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