1.3 API CHANGE: Add support for naming threads.
authorRyan C. Gordon <icculus@icculus.org>
Sun, 02 Oct 2011 00:29:16 -0400
changeset 5969 3a041d215edc
parent 5968 b229328c7ad4
child 5970 34263edce4f4
1.3 API CHANGE: Add support for naming threads.
configure.in
include/SDL_config.h.in
include/SDL_thread.h
src/audio/SDL_audio.c
src/main/beos/SDL_BeApp.cc
src/thread/SDL_systhread.h
src/thread/SDL_thread.c
src/thread/SDL_thread_c.h
src/thread/beos/SDL_systhread.c
src/thread/generic/SDL_systhread.c
src/thread/irix/SDL_systhread.c
src/thread/nds/SDL_systhread.c
src/thread/pthread/SDL_systhread.c
src/thread/windows/SDL_systhread.c
src/timer/SDL_timer.c
test/testatomic.c
test/testerror.c
test/testlock.c
test/testsem.c
test/testthread.c
test/threadwin.c
test/torturethread.c
--- a/configure.in	Tue Sep 27 23:16:04 2011 -0400
+++ b/configure.in	Sun Oct 02 00:29:16 2011 -0400
@@ -1642,6 +1642,30 @@
             ])
             AC_MSG_RESULT($has_pthread_spin_trylock)
 
+            AC_CHECK_HEADER(pthread_np.h, have_pthread_np_h=yes)
+            if test x$have_pthread_np_h = xyes; then
+                AC_DEFINE(HAVE_PTHREAD_NP_H, 1, [ ])
+            fi
+
+            # Check to see if pthread naming is available
+            AC_MSG_CHECKING(for pthread_setname_np)
+            AC_TRY_LINK_FUNC(pthread_setname_np, [
+              has_pthread_setname_np=yes
+              AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [ ])
+            ],[
+              has_pthread_setname_np=no
+            ])
+            AC_MSG_RESULT($has_pthread_setname_np)
+
+            AC_MSG_CHECKING(for pthread_set_name_np)
+            AC_TRY_LINK_FUNC(pthread_set_name_np, [
+              has_pthread_set_name_np=yes
+              AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [ ])
+            ],[
+              has_pthread_set_name_np=no
+            ])
+            AC_MSG_RESULT($has_pthread_set_name_np)
+
             # Restore the compiler flags and libraries
             CFLAGS="$ac_save_cflags"; LIBS="$ac_save_libs"
 
--- a/include/SDL_config.h.in	Tue Sep 27 23:16:04 2011 -0400
+++ b/include/SDL_config.h.in	Sun Oct 02 00:29:16 2011 -0400
@@ -69,6 +69,7 @@
 #undef HAVE_ICONV_H
 #undef HAVE_SIGNAL_H
 #undef HAVE_ALTIVEC_H
+#undef HAVE_PTHREAD_NP_H
 
 /* C library functions */
 #undef HAVE_MALLOC
@@ -148,6 +149,8 @@
 #undef HAVE_GETPAGESIZE
 #undef HAVE_MPROTECT
 #undef HAVE_ICONV
+#undef HAVE_PTHREAD_SETNAME_NP
+#undef HAVE_PTHREAD_SET_NAME_NP
 
 #else
 /* We may need some replacement for stdarg.h here */
--- a/include/SDL_thread.h	Tue Sep 27 23:16:04 2011 -0400
+++ b/include/SDL_thread.h	Sun Oct 02 00:29:16 2011 -0400
@@ -102,7 +102,7 @@
  *  Create a thread.
  */
 extern DECLSPEC SDL_Thread *SDLCALL
-SDL_CreateThread(SDL_ThreadFunction fn, void *data,
+SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
                  pfnSDL_CurrentBeginThread pfnBeginThread,
                  pfnSDL_CurrentEndThread pfnEndThread);
 
@@ -111,27 +111,51 @@
 /**
  *  Create a thread.
  */
-#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, NULL, NULL)
+#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, NULL, NULL)
 
 #else
 
 /**
  *  Create a thread.
  */
-#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthreadex, _endthreadex)
+#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, _beginthreadex, _endthreadex)
 
 #endif
 #else
 
 /**
  *  Create a thread.
+ *
+ *   Thread naming is a little complicated: Most systems have very small
+ *    limits for the string length (BeOS has 32 bytes, Linux currently has 16,
+ *    Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You'll
+ *    have to see what happens with your system's debugger. The name should be
+ *    UTF-8 (but using the naming limits of C identifiers is a better bet).
+ *   There are no requirements for thread naming conventions, so long as the
+ *    string is null-terminated UTF-8, but these guidelines are helpful in
+ *    choosing a name:
+ *
+ *    http://stackoverflow.com/questions/149932/naming-conventions-for-threads
+ *
+ *   If a system imposes requirements, SDL will try to munge the string for
+ *    it (truncate, etc), but the original string contents will be available
+ *    from SDL_GetThreadName().
  */
 extern DECLSPEC SDL_Thread *SDLCALL
