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