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