-SDL_CreateThread(SDL_ThreadFunction fn, void *data);
+SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
 
 #endif
 
 /**
+ * Get the thread name, as it was specified in SDL_CreateThread().
+ *  This function returns a pointer to a UTF-8 string that names the
+ *  specified thread, or NULL if it doesn't have a name. This is internal
+ *  memory, not to be free()'d by the caller, and remains valid until the
+ *  specified thread is cleaned up by SDL_WaitThread().
+ */
+extern DECLSPEC const char *SDLCALL SDL_GetThreadName(SDL_Thread *thread);
+
+/**
  *  Get the thread identifier for the current thread.
  */
 extern DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void);
--- a/src/audio/SDL_audio.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/audio/SDL_audio.c	Sun Oct 02 00:29:16 2011 -0400
@@ -1033,12 +1033,14 @@
     /* Start the audio thread if necessary */
     if (!current_audio.impl.ProvidesOwnCallbackThread) {
         /* Start the audio thread */
+        char name[64];
+        SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) (id + 1));
 /* !!! FIXME: this is nasty. */
 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
 #undef SDL_CreateThread
-        device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL);
+        device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL);
 #else
-        device->thread = SDL_CreateThread(SDL_RunAudio, device);
+        device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
 #endif
         if (device->thread == NULL) {
             SDL_CloseAudioDevice(id + 1);
--- a/src/main/beos/SDL_BeApp.cc	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/main/beos/SDL_BeApp.cc	Sun Oct 02 00:29:16 2011 -0400
@@ -60,7 +60,7 @@
 {
     /* Create the BApplication that handles appserver interaction */
     if (SDL_BeAppActive <= 0) {
-        SDL_AppThread = SDL_CreateThread(StartBeApp, NULL);
+        SDL_AppThread = SDL_CreateThread(StartBeApp, "SDLApplication", NULL);
         if (SDL_AppThread == NULL) {
             SDL_SetError("Couldn't create BApplication thread");
             return (-1);
--- a/src/thread/SDL_systhread.h	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/thread/SDL_systhread.h	Sun Oct 02 00:29:16 2011 -0400
@@ -40,7 +40,7 @@
 #endif
 
 /* This function does any necessary setup in the child thread */
-extern void SDL_SYS_SetupThread(void);
+extern void SDL_SYS_SetupThread(const char *name);
 
 /* This function sets the current thread priority */
 extern int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority);
--- a/src/thread/SDL_thread.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/thread/SDL_thread.c	Sun Oct 02 00:29:16 2011 -0400
@@ -188,25 +188,19 @@
 void
 SDL_RunThread(void *data)
 {
-    thread_args *args;
-    int (SDLCALL * userfunc) (void *);
-    void *userdata;
-    int *statusloc;
+    thread_args *args = (thread_args *) data;
+    int (SDLCALL * userfunc) (void *) = args->func;
+    void *userdata = args->data;
+    int *statusloc = &args->info->status;
 
     /* Perform any system-dependent setup
        - this function cannot fail, and cannot use SDL_SetError()
      */
-    SDL_SYS_SetupThread();
+    SDL_SYS_SetupThread(args->info->name);
 
     /* Get the thread id */
-    args = (thread_args *) data;
     args->info->threadid = SDL_ThreadID();
 
-    /* Figure out what function to run */
-    userfunc = args->func;
-    userdata = args->data;
-    statusloc = &args->info->status;
-
     /* Wake up the parent thread */
     SDL_SemPost(args->wait);
 
@@ -217,12 +211,14 @@
 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
 #undef SDL_CreateThread
 DECLSPEC SDL_Thread *SDLCALL
-SDL_CreateThread(int (SDLCALL * fn) (void *), void *data,
+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 *), void *data)
+SDL_CreateThread(int (SDLCALL * fn) (void *),
+                 const char *name, void *data)
 #endif
 {
     SDL_Thread *thread;
@@ -239,9 +235,20 @@
     thread->status = -1;
 
     /* Set up the arguments for the thread */
+    if (name != NULL) {
+        thread->name = SDL_strdup(name);
+        if (thread->name == NULL) {
+            SDL_OutOfMemory();
+            SDL_free(thread);
+            return (NULL);
+        }
+    }
+
+    /* Set up the arguments for the thread */
     args = (thread_args *) SDL_malloc(sizeof(*args));
     if (args == NULL) {
         SDL_OutOfMemory();
+        SDL_free(thread->name);
         SDL_free(thread);
         return (NULL);
     }
@@ -250,6 +257,7 @@
     args->info = thread;
     args->wait = SDL_CreateSemaphore(0);
     if (args->wait == NULL) {
+        SDL_free(thread->name);
         SDL_free(thread);
         SDL_free(args);
         return (NULL);
@@ -270,6 +278,7 @@
     } else {
         /* Oops, failed.  Gotta free everything */
         SDL_DelThread(thread);
+        SDL_free(thread->name);
         SDL_free(thread);
         thread = NULL;
     }
@@ -293,6 +302,12 @@
     return id;
 }
 
+const char *
+SDL_GetThreadName(SDL_Thread * thread)
+{
+    return thread->name;
+}
+
 int
 SDL_SetThreadPriority(SDL_ThreadPriority priority)
 {
@@ -308,6 +323,7 @@
             *status = thread->status;
         }
         SDL_DelThread(thread);
+        SDL_free(thread->name);
         SDL_free(thread);
     }
 }
--- a/src/thread/SDL_thread_c.h	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/thread/SDL_thread_c.h	Sun Oct 02 00:29:16 2011 -0400
@@ -51,6 +51,7 @@
     SYS_ThreadHandle handle;
     int status;
     SDL_error errbuf;
+    char *name;
     void *data;
 };
 
