Commit a8fa7bd1f7c1658ba7505e04cacfc63c481192ea

Ryan C. Gordon 2015-05-26T21:13:27

Added a hint to specify new thread stack size (thanks, Gabriel!). Fixes Bugzilla #2019. (we'll do a better fix when we break the API in SDL 2.1.)

diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index cc4d60f..69cb8ba 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -348,6 +348,18 @@ extern "C" {
 #define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION"
 
 
+
+/**
+*  \brief  A string specifying SDL's threads stack size in bytes or "-1" for the backend's default size
+*
+*  Use this hint in case you need to set SDL's threads stack size to other than the default.
+*  This is specially useful if you build SDL against a non glibc libc library (such as musl) which
+*  provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses).
+*  Support for this hint is currenly available only in the pthread backend.
+*  As a precaution, this hint can not be set via an environment variable.
+*/
+#define SDL_HINT_THREAD_STACK_SIZE              "SDL_THREAD_STACK_SIZE"
+
 /**
  *  \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS)
  */
diff --git a/src/SDL.c b/src/SDL.c
index 6318bbe..75d05a8 100644
--- a/src/SDL.c
+++ b/src/SDL.c
@@ -107,6 +107,7 @@ SDL_SetMainReady(void)
 int
 SDL_InitSubSystem(Uint32 flags)
 {
+    static Uint32 hints_initialized = SDL_FALSE;
     if (!SDL_MainIsReady) {
         SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
         return -1;
@@ -114,6 +115,13 @@ SDL_InitSubSystem(Uint32 flags)
 
     /* Clear the error message */
     SDL_ClearError();
+    
+    if (hints_initialized == SDL_FALSE) {
+        /* Set a default of -1 for SDL_HINT_THREAD_STACK_SIZE to prevent the
+           end user from interfering it's value with environment variables */
+        SDL_SetHintWithPriority(SDL_HINT_THREAD_STACK_SIZE, "-1", SDL_HINT_OVERRIDE);
+        hints_initialized = SDL_TRUE;
+    }
 
 #if SDL_VIDEO_DRIVER_WINDOWS
 	if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c
index 57b7fb8..a6f5b73 100644
--- a/src/thread/pthread/SDL_systhread.c
+++ b/src/thread/pthread/SDL_systhread.c
@@ -45,6 +45,7 @@
 
 #include "SDL_platform.h"
 #include "SDL_thread.h"
+#include "SDL_hints.h"
 #include "../SDL_thread_c.h"
 #include "../SDL_systhread.h"
 #ifdef __ANDROID__
@@ -86,6 +87,8 @@ int
 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
 {
     pthread_attr_t type;
+    size_t ss;
+    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__)
@@ -105,6 +108,13 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
         return SDL_SetError("Couldn't initialize pthread attributes");
     }
     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') {
+        pthread_attr_setstacksize(&type, (size_t)SDL_atoi(hint));
+    }
+    
+    pthread_attr_getstacksize(&type, &ss);
 
     /* Create the thread and go! */
     if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {
diff --git a/test/torturethread.c b/test/torturethread.c
index efbab5e..116ec09 100644
--- a/test/torturethread.c
+++ b/test/torturethread.c
@@ -87,6 +87,8 @@ main(int argc, char *argv[])
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
         return (1);
     }
+    
+    SDL_SetHintWithPriority(SDL_HINT_THREAD_STACK_SIZE, SDL_getenv(SDL_HINT_THREAD_STACK_SIZE), SDL_HINT_OVERRIDE);
 
     signal(SIGSEGV, SIG_DFL);
     for (i = 0; i < NUMTHREADS; i++) {