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 //
29 // micro windows header is used to avoid including heavy windows header to MTPlatform.h
30 //
31 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32 
33 
34 #define MW_WINBASEAPI __declspec(dllimport)
35 #define MW_WINAPI __stdcall
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 typedef CONDITION_VARIABLE MW_CONDITION_VARIABLE;
58 
59 typedef CONTEXT MW_CONTEXT;
60 
61 #define MW_INFINITE (INFINITE)
62 #define MW_WAIT_OBJECT_0 (WAIT_OBJECT_0)
63 #define MW_MEM_COMMIT (MEM_COMMIT)
64 #define MW_PAGE_READWRITE (PAGE_READWRITE)
65 #define MW_PAGE_NOACCESS (PAGE_NOACCESS)
66 #define MW_MEM_RELEASE (MEM_RELEASE)
67 #define MW_ERROR_TIMEOUT (ERROR_TIMEOUT)
68 
69 #define MW_CURRENT_FIBER_OFFSET (FIELD_OFFSET(NT_TIB, FiberData))
70 #define MW_STACK_BASE_OFFSET (FIELD_OFFSET(NT_TIB, StackBase))
71 #define MW_STACK_STACK_LIMIT_OFFSET (FIELD_OFFSET(NT_TIB, StackLimit))
72 #define MW_CONTEXT_FULL (CONTEXT_FULL)
73 
74 
75 #define MW_FIBER_FLAG_FLOAT_SWITCH (FIBER_FLAG_FLOAT_SWITCH)
76 
77 #define MW_THREAD_PRIORITY_HIGHEST (THREAD_PRIORITY_HIGHEST)
78 #define MW_THREAD_PRIORITY_NORMAL (THREAD_PRIORITY_NORMAL)
79 #define MW_THREAD_PRIORITY_LOWEST (THREAD_PRIORITY_LOWEST)
80 
81 #define MW_CREATE_SUSPENDED (CREATE_SUSPENDED)
82 
83 #define MW_MAXIMUM_PROCESSORS (MAXIMUM_PROCESSORS)
84 
85 #else
86 
87 // windows.h is not included, so declare types
88 
89 //
90 // define types
91 //
92 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 
94 struct MW_LARGE_INTEGER
95 {
96 	int64 QuadPart;
97 };
98 
99 typedef int MW_BOOL;
100 typedef void* MW_HANDLE;
101 
102 typedef unsigned long MW_DWORD;
103 typedef unsigned short MW_WORD;
104 typedef unsigned __int64 MW_DWORD64;
105 
106 #if MT_PTR64
107 typedef unsigned __int64 MW_ULONG_PTR;
108 #else
109 typedef unsigned __int32 MW_ULONG_PTR;
110 #endif
111 
112 //
113 // define thread function
114 //
115 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116 typedef MW_DWORD ( MW_WINAPI *TThreadStartFunc )(void* lpThreadParameter);
117 
118 //
119 // define fiber function
120 //
121 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
122 typedef void ( MW_WINAPI *TFiberStartFunc)(void* lpFiberParameter);
123 
124 
125 
126 
127 //
128 // system info structure, only used members are declared
129 //
130 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
131 struct MW_SYSTEM_INFO
132 {
133 	uint8 _unused_01[4];
134 	MW_DWORD dwPageSize;
135 	void* _unused_02[3];
136 	MW_DWORD dwNumberOfProcessors;
137 	uint8 _unused_03[12];
138 };
139 
140 
141 // Condition variable
142 typedef void* MW_CONDITION_VARIABLE;
143 
144 
145 #if MT_PTR64
146 
147 //
148 // x64 critical section, only used members are declared
149 //
150 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
151 struct MW_CRITICAL_SECTION
152 {
153 	uint8 _unused[40];
154 };
155 
156 //
157 // x64 machine context, only used members are declared
158 //
159 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
160 struct __declspec(align(16)) MW_CONTEXT
161 {
162 	uint8 _unused_01[48];
163 	MW_DWORD ContextFlags;
164 	uint8 _unused_02[100];
165 	MW_DWORD64 Rsp;
166 	uint8 _unused_03[88];
167 	MW_DWORD64 Rip;
168 	uint8 _unused_04[976];
169 };
170 
171 static_assert(__alignof(MW_CONTEXT) == 16, "MW_CONTEXT align requirements must be 16 bytes");
172 
173 #define MW_CURRENT_FIBER_OFFSET (32)
174 #define MW_STACK_BASE_OFFSET (8)
175 #define MW_STACK_STACK_LIMIT_OFFSET (16)
176 #define MW_CONTEXT_FULL (0x10000B)
177 
178 #else
179 
180 //
181 // x86 critical section, only used members are declared
182 //
183 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
184 struct MW_CRITICAL_SECTION
185 {
186 	uint8 _unused[24];
187 };
188 
189 //
190 // x86 machine context, only used members are declared
191 //
192 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
193 struct MW_CONTEXT
194 {
195 	MW_DWORD ContextFlags;
196 	uint8 _unused_01[180];
197 	MW_DWORD   Eip;
198 	uint8 _unused_02[8];
199 	MW_DWORD   Esp;
200 	uint8 _unused_03[516];
201 };
202 
203 
204 #define MW_CURRENT_FIBER_OFFSET (16)
205 #define MW_STACK_BASE_OFFSET (4)
206 #define MW_STACK_STACK_LIMIT_OFFSET (8)
207 #define MW_CONTEXT_FULL (0x10007)
208 
209 
210 #endif
211 
212 
213 //
214 // defines and flags
215 //
216 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
217 #define MW_INFINITE (0xFFFFFFFF)
218 #define MW_WAIT_OBJECT_0 (0)
219 #define MW_MEM_COMMIT (0x1000)
220 #define MW_PAGE_READWRITE (0x04)
221 #define MW_PAGE_NOACCESS (0x01)
222 #define MW_MEM_RELEASE (0x8000)
223 #define MW_ERROR_TIMEOUT (1460L)
224 
225 #define MW_THREAD_PRIORITY_HIGHEST (2)
226 #define MW_THREAD_PRIORITY_NORMAL (0)
227 #define MW_THREAD_PRIORITY_LOWEST (-2)
228 
229 #define MW_CREATE_SUSPENDED (0x00000004)
230 
231 
232 #if MT_PTR64
233 #define MW_MAXIMUM_PROCESSORS (64)
234 #define MW_FIBER_FLAG_FLOAT_SWITCH (0x1)
235 #else
236 #define MW_MAXIMUM_PROCESSORS (32)
237 #define MW_FIBER_FLAG_FLOAT_SWITCH (0x1)
238 #endif
239 
240 
241 #endif
242 
243 
244 
245 
246 #if !defined(MW_SKIP_FUNCTIONS) && !defined(_WINDOWS_)
247 
248 //
249 // functions
250 //
251 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
252 
253 
254 extern "C" {
255 
256 MW_WINBASEAPI MW_BOOL MW_WINAPI QueryPerformanceFrequency(MW_LARGE_INTEGER* lpFrequency);
257 MW_WINBASEAPI MW_BOOL MW_WINAPI QueryPerformanceCounter(MW_LARGE_INTEGER* lpPerformanceCount);
258 
259 MW_WINBASEAPI MW_ULONG_PTR MW_WINAPI SetThreadAffinityMask(MW_HANDLE hThread, MW_ULONG_PTR dwThreadAffinityMask );
260 MW_WINBASEAPI MW_DWORD MW_WINAPI SetThreadIdealProcessor(MW_HANDLE hThread, MW_DWORD dwIdealProcessor );
261 MW_WINBASEAPI MW_BOOL MW_WINAPI SetThreadPriority(MW_HANDLE hThread, int nPriority );
262 MW_WINBASEAPI MW_HANDLE MW_WINAPI CreateThread(void* lpThreadAttributes, size_t dwStackSize, TThreadStartFunc lpStartAddress, void* lpParameter, MW_DWORD dwCreationFlags, MW_DWORD* lpThreadId);
263 MW_WINBASEAPI MW_BOOL MW_WINAPI CloseHandle(MW_HANDLE hObject);
264 MW_WINBASEAPI MW_HANDLE MW_WINAPI GetCurrentThread();
265 MW_WINBASEAPI MW_DWORD MW_WINAPI GetCurrentThreadId();
266 MW_WINBASEAPI MW_DWORD MW_WINAPI ResumeThread(MW_HANDLE hThread);
267 MW_WINBASEAPI MW_BOOL MW_WINAPI SwitchToThread();
268 
269 
270 MW_WINBASEAPI void MW_WINAPI GetSystemInfo(MW_SYSTEM_INFO* lpSystemInfo);
271 
272 MW_WINBASEAPI void MW_WINAPI Sleep(MW_DWORD dwMilliseconds);
273 MW_WINBASEAPI MW_DWORD MW_WINAPI WaitForSingleObject(MW_HANDLE hHandle, MW_DWORD dwMilliseconds);
274 
275 MW_WINBASEAPI	void MW_WINAPI InitializeConditionVariable (MW_CONDITION_VARIABLE* lpConditionVariable);
276 MW_WINBASEAPI	void MW_WINAPI WakeConditionVariable (MW_CONDITION_VARIABLE* lpConditionVariable);
277 MW_WINBASEAPI	void MW_WINAPI WakeAllConditionVariable (MW_CONDITION_VARIABLE* lpConditionVariable);
278 MW_WINBASEAPI	MW_BOOL	MW_WINAPI SleepConditionVariableCS (MW_CONDITION_VARIABLE* lpConditionVariable,	MW_CRITICAL_SECTION* lpCriticalSection, MW_DWORD dwMilliseconds);
279 
280 MW_WINBASEAPI bool MW_WINAPI InitializeCriticalSectionAndSpinCount(MW_CRITICAL_SECTION* lpCriticalSection, MW_DWORD dwSpinCount );
281 MW_WINBASEAPI void MW_WINAPI DeleteCriticalSection(MW_CRITICAL_SECTION* lpCriticalSection );
282 MW_WINBASEAPI void MW_WINAPI EnterCriticalSection(MW_CRITICAL_SECTION* lpCriticalSection );
283 MW_WINBASEAPI void MW_WINAPI LeaveCriticalSection(MW_CRITICAL_SECTION* lpCriticalSection );
284 
285 MW_WINBASEAPI MW_HANDLE MW_WINAPI CreateEventA(MW_CRITICAL_SECTION* lpEventAttributes, MW_BOOL bManualReset, MW_BOOL bInitialState, const char* lpName );
286 MW_WINBASEAPI MW_HANDLE MW_WINAPI CreateEventW(MW_CRITICAL_SECTION* lpEventAttributes, MW_BOOL bManualReset, MW_BOOL bInitialState, const wchar_t* lpName );
287 MW_WINBASEAPI MW_BOOL MW_WINAPI SetEvent( MW_HANDLE hEvent );
288 MW_WINBASEAPI MW_BOOL MW_WINAPI ResetEvent( MW_HANDLE hEvent );
289 
290 MW_WINBASEAPI MW_BOOL MW_WINAPI GetThreadContext( MW_HANDLE hThread, MW_CONTEXT* lpContext );
291 MW_WINBASEAPI MW_BOOL MW_WINAPI SetThreadContext( MW_HANDLE hThread, const MW_CONTEXT* lpContext );
292 
293 MW_WINBASEAPI void* MW_WINAPI VirtualAlloc( void* lpAddress, size_t dwSize, MW_DWORD flAllocationType, MW_DWORD flProtect );
294 MW_WINBASEAPI MW_BOOL MW_WINAPI VirtualProtect( void* lpAddress, size_t dwSize, MW_DWORD flNewProtect, MW_DWORD* lpflOldProtect );
295 MW_WINBASEAPI MW_BOOL MW_WINAPI VirtualFree( void* lpAddress, size_t dwSize, MW_DWORD dwFreeType );
296 
297 
298 MW_WINBASEAPI void MW_WINAPI DeleteFiber( void* lpFiber );
299 MW_WINBASEAPI void* MW_WINAPI ConvertThreadToFiberEx( void* lpParameter, MW_DWORD dwFlags );
300 MW_WINBASEAPI MW_BOOL MW_WINAPI ConvertFiberToThread();
301 MW_WINBASEAPI void* MW_WINAPI CreateFiber( size_t dwStackSize, TFiberStartFunc lpStartAddress, void* lpParameter );
302 MW_WINBASEAPI void MW_WINAPI SwitchToFiber( void* lpFiber );
303 MW_WINBASEAPI MW_BOOL MW_WINAPI IsThreadAFiber();
304 
305 MW_WINBASEAPI void MW_WINAPI RaiseException(MW_DWORD dwExceptionCode, MW_DWORD dwExceptionFlags, MW_DWORD nNumberOfArguments, const MW_ULONG_PTR* lpArguments );
306 
307 MW_WINBASEAPI MW_DWORD MW_WINAPI GetLastError();
308 
309 
310 
311 
312 }
313 
314 #endif
315