--- a/src/thread/beos/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/thread/beos/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
@@ -65,8 +65,13 @@
 int
 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
 {
+    /* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */
+    char name[B_OS_NAME_LENGTH];
+    SDL_snprintf(name, sizeof (name), "%s", thread->name);
+    name[sizeof (name) - 1] = '\0';
+
     /* Create the thread and go! */
-    thread->handle = spawn_thread(RunThread, "SDL", B_NORMAL_PRIORITY, args);
+    thread->handle = spawn_thread(RunThread, name, B_NORMAL_PRIORITY, args);
     if ((thread->handle == B_NO_MORE_THREADS) ||
         (thread->handle == B_NO_MEMORY)) {
         SDL_SetError("Not enough resources to create thread");
@@ -77,8 +82,9 @@
 }
 
 void
-SDL_SYS_SetupThread(void)
+SDL_SYS_SetupThread(const char *name)
 {
+    /* We set the thread name during SDL_SYS_CreateThread(). */
     /* Mask asynchronous signals for this thread */
     SDL_MaskSignals(NULL);
 }
--- a/src/thread/generic/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/thread/generic/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
@@ -33,7 +33,7 @@
 }
 
 void
-SDL_SYS_SetupThread(void)
+SDL_SYS_SetupThread(const char *name)
 {
     return;
 }
--- a/src/thread/irix/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/thread/irix/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
@@ -50,7 +50,7 @@
 }
 
 void
-SDL_SYS_SetupThread(void)
+SDL_SYS_SetupThread(const char *name)
 {
     int i;
     sigset_t mask;
--- a/src/thread/nds/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/thread/nds/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
@@ -38,7 +38,7 @@
 }
 
 void
-SDL_SYS_SetupThread(void)
+SDL_SYS_SetupThread(const char *name)
 {
     return;
 }
--- a/src/thread/pthread/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/thread/pthread/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
@@ -21,6 +21,11 @@
 #include "SDL_config.h"
 
 #include <pthread.h>
+
+#if HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+
 #include <signal.h>
 #ifdef __LINUX__
 #include <sys/time.h>
@@ -28,6 +33,7 @@
 #include <sys/syscall.h>
 #endif
 
+#include "SDL_platform.h"
 #include "SDL_thread.h"
 #include "../SDL_thread_c.h"
 #include "../SDL_systhread.h"
@@ -67,12 +73,27 @@
     return (0);
 }
 
+/* make pthread_setname_np() a weak reference even without SDK support. */
+#if __MACOSX__ && (MAC_OS_X_VERSION_MAX_ALLOWED < 1060)
+int pthread_setname_np(const char*) __attribute__((weak_import,visibility("default")));
+#elif __IPHONEOS__ && (__IPHONE_OS_VERSION_MAX_ALLOWED < 30200)
+int pthread_setname_np(const char*) __attribute__((weak_import));
+#endif
+
 void
