From 7ae2951fca4629508e135b43bbc3b711bca525d7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 12 Apr 2016 14:38:50 -0400 Subject: [PATCH] threads: Handle SDL_HINT_THREAD_STACK_SIZE at top level, implement elsewhere. --- src/thread/SDL_thread.c | 49 +++++++++++++++++++++++++---- src/thread/SDL_thread_c.h | 14 +++++++++ src/thread/psp/SDL_systhread.c | 4 +-- src/thread/pthread/SDL_systhread.c | 11 ++----- src/thread/stdcpp/SDL_systhread.cpp | 1 + src/thread/windows/SDL_systhread.c | 7 +++-- 6 files changed, 68 insertions(+), 18 deletions(-) diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index e66c5819cdea2..1306ae00dada0 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -26,6 +26,7 @@ #include "SDL_thread.h" #include "SDL_thread_c.h" #include "SDL_systhread.h" +#include "SDL_hints.h" #include "../SDL_error_c.h" @@ -304,15 +305,15 @@ SDL_RunThread(void *data) #endif #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD -DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(int (SDLCALL * fn) (void *), - const char *name, void *data, +static SDL_Thread * +SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), + const char *name, const size_t stacksize, void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread) #else -DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(int (SDLCALL * fn) (void *), - const char *name, void *data) +static SDL_Thread * +SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), + const char *name, const size_t stacksize, void *data) #endif { SDL_Thread *thread; @@ -362,6 +363,8 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), return (NULL); } + thread->stacksize = stacksize; + /* Create the thread and go! */ #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD ret = SDL_SYS_CreateThread(thread, args, pfnBeginThread, pfnEndThread); @@ -386,6 +389,40 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), return (thread); } +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD +DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(int (SDLCALL * fn) (void *), + const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) +#else +DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(int (SDLCALL * fn) (void *), + const char *name, void *data) +#endif +{ + /* !!! FIXME: in 2.1, just make stackhint part of the usual API. */ + const char *stackhint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE); + size_t stacksize = 0; + + /* If the SDL_HINT_THREAD_STACK_SIZE exists, use it */ + if (stackhint != NULL) { + char *endp = NULL; + const Sint64 hintval = SDL_strtoll(stackhint, &endp, 10); + if ((*stackhint != '\0') && (*endp == '\0')) { /* a valid number? */ + if (hintval > 0) { /* reject bogus values. */ + stacksize = (size_t) hintval; + } + } + } + +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD + return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, pfnBeginThread, pfnEndThread); +#else + return SDL_CreateThreadWithStackSize(fn, name, stacksize, data); +#endif +} + SDL_threadID SDL_GetThreadID(SDL_Thread * thread) { diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index a283a0e2cabdc..7749183d09b31 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -59,6 +59,7 @@ struct SDL_Thread SDL_atomic_t state; /* SDL_THREAD_STATE_* */ SDL_error errbuf; char *name; + size_t stacksize; /* 0 for default, >0 for user-specified stack size. */ void *data; }; @@ -89,6 +90,19 @@ extern SDL_TLSData *SDL_Generic_GetTLSData(); */ extern int SDL_Generic_SetTLSData(SDL_TLSData *data); +/* !!! FIXME: for 2.1, remove this and make stack size part of SDL_CreateThread. */ +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD +SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), + const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) +#else +SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), + const char *name, const size_t stacksize, void *data) +#endif + #endif /* _SDL_thread_c_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/psp/SDL_systhread.c b/src/thread/psp/SDL_systhread.c index ab8aff3766a87..96f2e1dc19814 100644 --- a/src/thread/psp/SDL_systhread.c +++ b/src/thread/psp/SDL_systhread.c @@ -52,8 +52,8 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) priority = status.currentPriority; } - thread->handle = sceKernelCreateThread("SDL thread", ThreadEntry, - priority, 0x8000, + thread->handle = sceKernelCreateThread(thread->name, ThreadEntry, + priority, thread->stacksize ? ((int) stacksize) : 0x8000, PSP_THREAD_ATTR_VFPU, NULL); if (thread->handle < 0) { return SDL_SetError("sceKernelCreateThread() failed"); diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c index 22f7bd57b4347..79d6543750d6d 100644 --- a/src/thread/pthread/SDL_systhread.c +++ b/src/thread/pthread/SDL_systhread.c @@ -45,7 +45,6 @@ #include "SDL_platform.h" #include "SDL_thread.h" -#include "SDL_hints.h" #include "../SDL_thread_c.h" #include "../SDL_systhread.h" #ifdef __ANDROID__ @@ -87,7 +86,6 @@ int SDL_SYS_CreateThread(SDL_Thread * thread, void *args) { pthread_attr_t type; - const char *hint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE); /* do this here before any threads exist, so there's no race condition. */ #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) @@ -108,12 +106,9 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) } pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE); - /* If the SDL_HINT_THREAD_STACK_SIZE exists and it seems to be a positive number, use it */ - if (hint && hint[0] >= '0' && hint[0] <= '9') { - const size_t stacksize = (size_t) SDL_atoi(hint); - if (stacksize > 0) { - pthread_attr_setstacksize(&type, stacksize); - } + /* Set caller-requested stack size. Otherwise: use the system default. */ + if (thread->stacksize) { + pthread_attr_setstacksize(&type, (size_t) thread->stacksize); } /* Create the thread and go! */ diff --git a/src/thread/stdcpp/SDL_systhread.cpp b/src/thread/stdcpp/SDL_systhread.cpp index 219c67e931ffa..6e5ef473e039b 100644 --- a/src/thread/stdcpp/SDL_systhread.cpp +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -48,6 +48,7 @@ int SDL_SYS_CreateThread(SDL_Thread * thread, void *args) { try { + // !!! FIXME: no way to set a thread stack size here. std::thread cpp_thread(RunThread, args); thread->handle = (void *) new std::thread(std::move(cpp_thread)); return 0; diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c index 2f22b890bf2ef..249e361ba44cb 100644 --- a/src/thread/windows/SDL_systhread.c +++ b/src/thread/windows/SDL_systhread.c @@ -129,14 +129,17 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) /* Also save the real parameters we have to pass to thread function */ pThreadParms->args = args; + /* thread->stacksize == 0 means "system default", same as win32 expects */ if (pfnBeginThread) { unsigned threadid = 0; thread->handle = (SYS_ThreadHandle) - ((size_t) pfnBeginThread(NULL, 0, RunThreadViaBeginThreadEx, + ((size_t) pfnBeginThread(NULL, (unsigned int) thread->stacksize, + RunThreadViaBeginThreadEx, pThreadParms, 0, &threadid)); } else { DWORD threadid = 0; - thread->handle = CreateThread(NULL, 0, RunThreadViaCreateThread, + thread->handle = CreateThread(NULL, thread->stacksize, + RunThreadViaCreateThread, pThreadParms, 0, &threadid); } if (thread->handle == NULL) {