1 2 // Copyright 2018 - 2021 Michael D. Parker 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 module bindbc.sdl.bind.sdlthread; 8 9 import core.stdc.config : c_ulong; 10 import bindbc.sdl.config; 11 12 struct SDL_Thread; 13 alias SDL_threadID = c_ulong; 14 alias SDL_TLSID = uint; 15 16 static if(sdlSupport >= SDLSupport.sdl209) { 17 enum SDL_ThreadPriority { 18 SDL_THREAD_PRIORITY_LOW, 19 SDL_THREAD_PRIORITY_NORMAL, 20 SDL_THREAD_PRIORITY_HIGH, 21 SDL_THREAD_PRIORITY_TIME_CRITICAL, 22 } 23 } 24 else { 25 enum SDL_ThreadPriority { 26 SDL_THREAD_PRIORITY_LOW, 27 SDL_THREAD_PRIORITY_NORMAL, 28 SDL_THREAD_PRIORITY_HIGH, 29 } 30 } 31 mixin(expandEnum!SDL_ThreadPriority); 32 33 extern(C) nothrow { 34 alias SDL_ThreadFunction = int function(void*); 35 alias TLSDestructor = void function(void*); 36 } 37 38 version(Windows) { 39 /* 40 On Windows, SDL_CreateThread/WithStackSize require the _beginthreadex/_endthreadex of 41 the caller's process when using the DLL. As best as I can tell, this will be okay even 42 when statically linking. If it does break, I'll need to add a new version identifier 43 when BindBC_Static is specified in order to distingiuish between linking with the 44 DLL's import library and statically linking with SDL. 45 */ 46 private { 47 import core.stdc.stdint : uintptr_t; 48 49 extern(Windows) alias btex_fptr = uint function(void*); 50 extern(C) @nogc nothrow { 51 uintptr_t _beginthreadex(void*,uint,btex_fptr,void*,uint,uint*); 52 void _endthreadex(uint); 53 54 alias pfnSDL_CurrentBeginThread = uintptr_t function(void*,uint,btex_fptr,void*,uint,uint*); 55 alias pfnSDL_CurrentEndThread = void function(uint); 56 } 57 } 58 59 SDL_Thread* SDL_CreateThreadImpl(SDL_ThreadFunction fn, const(char)* name, void* data) { 60 return SDL_CreateThread(fn, name, data, &_beginthreadex, &_endthreadex); 61 } 62 63 static if(sdlSupport >= SDLSupport.sdl209) { 64 SDL_Thread* SDL_CreateThreadWithStackSizeImpl(SDL_ThreadFunction fn, const(char)* name, const(size_t) stackSize, void* data) { 65 return SDL_CreateThreadWithStackSize(fn, name, stackSize, data, &_beginthreadex, &_endthreadex); 66 } 67 } 68 } 69 70 71 static if(staticBinding) { 72 extern(C) @nogc nothrow { 73 version(Windows) SDL_Thread* SDL_CreateThread(SDL_ThreadFunction fn, const(char)* name, void* data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); 74 else SDL_Thread* SDL_CreateThread(SDL_ThreadFunction,const(char)*,void*); 75 76 const(char)* SDL_GetThreadName(SDL_Thread* thread); 77 SDL_threadID SDL_ThreadID(); 78 SDL_threadID SDL_GetThreadID(SDL_Thread* thread); 79 int SDL_SetThreadPriority(SDL_ThreadPriority priority); 80 void SDL_WaitThread(SDL_Thread* thread, int* status); 81 SDL_TLSID SDL_TLSCreate(); 82 void* SDL_TLSGet(SDL_TLSID id); 83 int SDL_TLSSet(SDL_TLSID id,const(void)* value, TLSDestructor destructor); 84 85 static if(sdlSupport >= SDLSupport.sdl202) { 86 void SDL_DetachThread(SDL_Thread* thread); 87 } 88 static if(sdlSupport >= SDLSupport.sdl209) { 89 version(Windows) SDL_Thread* SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const(char)* name, const(size_t) stacksize, void* data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); 90 else SDL_Thread* SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const(char)* name, const(size_t) stacksize, void* data); 91 } 92 } 93 } 94 else { 95 extern(C) @nogc nothrow { 96 version(Windows)alias pSDL_CreateThread = SDL_Thread* function(SDL_ThreadFunction fn, const(char)* name, void* data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); 97 else alias pSDL_CreateThread = SDL_Thread* function(SDL_ThreadFunction fn, const(char)* name, void* data); 98 99 alias pSDL_GetThreadName = const(char)* function(SDL_Thread* thread); 100 alias pSDL_ThreadID = SDL_threadID function(); 101 alias pSDL_GetThreadID = SDL_threadID function(SDL_Thread* thread); 102 alias pSDL_SetThreadPriority = int function(SDL_ThreadPriority priority); 103 alias pSDL_WaitThread = void function(SDL_Thread* thread, int* status); 104 alias pSDL_TLSCreate = SDL_TLSID function(); 105 alias pSDL_TLSGet = void* function(SDL_TLSID id); 106 alias pSDL_TLSSet = int function(SDL_TLSID id,const(void)* value, TLSDestructor destructor); 107 } 108 109 __gshared { 110 pSDL_CreateThread SDL_CreateThread; 111 pSDL_GetThreadName SDL_GetThreadName; 112 pSDL_ThreadID SDL_ThreadID; 113 pSDL_GetThreadID SDL_GetThreadID; 114 pSDL_SetThreadPriority SDL_SetThreadPriority; 115 pSDL_WaitThread SDL_WaitThread; 116 pSDL_TLSCreate SDL_TLSCreate; 117 pSDL_TLSGet SDL_TLSGet; 118 pSDL_TLSSet SDL_TLSSet; 119 } 120 121 static if(sdlSupport >= SDLSupport.sdl202) { 122 extern(C) @nogc nothrow { 123 alias pSDL_DetachThread = void function(SDL_Thread* thread); 124 } 125 __gshared { 126 pSDL_DetachThread SDL_DetachThread; 127 } 128 } 129 static if(sdlSupport >= SDLSupport.sdl209) { 130 131 extern(C) @nogc nothrow { 132 version(Windows) alias pSDL_CreateThreadWithStackSize = SDL_Thread* function(SDL_ThreadFunction fn, const(char)* name, const(size_t) stacksize, void* data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); 133 else alias pSDL_CreateThreadWithStackSize = SDL_Thread* function(SDL_ThreadFunction fn, const(char)* name, const(size_t) stacksize, void* data); 134 } 135 136 __gshared { 137 pSDL_CreateThreadWithStackSize SDL_CreateThreadWithStackSize; 138 } 139 } 140 }