-SDL_SYS_SetupThread(void)
+SDL_SYS_SetupThread(const char *name)
 {
     int i;
     sigset_t mask;
 
+#if __MACOSX__ || __IPHONEOS__
+    if (pthread_setname_np != NULL) { pthread_setname_np(name); }
+#elif HAVE_PTHREAD_SETNAME_NP
+    pthread_setname_np(pthread_self(), name);
+#elif HAVE_PTHREAD_SET_NAME_NP
+    pthread_set_name_np(pthread_self(), name);
+#endif
+
     /* Mask asynchronous signals for this thread */
     sigemptyset(&mask);
     for (i = 0; sig_list[i]; ++i) {
--- a/src/thread/windows/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/thread/windows/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
@@ -146,10 +146,38 @@
     return (0);
 }
 
+#ifdef _MSC_VER
+#pragma pack(push,8)
+typedef struct tagTHREADNAME_INFO
+{
+    DWORD dwType; /* must be 0x1000 */
+    LPCSTR szName; /* pointer to name (in user addr space) */
+    DWORD dwThreadID; /* thread ID (-1=caller thread) */
+    DWORD dwFlags; /* reserved for future use, must be zero */
+} THREADNAME_INFO;
+#pragma pack(pop)
+#endif
+
 void
-SDL_SYS_SetupThread(void)
+SDL_SYS_SetupThread(const char *name)
 {
-    return;
+#ifdef _MSC_VER  /* !!! FIXME: can we do SEH on other compilers yet? */
+    /* This magic tells the debugger to name a thread if it's listening. */
+    THREADNAME_INFO inf;
+    info.dwType = 0x1000;
+    info.szName = name;
+    info.dwThreadID = (DWORD) -1;
+    info.dwFlags = 0;
+
+    __try
+    {
+        RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf);
+    }
+    except(EXCEPTION_CONTINUE_EXECUTION)
+    {
+        /* The program itself should ignore this bogus exception. */
+    }
+#endif
 }
 
 SDL_threadID
--- a/src/timer/SDL_timer.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/src/timer/SDL_timer.c	Sun Oct 02 00:29:16 2011 -0400
@@ -209,6 +209,7 @@
     SDL_TimerData *data = &SDL_timer_data;
 
     if (!data->active) {
+        const char *name = "SDLTimer";
         data->timermap_lock = SDL_CreateMutex();
         if (!data->timermap_lock) {
             return -1;
@@ -224,9 +225,9 @@
         /* !!! FIXME: this is nasty. */
 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
 #undef SDL_CreateThread
-        data->thread = SDL_CreateThread(SDL_TimerThread, data, NULL, NULL);
+        data->thread = SDL_CreateThread(SDL_TimerThread, name, data, NULL, NULL);
 #else
-        data->thread = SDL_CreateThread(SDL_TimerThread, data);
+        data->thread = SDL_CreateThread(SDL_TimerThread, name, data);
 #endif
         if (!data->thread) {
             SDL_TimerQuit();
--- a/test/testatomic.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/test/testatomic.c	Sun Oct 02 00:29:16 2011 -0400
@@ -143,7 +143,7 @@
     SDL_AtomicSet(&threadsRunning, NThreads);
 
     while (T--)
-        SDL_CreateThread(adder, NULL);
+        SDL_CreateThread(adder, "Adder", NULL);
  
     while (SDL_AtomicGet(&threadsRunning) > 0)
         SDL_SemWait(threadDone);
@@ -618,7 +618,7 @@
 #ifdef TEST_SPINLOCK_FIFO
     /* Start a monitoring thread */
     if (lock_free) {
-        SDL_CreateThread(FIFO_Watcher, &queue);
+        SDL_CreateThread(FIFO_Watcher, "FIFOWatcher", &queue);
     }
 #endif
 
@@ -627,9 +627,11 @@
     SDL_zero(readerData);
     SDL_AtomicSet(&readersRunning, NUM_READERS);
     for (i = 0; i < NUM_READERS; ++i) {
+        char name[64];
+        SDL_snprintf(name, sizeof (name), "FIFOReader%d", i);
         readerData[i].queue = &queue;
         readerData[i].lock_free = lock_free;
-        SDL_CreateThread(FIFO_Reader, &readerData[i]);
+        SDL_CreateThread(FIFO_Reader, name, &readerData[i]);
     }
 
     /* Start up the writers */
@@ -637,10 +639,12 @@
     SDL_zero(writerData);
     SDL_AtomicSet(&writersRunning, NUM_WRITERS);
     for (i = 0; i < NUM_WRITERS; ++i) {
+        char name[64];
+        SDL_snprintf(name, sizeof (name), "FIFOWriter%d", i);
         writerData[i].queue = &queue;
         writerData[i].index = i;
         writerData[i].lock_free = lock_free;
-        SDL_CreateThread(FIFO_Writer, &writerData[i]);
+        SDL_CreateThread(FIFO_Writer, name, &writerData[i]);
     }
  
     /* Wait for the writers */
--- a/test/testerror.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/test/testerror.c	Sun Oct 02 00:29:16 2011 -0400
@@ -58,7 +58,7 @@
     SDL_SetError("No worries");
 
     alive = 1;
-    thread = SDL_CreateThread(ThreadFunc, "#1");
+    thread = SDL_CreateThread(ThreadFunc, NULL, "#1");
     if (thread == NULL) {
         fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError());
         quit(1);
--- a/test/testlock.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/test/testlock.c	Sun Oct 02 00:29:16 2011 -0400
@@ -112,7 +112,9 @@
     printf("Main thread: %lu\n", mainthread);
     atexit(printid);
     for (i = 0; i < maxproc; ++i) {
-        if ((threads[i] = SDL_CreateThread(Run, NULL)) == NULL)
+        char name[64];
+        SDL_snprintf(name, sizeof (name), "Worker%d", i);
+        if ((threads[i] = SDL_CreateThread(Run, name, NULL)) == NULL)
             fprintf(stderr, "Couldn't create thread!\n");
     }
     signal(SIGINT, terminate);
--- a/test/testsem.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/test/testsem.c	Sun Oct 02 00:29:16 2011 -0400
@@ -100,7 +100,9 @@
            init_sem);
     /* Create all the threads */
     for (i = 0; i < NUM_THREADS; ++i) {
-        threads[i] = SDL_CreateThread(ThreadFunc, (void *) i);
+        char name[64];
+        SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i);
+        threads[i] = SDL_CreateThread(ThreadFunc, name, (void *) i);
     }
 
     /* Wait 10 seconds */
--- a/test/testthread.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/test/testthread.c	Sun Oct 02 00:29:16 2011 -0400
@@ -63,7 +63,7 @@
     }
 
     alive = 1;
