1d0d10efeSs.makeev // The MIT License (MIT) 2d0d10efeSs.makeev // 3d0d10efeSs.makeev // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev 4d0d10efeSs.makeev // 5d0d10efeSs.makeev // Permission is hereby granted, free of charge, to any person obtaining a copy 6d0d10efeSs.makeev // of this software and associated documentation files (the "Software"), to deal 7d0d10efeSs.makeev // in the Software without restriction, including without limitation the rights 8d0d10efeSs.makeev // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9d0d10efeSs.makeev // copies of the Software, and to permit persons to whom the Software is 10d0d10efeSs.makeev // furnished to do so, subject to the following conditions: 11d0d10efeSs.makeev // 12d0d10efeSs.makeev // The above copyright notice and this permission notice shall be included in 13d0d10efeSs.makeev // all copies or substantial portions of the Software. 14d0d10efeSs.makeev // 15d0d10efeSs.makeev // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16d0d10efeSs.makeev // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17d0d10efeSs.makeev // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18d0d10efeSs.makeev // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19d0d10efeSs.makeev // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20d0d10efeSs.makeev // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21d0d10efeSs.makeev // THE SOFTWARE. 22d0d10efeSs.makeev #pragma once 23d0d10efeSs.makeev 241e78cb24Ss.makeev_local #include <MTConfig.h> 25d0d10efeSs.makeev #include <MTTypes.h> 26d0d10efeSs.makeev 273d930776Ss.makeev_local 28d0d10efeSs.makeev // 29d0d10efeSs.makeev // micro windows header is used to avoid including heavy windows header to MTPlatform.h 30d0d10efeSs.makeev // 31d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 32d0d10efeSs.makeev 33d0d10efeSs.makeev 34d0d10efeSs.makeev #define MW_WINBASEAPI __declspec(dllimport) 35d0d10efeSs.makeev #define MW_WINAPI __stdcall 36d0d10efeSs.makeev 3787ecbf38Ss.makeev #if defined(_WINDOWS_) || defined(_WINBASE_) 38d0d10efeSs.makeev 39d0d10efeSs.makeev // 40d0d10efeSs.makeev // if windows.h is already included simply create aliases to the MW_ types 41d0d10efeSs.makeev // 42d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 43d0d10efeSs.makeev typedef LARGE_INTEGER MW_LARGE_INTEGER; 44d0d10efeSs.makeev typedef BOOL MW_BOOL; 45d0d10efeSs.makeev typedef HANDLE MW_HANDLE; 46d0d10efeSs.makeev 47d0d10efeSs.makeev typedef DWORD MW_DWORD; 48d0d10efeSs.makeev typedef WORD MW_WORD; 49d0d10efeSs.makeev typedef DWORD64 MW_DWORD64; 50c88507a8Ss.makeev_local typedef ULONG_PTR MW_ULONG_PTR; 51d0d10efeSs.makeev 52d0d10efeSs.makeev typedef LPTHREAD_START_ROUTINE TThreadStartFunc; 53d0d10efeSs.makeev 54d0d10efeSs.makeev typedef SYSTEM_INFO MW_SYSTEM_INFO; 55d0d10efeSs.makeev 56d0d10efeSs.makeev typedef CRITICAL_SECTION MW_CRITICAL_SECTION; 57436acff3Ss.makeev_local typedef CONDITION_VARIABLE MW_CONDITION_VARIABLE; 58d0d10efeSs.makeev 59d0d10efeSs.makeev typedef CONTEXT MW_CONTEXT; 60d0d10efeSs.makeev 61d0d10efeSs.makeev #define MW_INFINITE (INFINITE) 62d0d10efeSs.makeev #define MW_WAIT_OBJECT_0 (WAIT_OBJECT_0) 63d0d10efeSs.makeev #define MW_MEM_COMMIT (MEM_COMMIT) 64d0d10efeSs.makeev #define MW_PAGE_READWRITE (PAGE_READWRITE) 65d0d10efeSs.makeev #define MW_PAGE_NOACCESS (PAGE_NOACCESS) 66d0d10efeSs.makeev #define MW_MEM_RELEASE (MEM_RELEASE) 67436acff3Ss.makeev_local #define MW_ERROR_TIMEOUT (ERROR_TIMEOUT) 68d0d10efeSs.makeev 693d930776Ss.makeev_local #define MW_CURRENT_FIBER_OFFSET (FIELD_OFFSET(NT_TIB, FiberData)) 70d0d10efeSs.makeev #define MW_STACK_BASE_OFFSET (FIELD_OFFSET(NT_TIB, StackBase)) 71d0d10efeSs.makeev #define MW_STACK_STACK_LIMIT_OFFSET (FIELD_OFFSET(NT_TIB, StackLimit)) 72d0d10efeSs.makeev #define MW_CONTEXT_FULL (CONTEXT_FULL) 73d0d10efeSs.makeev 74d0d10efeSs.makeev 7587ecbf38Ss.makeev #define MW_FIBER_FLAG_FLOAT_SWITCH (FIBER_FLAG_FLOAT_SWITCH) 7687ecbf38Ss.makeev 77d7cf17b1Ss.makeev_local #define MW_THREAD_PRIORITY_HIGHEST (THREAD_PRIORITY_HIGHEST) 78d7cf17b1Ss.makeev_local #define MW_THREAD_PRIORITY_NORMAL (THREAD_PRIORITY_NORMAL) 79d7cf17b1Ss.makeev_local #define MW_THREAD_PRIORITY_LOWEST (THREAD_PRIORITY_LOWEST) 80d7cf17b1Ss.makeev_local 81d7cf17b1Ss.makeev_local #define MW_CREATE_SUSPENDED (CREATE_SUSPENDED) 82d7cf17b1Ss.makeev_local 83d7cf17b1Ss.makeev_local #define MW_MAXIMUM_PROCESSORS (MAXIMUM_PROCESSORS) 8487ecbf38Ss.makeev 85d0d10efeSs.makeev #else 86d0d10efeSs.makeev 8787ecbf38Ss.makeev // windows.h is not included, so declare types 88d0d10efeSs.makeev 89d0d10efeSs.makeev // 90d0d10efeSs.makeev // define types 91d0d10efeSs.makeev // 92d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 93d0d10efeSs.makeev 94d0d10efeSs.makeev struct MW_LARGE_INTEGER 95d0d10efeSs.makeev { 96d0d10efeSs.makeev int64 QuadPart; 97d0d10efeSs.makeev }; 98d0d10efeSs.makeev 99d0d10efeSs.makeev typedef int MW_BOOL; 100d0d10efeSs.makeev typedef void* MW_HANDLE; 101d0d10efeSs.makeev 102d0d10efeSs.makeev typedef unsigned long MW_DWORD; 103d0d10efeSs.makeev typedef unsigned short MW_WORD; 104d0d10efeSs.makeev typedef unsigned __int64 MW_DWORD64; 105d0d10efeSs.makeev 106c88507a8Ss.makeev_local #if MT_PTR64 107c88507a8Ss.makeev_local typedef unsigned __int64 MW_ULONG_PTR; 108c88507a8Ss.makeev_local #else 109c88507a8Ss.makeev_local typedef unsigned __int32 MW_ULONG_PTR; 110c88507a8Ss.makeev_local #endif 111c88507a8Ss.makeev_local 112d0d10efeSs.makeev // 113d0d10efeSs.makeev // define thread function 114d0d10efeSs.makeev // 115d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 11687ecbf38Ss.makeev typedef MW_DWORD ( MW_WINAPI *TThreadStartFunc )(void* lpThreadParameter); 11787ecbf38Ss.makeev 11887ecbf38Ss.makeev // 11987ecbf38Ss.makeev // define fiber function 12087ecbf38Ss.makeev // 12187ecbf38Ss.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 12287ecbf38Ss.makeev typedef void ( MW_WINAPI *TFiberStartFunc)(void* lpFiberParameter); 12387ecbf38Ss.makeev 12487ecbf38Ss.makeev 125d0d10efeSs.makeev 126d0d10efeSs.makeev 127d0d10efeSs.makeev // 128d0d10efeSs.makeev // system info structure, only used members are declared 129d0d10efeSs.makeev // 130d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 131d0d10efeSs.makeev struct MW_SYSTEM_INFO 132d0d10efeSs.makeev { 133d0d10efeSs.makeev uint8 _unused_01[4]; 134d0d10efeSs.makeev MW_DWORD dwPageSize; 135d0d10efeSs.makeev void* _unused_02[3]; 136d0d10efeSs.makeev MW_DWORD dwNumberOfProcessors; 137d0d10efeSs.makeev uint8 _unused_03[12]; 138d0d10efeSs.makeev }; 139d0d10efeSs.makeev 140436acff3Ss.makeev_local 141436acff3Ss.makeev_local // Condition variable 142436acff3Ss.makeev_local typedef void* MW_CONDITION_VARIABLE; 143436acff3Ss.makeev_local 144436acff3Ss.makeev_local 1451e78cb24Ss.makeev_local #if MT_PTR64 146d0d10efeSs.makeev 147d0d10efeSs.makeev // 148d0d10efeSs.makeev // x64 critical section, only used members are declared 149d0d10efeSs.makeev // 150d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 151d0d10efeSs.makeev struct MW_CRITICAL_SECTION 152d0d10efeSs.makeev { 153d0d10efeSs.makeev uint8 _unused[40]; 154d0d10efeSs.makeev }; 155d0d10efeSs.makeev 156d0d10efeSs.makeev // 157d0d10efeSs.makeev // x64 machine context, only used members are declared 158d0d10efeSs.makeev // 159d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 160d0d10efeSs.makeev struct __declspec(align(16)) MW_CONTEXT 161d0d10efeSs.makeev { 162d0d10efeSs.makeev uint8 _unused_01[48]; 163d0d10efeSs.makeev MW_DWORD ContextFlags; 164d0d10efeSs.makeev uint8 _unused_02[100]; 165d0d10efeSs.makeev MW_DWORD64 Rsp; 166d0d10efeSs.makeev uint8 _unused_03[88]; 167d0d10efeSs.makeev MW_DWORD64 Rip; 168d0d10efeSs.makeev uint8 _unused_04[976]; 169d0d10efeSs.makeev }; 170d0d10efeSs.makeev 17153ef36e3Ss.makeev_local static_assert(__alignof(MW_CONTEXT) == 16, "MW_CONTEXT align requirements must be 16 bytes"); 17253ef36e3Ss.makeev_local 1733d930776Ss.makeev_local #define MW_CURRENT_FIBER_OFFSET (32) 174d0d10efeSs.makeev #define MW_STACK_BASE_OFFSET (8) 175d0d10efeSs.makeev #define MW_STACK_STACK_LIMIT_OFFSET (16) 176d0d10efeSs.makeev #define MW_CONTEXT_FULL (0x10000B) 177d0d10efeSs.makeev 178d0d10efeSs.makeev #else 179d0d10efeSs.makeev 180d0d10efeSs.makeev // 181d0d10efeSs.makeev // x86 critical section, only used members are declared 182d0d10efeSs.makeev // 183d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 184d0d10efeSs.makeev struct MW_CRITICAL_SECTION 185d0d10efeSs.makeev { 186d0d10efeSs.makeev uint8 _unused[24]; 187d0d10efeSs.makeev }; 188d0d10efeSs.makeev 189d0d10efeSs.makeev // 190d0d10efeSs.makeev // x86 machine context, only used members are declared 191d0d10efeSs.makeev // 192d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 193d0d10efeSs.makeev struct MW_CONTEXT 194d0d10efeSs.makeev { 195d0d10efeSs.makeev MW_DWORD ContextFlags; 196d0d10efeSs.makeev uint8 _unused_01[180]; 197d0d10efeSs.makeev MW_DWORD Eip; 198d0d10efeSs.makeev uint8 _unused_02[8]; 199d0d10efeSs.makeev MW_DWORD Esp; 200d0d10efeSs.makeev uint8 _unused_03[516]; 201d0d10efeSs.makeev }; 202d0d10efeSs.makeev 203d0d10efeSs.makeev 2043d930776Ss.makeev_local #define MW_CURRENT_FIBER_OFFSET (16) 205d0d10efeSs.makeev #define MW_STACK_BASE_OFFSET (4) 206d0d10efeSs.makeev #define MW_STACK_STACK_LIMIT_OFFSET (8) 207d0d10efeSs.makeev #define MW_CONTEXT_FULL (0x10007) 208d0d10efeSs.makeev 209d0d10efeSs.makeev 210d0d10efeSs.makeev #endif 211d0d10efeSs.makeev 212d0d10efeSs.makeev 213d0d10efeSs.makeev // 214d0d10efeSs.makeev // defines and flags 215d0d10efeSs.makeev // 216d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 217d0d10efeSs.makeev #define MW_INFINITE (0xFFFFFFFF) 218d0d10efeSs.makeev #define MW_WAIT_OBJECT_0 (0) 219d0d10efeSs.makeev #define MW_MEM_COMMIT (0x1000) 220d0d10efeSs.makeev #define MW_PAGE_READWRITE (0x04) 221d0d10efeSs.makeev #define MW_PAGE_NOACCESS (0x01) 222d0d10efeSs.makeev #define MW_MEM_RELEASE (0x8000) 223436acff3Ss.makeev_local #define MW_ERROR_TIMEOUT (1460L) 224d0d10efeSs.makeev 225d7cf17b1Ss.makeev_local #define MW_THREAD_PRIORITY_HIGHEST (2) 226d7cf17b1Ss.makeev_local #define MW_THREAD_PRIORITY_NORMAL (0) 227d7cf17b1Ss.makeev_local #define MW_THREAD_PRIORITY_LOWEST (-2) 228d7cf17b1Ss.makeev_local 229d7cf17b1Ss.makeev_local #define MW_CREATE_SUSPENDED (0x00000004) 230d7cf17b1Ss.makeev_local 2313d930776Ss.makeev_local 232d7cf17b1Ss.makeev_local #if MT_PTR64 233d7cf17b1Ss.makeev_local #define MW_MAXIMUM_PROCESSORS (64) 2343d930776Ss.makeev_local #define MW_FIBER_FLAG_FLOAT_SWITCH (0x1) 235d7cf17b1Ss.makeev_local #else 236d7cf17b1Ss.makeev_local #define MW_MAXIMUM_PROCESSORS (32) 2373d930776Ss.makeev_local #define MW_FIBER_FLAG_FLOAT_SWITCH (0x1) 238d7cf17b1Ss.makeev_local #endif 239d0d10efeSs.makeev 2403d930776Ss.makeev_local 241d0d10efeSs.makeev #endif 242d0d10efeSs.makeev 243d0d10efeSs.makeev 244d0d10efeSs.makeev 2453d930776Ss.makeev_local 246d0d10efeSs.makeev #if !defined(MW_SKIP_FUNCTIONS) && !defined(_WINDOWS_) 247d0d10efeSs.makeev 248d0d10efeSs.makeev // 249d0d10efeSs.makeev // functions 250d0d10efeSs.makeev // 251d0d10efeSs.makeev /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 252d0d10efeSs.makeev 253d0d10efeSs.makeev 254d0d10efeSs.makeev extern "C" { 255d0d10efeSs.makeev 256d0d10efeSs.makeev MW_WINBASEAPI MW_BOOL MW_WINAPI QueryPerformanceFrequency(MW_LARGE_INTEGER* lpFrequency); 257d0d10efeSs.makeev MW_WINBASEAPI MW_BOOL MW_WINAPI QueryPerformanceCounter(MW_LARGE_INTEGER* lpPerformanceCount); 258d0d10efeSs.makeev 259d7cf17b1Ss.makeev_local MW_WINBASEAPI MW_ULONG_PTR MW_WINAPI SetThreadAffinityMask(MW_HANDLE hThread, MW_ULONG_PTR dwThreadAffinityMask ); 260d7cf17b1Ss.makeev_local MW_WINBASEAPI MW_DWORD MW_WINAPI SetThreadIdealProcessor(MW_HANDLE hThread, MW_DWORD dwIdealProcessor ); 261d7cf17b1Ss.makeev_local MW_WINBASEAPI MW_BOOL MW_WINAPI SetThreadPriority(MW_HANDLE hThread, int nPriority ); 262d0d10efeSs.makeev MW_WINBASEAPI MW_HANDLE MW_WINAPI CreateThread(void* lpThreadAttributes, size_t dwStackSize, TThreadStartFunc lpStartAddress, void* lpParameter, MW_DWORD dwCreationFlags, MW_DWORD* lpThreadId); 263d0d10efeSs.makeev MW_WINBASEAPI MW_BOOL MW_WINAPI CloseHandle(MW_HANDLE hObject); 264d0d10efeSs.makeev MW_WINBASEAPI MW_HANDLE MW_WINAPI GetCurrentThread(); 265d0d10efeSs.makeev MW_WINBASEAPI MW_DWORD MW_WINAPI GetCurrentThreadId(); 266d7cf17b1Ss.makeev_local MW_WINBASEAPI MW_DWORD MW_WINAPI ResumeThread(MW_HANDLE hThread); 267f7a9bfc3Ss.makeev_local MW_WINBASEAPI MW_BOOL MW_WINAPI SwitchToThread(); 268d7cf17b1Ss.makeev_local 269d0d10efeSs.makeev 270d0d10efeSs.makeev MW_WINBASEAPI void MW_WINAPI GetSystemInfo(MW_SYSTEM_INFO* lpSystemInfo); 271d0d10efeSs.makeev 272d0d10efeSs.makeev MW_WINBASEAPI void MW_WINAPI Sleep(MW_DWORD dwMilliseconds); 273d0d10efeSs.makeev MW_WINBASEAPI MW_DWORD MW_WINAPI WaitForSingleObject(MW_HANDLE hHandle, MW_DWORD dwMilliseconds); 274d0d10efeSs.makeev 275436acff3Ss.makeev_local MW_WINBASEAPI void MW_WINAPI InitializeConditionVariable (MW_CONDITION_VARIABLE* lpConditionVariable); 276436acff3Ss.makeev_local MW_WINBASEAPI void MW_WINAPI WakeConditionVariable (MW_CONDITION_VARIABLE* lpConditionVariable); 277436acff3Ss.makeev_local MW_WINBASEAPI void MW_WINAPI WakeAllConditionVariable (MW_CONDITION_VARIABLE* lpConditionVariable); 278436acff3Ss.makeev_local MW_WINBASEAPI MW_BOOL MW_WINAPI SleepConditionVariableCS (MW_CONDITION_VARIABLE* lpConditionVariable, MW_CRITICAL_SECTION* lpCriticalSection, MW_DWORD dwMilliseconds); 279436acff3Ss.makeev_local 280d0d10efeSs.makeev MW_WINBASEAPI bool MW_WINAPI InitializeCriticalSectionAndSpinCount(MW_CRITICAL_SECTION* lpCriticalSection, MW_DWORD dwSpinCount ); 281d0d10efeSs.makeev MW_WINBASEAPI void MW_WINAPI DeleteCriticalSection(MW_CRITICAL_SECTION* lpCriticalSection ); 282d0d10efeSs.makeev MW_WINBASEAPI void MW_WINAPI EnterCriticalSection(MW_CRITICAL_SECTION* lpCriticalSection ); 283d0d10efeSs.makeev MW_WINBASEAPI void MW_WINAPI LeaveCriticalSection(MW_CRITICAL_SECTION* lpCriticalSection ); 284d0d10efeSs.makeev 285d0d10efeSs.makeev MW_WINBASEAPI MW_HANDLE MW_WINAPI CreateEventA(MW_CRITICAL_SECTION* lpEventAttributes, MW_BOOL bManualReset, MW_BOOL bInitialState, const char* lpName ); 286d0d10efeSs.makeev MW_WINBASEAPI MW_HANDLE MW_WINAPI CreateEventW(MW_CRITICAL_SECTION* lpEventAttributes, MW_BOOL bManualReset, MW_BOOL bInitialState, const wchar_t* lpName ); 287d0d10efeSs.makeev MW_WINBASEAPI MW_BOOL MW_WINAPI SetEvent( MW_HANDLE hEvent ); 288d0d10efeSs.makeev MW_WINBASEAPI MW_BOOL MW_WINAPI ResetEvent( MW_HANDLE hEvent ); 289d0d10efeSs.makeev 290d0d10efeSs.makeev MW_WINBASEAPI MW_BOOL MW_WINAPI GetThreadContext( MW_HANDLE hThread, MW_CONTEXT* lpContext ); 291d0d10efeSs.makeev MW_WINBASEAPI MW_BOOL MW_WINAPI SetThreadContext( MW_HANDLE hThread, const MW_CONTEXT* lpContext ); 292d0d10efeSs.makeev 293d0d10efeSs.makeev MW_WINBASEAPI void* MW_WINAPI VirtualAlloc( void* lpAddress, size_t dwSize, MW_DWORD flAllocationType, MW_DWORD flProtect ); 294d0d10efeSs.makeev MW_WINBASEAPI MW_BOOL MW_WINAPI VirtualProtect( void* lpAddress, size_t dwSize, MW_DWORD flNewProtect, MW_DWORD* lpflOldProtect ); 295d0d10efeSs.makeev MW_WINBASEAPI MW_BOOL MW_WINAPI VirtualFree( void* lpAddress, size_t dwSize, MW_DWORD dwFreeType ); 296d0d10efeSs.makeev 29787ecbf38Ss.makeev 29887ecbf38Ss.makeev MW_WINBASEAPI void MW_WINAPI DeleteFiber( void* lpFiber ); 29987ecbf38Ss.makeev MW_WINBASEAPI void* MW_WINAPI ConvertThreadToFiberEx( void* lpParameter, MW_DWORD dwFlags ); 300*d8cd6e1fSTsarevich Dmitry MW_WINBASEAPI MW_BOOL MW_WINAPI ConvertFiberToThread(); 30187ecbf38Ss.makeev MW_WINBASEAPI void* MW_WINAPI CreateFiber( size_t dwStackSize, TFiberStartFunc lpStartAddress, void* lpParameter ); 30287ecbf38Ss.makeev MW_WINBASEAPI void MW_WINAPI SwitchToFiber( void* lpFiber ); 3033d930776Ss.makeev_local MW_WINBASEAPI MW_BOOL MW_WINAPI IsThreadAFiber(); 30487ecbf38Ss.makeev 305c88507a8Ss.makeev_local MW_WINBASEAPI void MW_WINAPI RaiseException(MW_DWORD dwExceptionCode, MW_DWORD dwExceptionFlags, MW_DWORD nNumberOfArguments, const MW_ULONG_PTR* lpArguments ); 30687ecbf38Ss.makeev 3073d930776Ss.makeev_local MW_WINBASEAPI MW_DWORD MW_WINAPI GetLastError(); 30887ecbf38Ss.makeev 309f7a9bfc3Ss.makeev_local 310f7a9bfc3Ss.makeev_local 311f7a9bfc3Ss.makeev_local 312d0d10efeSs.makeev } 313d0d10efeSs.makeev 314d0d10efeSs.makeev #endif 315