1 // The MIT License (MIT)
2 //
3 // 	Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev
4 //
5 // 	Permission is hereby granted, free of charge, to any person obtaining a copy
6 // 	of this software and associated documentation files (the "Software"), to deal
7 // 	in the Software without restriction, including without limitation the rights
8 // 	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // 	copies of the Software, and to permit persons to whom the Software is
10 // 	furnished to do so, subject to the following conditions:
11 //
12 //  The above copyright notice and this permission notice shall be included in
13 // 	all copies or substantial portions of the Software.
14 //
15 // 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // 	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // 	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // 	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // 	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // 	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // 	THE SOFTWARE.
22 #pragma once
23 
24 #include <MTConfig.h>
25 #include <MTTypes.h>
26 
27 //
28 // micro windows header is used to avoid including heavy windows header to MTPlatform.h
29 //
30 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 
32 
33 #define MW_WINBASEAPI __declspec(dllimport)
34 #define MW_WINAPI __stdcall
35 
36 
37 #if defined(_WINDOWS_) || defined(_WINBASE_)
38 
39 //
40 // if windows.h is already included simply create aliases to the MW_ types
41 //
42 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
43 typedef LARGE_INTEGER MW_LARGE_INTEGER;
44 typedef BOOL MW_BOOL;
45 typedef HANDLE MW_HANDLE;
46 
47 typedef DWORD MW_DWORD;
48 typedef WORD MW_WORD;
49 typedef DWORD64 MW_DWORD64;
50 typedef ULONG_PTR MW_ULONG_PTR;
51 
52 typedef LPTHREAD_START_ROUTINE TThreadStartFunc;
53 
54 typedef SYSTEM_INFO MW_SYSTEM_INFO;
55 
56 typedef CRITICAL_SECTION MW_CRITICAL_SECTION;
57 
58 typedef CONTEXT MW_CONTEXT;
59 
60 #define MW_INFINITE (INFINITE)
61 #define MW_WAIT_OBJECT_0 (WAIT_OBJECT_0)
62 #define MW_MEM_COMMIT (MEM_COMMIT)
63 #define MW_PAGE_READWRITE (PAGE_READWRITE)
64 #define MW_PAGE_NOACCESS (PAGE_NOACCESS)
65 #define MW_MEM_RELEASE (MEM_RELEASE)
66 
67 
68 #define MW_STACK_BASE_OFFSET (FIELD_OFFSET(NT_TIB, StackBase))
69 #define MW_STACK_STACK_LIMIT_OFFSET (FIELD_OFFSET(NT_TIB, StackLimit))
70 #define MW_CONTEXT_FULL (CONTEXT_FULL)
71 
72 
73 #define MW_FIBER_FLAG_FLOAT_SWITCH (FIBER_FLAG_FLOAT_SWITCH)
74 
75 
76 #else
77 
78 // windows.h is not included, so declare types
79 
80 //
81 // define types
82 //
83 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84 
85 struct MW_LARGE_INTEGER
86 {
87 	int64 QuadPart;
88 };
89 
90 typedef int MW_BOOL;
91 typedef void* MW_HANDLE;
92 
93 typedef unsigned long MW_DWORD;
94 typedef unsigned short MW_WORD;
95 typedef unsigned __int64 MW_DWORD64;
96 
97 #if MT_PTR64
98 typedef unsigned __int64 MW_ULONG_PTR;
99 #else
100 typedef unsigned __int32 MW_ULONG_PTR;
101 #endif
102 
103 //
104 // define thread function
105 //
106 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
107 typedef MW_DWORD ( MW_WINAPI *TThreadStartFunc )(void* lpThreadParameter);
108 
109 //
110 // define fiber function
111 //
112 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
113 typedef void ( MW_WINAPI *TFiberStartFunc)(void* lpFiberParameter);
114 
115 
116 
117 
118 //
119 // system info structure, only used members are declared
120 //
121 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
122 struct MW_SYSTEM_INFO
123 {
124 	uint8 _unused_01[4];
125 	MW_DWORD dwPageSize;
126 	void* _unused_02[3];
127 	MW_DWORD dwNumberOfProcessors;
128 	uint8 _unused_03[12];
129 };
130 
131 #if MT_PTR64
132 
133 //
134 // x64 critical section, only used members are declared
135 //
136 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
137 struct MW_CRITICAL_SECTION
138 {
139 	uint8 _unused[40];
140 };
141 
142 //
143 // x64 machine context, only used members are declared
144 //
145 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
146 struct __declspec(align(16)) MW_CONTEXT
147 {
148 	uint8 _unused_01[48];
149 	MW_DWORD ContextFlags;
150 	uint8 _unused_02[100];
151 	MW_DWORD64 Rsp;
152 	uint8 _unused_03[88];
153 	MW_DWORD64 Rip;
154 	uint8 _unused_04[976];
155 };
156 
157 static_assert(__alignof(MW_CONTEXT) == 16, "MW_CONTEXT align requirements must be 16 bytes");
158 
159 #define MW_STACK_BASE_OFFSET (8)
160 #define MW_STACK_STACK_LIMIT_OFFSET (16)
161 #define MW_CONTEXT_FULL (0x10000B)
162 
163 #else
164 
165 //
166 // x86 critical section, only used members are declared
167 //
168 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
169 struct MW_CRITICAL_SECTION
170 {
171 	uint8 _unused[24];
172 };
173 
174 //
175 // x86 machine context, only used members are declared
176 //
177 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
178 struct MW_CONTEXT
179 {
180 	MW_DWORD ContextFlags;
181 	uint8 _unused_01[180];
182 	MW_DWORD   Eip;
183 	uint8 _unused_02[8];
184 	MW_DWORD   Esp;
185 	uint8 _unused_03[516];
186 };
187 
188 
189 #define MW_STACK_BASE_OFFSET (4)
190 #define MW_STACK_STACK_LIMIT_OFFSET (8)
191 #define MW_CONTEXT_FULL (0x10007)
192 
193 
194 #endif
195 
196 
197 //
198 // defines and flags
199 //
200 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
201 #define MW_INFINITE (0xFFFFFFFF)
202 #define MW_WAIT_OBJECT_0 (0)
203 #define MW_MEM_COMMIT (0x1000)
204 #define MW_PAGE_READWRITE (0x04)
205 #define MW_PAGE_NOACCESS (0x01)
206 #define MW_MEM_RELEASE (0x8000)
207 #define MW_FIBER_FLAG_FLOAT_SWITCH (0x1)
208 
209 
210 #endif
211 
212 
213 
214 #if !defined(MW_SKIP_FUNCTIONS) && !defined(_WINDOWS_)
215 
216 //
217 // functions
218 //
219 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
220 
221 
222 extern "C" {
223 
224 MW_WINBASEAPI MW_BOOL MW_WINAPI QueryPerformanceFrequency(MW_LARGE_INTEGER* lpFrequency);
225 MW_WINBASEAPI MW_BOOL MW_WINAPI QueryPerformanceCounter(MW_LARGE_INTEGER* lpPerformanceCount);
226 
227 MW_WINBASEAPI MW_HANDLE MW_WINAPI CreateThread(void* lpThreadAttributes, size_t dwStackSize, TThreadStartFunc lpStartAddress, void* lpParameter, MW_DWORD dwCreationFlags, MW_DWORD* lpThreadId);
228 MW_WINBASEAPI MW_BOOL MW_WINAPI CloseHandle(MW_HANDLE hObject);
229 MW_WINBASEAPI MW_HANDLE MW_WINAPI GetCurrentThread();
230 MW_WINBASEAPI MW_DWORD MW_WINAPI GetCurrentThreadId();
231 
232 MW_WINBASEAPI void MW_WINAPI GetSystemInfo(MW_SYSTEM_INFO* lpSystemInfo);
233 
234 MW_WINBASEAPI void MW_WINAPI Sleep(MW_DWORD dwMilliseconds);
235 MW_WINBASEAPI MW_DWORD MW_WINAPI WaitForSingleObject(MW_HANDLE hHandle, MW_DWORD dwMilliseconds);
236 
237 MW_WINBASEAPI bool MW_WINAPI InitializeCriticalSectionAndSpinCount(MW_CRITICAL_SECTION* lpCriticalSection, MW_DWORD dwSpinCount );
238 MW_WINBASEAPI void MW_WINAPI DeleteCriticalSection(MW_CRITICAL_SECTION* lpCriticalSection );
239 MW_WINBASEAPI void MW_WINAPI EnterCriticalSection(MW_CRITICAL_SECTION* lpCriticalSection );
240 MW_WINBASEAPI void MW_WINAPI LeaveCriticalSection(MW_CRITICAL_SECTION* lpCriticalSection );
241 
242 MW_WINBASEAPI MW_HANDLE MW_WINAPI CreateEventA(MW_CRITICAL_SECTION* lpEventAttributes, MW_BOOL bManualReset, MW_BOOL bInitialState, const char* lpName );
243 MW_WINBASEAPI MW_HANDLE MW_WINAPI CreateEventW(MW_CRITICAL_SECTION* lpEventAttributes, MW_BOOL bManualReset, MW_BOOL bInitialState, const wchar_t* lpName );
244 MW_WINBASEAPI MW_BOOL MW_WINAPI SetEvent( MW_HANDLE hEvent );
245 MW_WINBASEAPI MW_BOOL MW_WINAPI ResetEvent( MW_HANDLE hEvent );
246 
247 MW_WINBASEAPI MW_BOOL MW_WINAPI GetThreadContext( MW_HANDLE hThread, MW_CONTEXT* lpContext );
248 MW_WINBASEAPI MW_BOOL MW_WINAPI SetThreadContext( MW_HANDLE hThread, const MW_CONTEXT* lpContext );
249 
250 MW_WINBASEAPI void* MW_WINAPI VirtualAlloc( void* lpAddress, size_t dwSize, MW_DWORD flAllocationType, MW_DWORD flProtect );
251 MW_WINBASEAPI MW_BOOL MW_WINAPI VirtualProtect( void* lpAddress, size_t dwSize, MW_DWORD flNewProtect, MW_DWORD* lpflOldProtect );
252 MW_WINBASEAPI MW_BOOL MW_WINAPI VirtualFree( void* lpAddress, size_t dwSize, MW_DWORD dwFreeType );
253 
254 
255 MW_WINBASEAPI void MW_WINAPI DeleteFiber( void* lpFiber );
256 MW_WINBASEAPI void* MW_WINAPI ConvertThreadToFiberEx( void* lpParameter, MW_DWORD dwFlags );
257 MW_WINBASEAPI void* MW_WINAPI CreateFiber( size_t dwStackSize, TFiberStartFunc lpStartAddress, void* lpParameter );
258 MW_WINBASEAPI void MW_WINAPI SwitchToFiber( void* lpFiber );
259 
260 MW_WINBASEAPI void MW_WINAPI RaiseException(MW_DWORD dwExceptionCode, MW_DWORD dwExceptionFlags, MW_DWORD nNumberOfArguments, const MW_ULONG_PTR* lpArguments );
261 
262 
263 }
264 
265 #endif
266