-    thread = SDL_CreateThread(ThreadFunc, "#1");
+    thread = SDL_CreateThread(ThreadFunc, "One", "#1");
     if (thread == NULL) {
         fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError());
         quit(1);
@@ -75,7 +75,7 @@
 
     alive = 1;
     signal(SIGTERM, killed);
-    thread = SDL_CreateThread(ThreadFunc, "#2");
+    thread = SDL_CreateThread(ThreadFunc, "Two", "#2");
     if (thread == NULL) {
         fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError());
         quit(1);
--- a/test/threadwin.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/test/threadwin.c	Sun Oct 02 00:29:16 2011 -0400
@@ -296,8 +296,8 @@
     SDL_SetEventFilter(FilterEvents, NULL);
 
     /* Create the event handling threads */
-    mouse_thread = SDL_CreateThread(HandleMouse, NULL);
-    keybd_thread = SDL_CreateThread(HandleKeyboard, NULL);
+    mouse_thread = SDL_CreateThread(HandleMouse, "MouseHandler", NULL);
+    keybd_thread = SDL_CreateThread(HandleKeyboard, "KeyboardHandler", NULL);
 
     /* Set the surface pixels and refresh! */
     for (i = 0; i < 256; ++i) {
--- a/test/torturethread.c	Tue Sep 27 23:16:04 2011 -0400
+++ b/test/torturethread.c	Sun Oct 02 00:29:16 2011 -0400
@@ -52,8 +52,10 @@
     fprintf(stderr, "Creating Thread %d\n", tid);
 
     for (i = 0; i < NUMTHREADS; i++) {
+        char name[64];
+        SDL_snprintf(name, sizeof (name), "Child%d_%d", tid, i);
         flags[i] = 0;
-        sub_threads[i] = SDL_CreateThread(SubThreadFunc, &flags[i]);
+        sub_threads[i] = SDL_CreateThread(SubThreadFunc, name, &flags[i]);
     }
 
     printf("Thread '%d' waiting for signal\n", tid);
@@ -86,8 +88,10 @@
 
     signal(SIGSEGV, SIG_DFL);
     for (i = 0; i < NUMTHREADS; i++) {
+        char name[64];
+        SDL_snprintf(name, sizeof (name), "Parent%d", i);
         time_for_threads_to_die[i] = 0;
-        threads[i] = SDL_CreateThread(ThreadFunc, (void *) (uintptr_t) i);
+        threads[i] = SDL_CreateThread(ThreadFunc, name, (void*) (uintptr_t) i);
 
         if (threads[i] == NULL) {
             fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError());