1.3 API CHANGE: Add support for naming threads.
authorRyan C. Gordon <icculus@icculus.org>
Sun, 02 Oct 2011 00:29:16 -0400
changeset 59693a041d215edc
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
     1.1 --- a/configure.in	Tue Sep 27 23:16:04 2011 -0400
     1.2 +++ b/configure.in	Sun Oct 02 00:29:16 2011 -0400
     1.3 @@ -1642,6 +1642,30 @@
     1.4              ])
     1.5              AC_MSG_RESULT($has_pthread_spin_trylock)
     1.6  
     1.7 +            AC_CHECK_HEADER(pthread_np.h, have_pthread_np_h=yes)
     1.8 +            if test x$have_pthread_np_h = xyes; then
     1.9 +                AC_DEFINE(HAVE_PTHREAD_NP_H, 1, [ ])
    1.10 +            fi
    1.11 +
    1.12 +            # Check to see if pthread naming is available
    1.13 +            AC_MSG_CHECKING(for pthread_setname_np)
    1.14 +            AC_TRY_LINK_FUNC(pthread_setname_np, [
    1.15 +              has_pthread_setname_np=yes
    1.16 +              AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [ ])
    1.17 +            ],[
    1.18 +              has_pthread_setname_np=no
    1.19 +            ])
    1.20 +            AC_MSG_RESULT($has_pthread_setname_np)
    1.21 +
    1.22 +            AC_MSG_CHECKING(for pthread_set_name_np)
    1.23 +            AC_TRY_LINK_FUNC(pthread_set_name_np, [
    1.24 +              has_pthread_set_name_np=yes
    1.25 +              AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [ ])
    1.26 +            ],[
    1.27 +              has_pthread_set_name_np=no
    1.28 +            ])
    1.29 +            AC_MSG_RESULT($has_pthread_set_name_np)
    1.30 +
    1.31              # Restore the compiler flags and libraries
    1.32              CFLAGS="$ac_save_cflags"; LIBS="$ac_save_libs"
    1.33  
     2.1 --- a/include/SDL_config.h.in	Tue Sep 27 23:16:04 2011 -0400
     2.2 +++ b/include/SDL_config.h.in	Sun Oct 02 00:29:16 2011 -0400
     2.3 @@ -69,6 +69,7 @@
     2.4  #undef HAVE_ICONV_H
     2.5  #undef HAVE_SIGNAL_H
     2.6  #undef HAVE_ALTIVEC_H
     2.7 +#undef HAVE_PTHREAD_NP_H
     2.8  
     2.9  /* C library functions */
    2.10  #undef HAVE_MALLOC
    2.11 @@ -148,6 +149,8 @@
    2.12  #undef HAVE_GETPAGESIZE
    2.13  #undef HAVE_MPROTECT
    2.14  #undef HAVE_ICONV
    2.15 +#undef HAVE_PTHREAD_SETNAME_NP
    2.16 +#undef HAVE_PTHREAD_SET_NAME_NP
    2.17  
    2.18  #else
    2.19  /* We may need some replacement for stdarg.h here */
     3.1 --- a/include/SDL_thread.h	Tue Sep 27 23:16:04 2011 -0400
     3.2 +++ b/include/SDL_thread.h	Sun Oct 02 00:29:16 2011 -0400
     3.3 @@ -102,7 +102,7 @@
     3.4   *  Create a thread.
     3.5   */
     3.6  extern DECLSPEC SDL_Thread *SDLCALL
     3.7 -SDL_CreateThread(SDL_ThreadFunction fn, void *data,
     3.8 +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
     3.9                   pfnSDL_CurrentBeginThread pfnBeginThread,
    3.10                   pfnSDL_CurrentEndThread pfnEndThread);
    3.11  
    3.12 @@ -111,27 +111,51 @@
    3.13  /**
    3.14   *  Create a thread.
    3.15   */
    3.16 -#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, NULL, NULL)
    3.17 +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, NULL, NULL)
    3.18  
    3.19  #else
    3.20  
    3.21  /**
    3.22   *  Create a thread.
    3.23   */
    3.24 -#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthreadex, _endthreadex)
    3.25 +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, _beginthreadex, _endthreadex)
    3.26  
    3.27  #endif
    3.28  #else
    3.29  
    3.30  /**
    3.31   *  Create a thread.
    3.32 + *
    3.33 + *   Thread naming is a little complicated: Most systems have very small
    3.34 + *    limits for the string length (BeOS has 32 bytes, Linux currently has 16,
    3.35 + *    Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You'll
    3.36 + *    have to see what happens with your system's debugger. The name should be
    3.37 + *    UTF-8 (but using the naming limits of C identifiers is a better bet).
    3.38 + *   There are no requirements for thread naming conventions, so long as the
    3.39 + *    string is null-terminated UTF-8, but these guidelines are helpful in
    3.40 + *    choosing a name:
    3.41 + *
    3.42 + *    http://stackoverflow.com/questions/149932/naming-conventions-for-threads
    3.43 + *
    3.44 + *   If a system imposes requirements, SDL will try to munge the string for
    3.45 + *    it (truncate, etc), but the original string contents will be available
    3.46 + *    from SDL_GetThreadName().
    3.47   */
    3.48  extern DECLSPEC SDL_Thread *SDLCALL
    3.49 -SDL_CreateThread(SDL_ThreadFunction fn, void *data);
    3.50 +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
    3.51  
    3.52  #endif
    3.53  
    3.54  /**
    3.55 + * Get the thread name, as it was specified in SDL_CreateThread().
    3.56 + *  This function returns a pointer to a UTF-8 string that names the
    3.57 + *  specified thread, or NULL if it doesn't have a name. This is internal
    3.58 + *  memory, not to be free()'d by the caller, and remains valid until the
    3.59 + *  specified thread is cleaned up by SDL_WaitThread().
    3.60 + */
    3.61 +extern DECLSPEC const char *SDLCALL SDL_GetThreadName(SDL_Thread *thread);
    3.62 +
    3.63 +/**
    3.64   *  Get the thread identifier for the current thread.
    3.65   */
    3.66  extern DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void);
     4.1 --- a/src/audio/SDL_audio.c	Tue Sep 27 23:16:04 2011 -0400
     4.2 +++ b/src/audio/SDL_audio.c	Sun Oct 02 00:29:16 2011 -0400
     4.3 @@ -1033,12 +1033,14 @@
     4.4      /* Start the audio thread if necessary */
     4.5      if (!current_audio.impl.ProvidesOwnCallbackThread) {
     4.6          /* Start the audio thread */
     4.7 +        char name[64];
     4.8 +        SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) (id + 1));
     4.9  /* !!! FIXME: this is nasty. */
    4.10  #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
    4.11  #undef SDL_CreateThread
    4.12 -        device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL);
    4.13 +        device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL);
    4.14  #else
    4.15 -        device->thread = SDL_CreateThread(SDL_RunAudio, device);
    4.16 +        device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
    4.17  #endif
    4.18          if (device->thread == NULL) {
    4.19              SDL_CloseAudioDevice(id + 1);
     5.1 --- a/src/main/beos/SDL_BeApp.cc	Tue Sep 27 23:16:04 2011 -0400
     5.2 +++ b/src/main/beos/SDL_BeApp.cc	Sun Oct 02 00:29:16 2011 -0400
     5.3 @@ -60,7 +60,7 @@
     5.4  {
     5.5      /* Create the BApplication that handles appserver interaction */
     5.6      if (SDL_BeAppActive <= 0) {
     5.7 -        SDL_AppThread = SDL_CreateThread(StartBeApp, NULL);
     5.8 +        SDL_AppThread = SDL_CreateThread(StartBeApp, "SDLApplication", NULL);
     5.9          if (SDL_AppThread == NULL) {
    5.10              SDL_SetError("Couldn't create BApplication thread");
    5.11              return (-1);
     6.1 --- a/src/thread/SDL_systhread.h	Tue Sep 27 23:16:04 2011 -0400
     6.2 +++ b/src/thread/SDL_systhread.h	Sun Oct 02 00:29:16 2011 -0400
     6.3 @@ -40,7 +40,7 @@
     6.4  #endif
     6.5  
     6.6  /* This function does any necessary setup in the child thread */
     6.7 -extern void SDL_SYS_SetupThread(void);
     6.8 +extern void SDL_SYS_SetupThread(const char *name);
     6.9  
    6.10  /* This function sets the current thread priority */
    6.11  extern int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority);
     7.1 --- a/src/thread/SDL_thread.c	Tue Sep 27 23:16:04 2011 -0400
     7.2 +++ b/src/thread/SDL_thread.c	Sun Oct 02 00:29:16 2011 -0400
     7.3 @@ -188,25 +188,19 @@
     7.4  void
     7.5  SDL_RunThread(void *data)
     7.6  {
     7.7 -    thread_args *args;
     7.8 -    int (SDLCALL * userfunc) (void *);
     7.9 -    void *userdata;
    7.10 -    int *statusloc;
    7.11 +    thread_args *args = (thread_args *) data;
    7.12 +    int (SDLCALL * userfunc) (void *) = args->func;
    7.13 +    void *userdata = args->data;
    7.14 +    int *statusloc = &args->info->status;
    7.15  
    7.16      /* Perform any system-dependent setup
    7.17         - this function cannot fail, and cannot use SDL_SetError()
    7.18       */
    7.19 -    SDL_SYS_SetupThread();
    7.20 +    SDL_SYS_SetupThread(args->info->name);
    7.21  
    7.22      /* Get the thread id */
    7.23 -    args = (thread_args *) data;
    7.24      args->info->threadid = SDL_ThreadID();
    7.25  
    7.26 -    /* Figure out what function to run */
    7.27 -    userfunc = args->func;
    7.28 -    userdata = args->data;
    7.29 -    statusloc = &args->info->status;
    7.30 -
    7.31      /* Wake up the parent thread */
    7.32      SDL_SemPost(args->wait);
    7.33  
    7.34 @@ -217,12 +211,14 @@
    7.35  #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
    7.36  #undef SDL_CreateThread
    7.37  DECLSPEC SDL_Thread *SDLCALL
    7.38 -SDL_CreateThread(int (SDLCALL * fn) (void *), void *data,
    7.39 +SDL_CreateThread(int (SDLCALL * fn) (void *),
    7.40 +                 const char *name, void *data,
    7.41                   pfnSDL_CurrentBeginThread pfnBeginThread,
    7.42                   pfnSDL_CurrentEndThread pfnEndThread)
    7.43  #else
    7.44  DECLSPEC SDL_Thread *SDLCALL
    7.45 -SDL_CreateThread(int (SDLCALL * fn) (void *), void *data)
    7.46 +SDL_CreateThread(int (SDLCALL * fn) (void *),
    7.47 +                 const char *name, void *data)
    7.48  #endif
    7.49  {
    7.50      SDL_Thread *thread;
    7.51 @@ -239,9 +235,20 @@
    7.52      thread->status = -1;
    7.53  
    7.54      /* Set up the arguments for the thread */
    7.55 +    if (name != NULL) {
    7.56 +        thread->name = SDL_strdup(name);
    7.57 +        if (thread->name == NULL) {
    7.58 +            SDL_OutOfMemory();
    7.59 +            SDL_free(thread);
    7.60 +            return (NULL);
    7.61 +        }
    7.62 +    }
    7.63 +
    7.64 +    /* Set up the arguments for the thread */
    7.65      args = (thread_args *) SDL_malloc(sizeof(*args));
    7.66      if (args == NULL) {
    7.67          SDL_OutOfMemory();
    7.68 +        SDL_free(thread->name);
    7.69          SDL_free(thread);
    7.70          return (NULL);
    7.71      }
    7.72 @@ -250,6 +257,7 @@
    7.73      args->info = thread;
    7.74      args->wait = SDL_CreateSemaphore(0);
    7.75      if (args->wait == NULL) {
    7.76 +        SDL_free(thread->name);
    7.77          SDL_free(thread);
    7.78          SDL_free(args);
    7.79          return (NULL);
    7.80 @@ -270,6 +278,7 @@
    7.81      } else {
    7.82          /* Oops, failed.  Gotta free everything */
    7.83          SDL_DelThread(thread);
    7.84 +        SDL_free(thread->name);
    7.85          SDL_free(thread);
    7.86          thread = NULL;
    7.87      }
    7.88 @@ -293,6 +302,12 @@
    7.89      return id;
    7.90  }
    7.91  
    7.92 +const char *
    7.93 +SDL_GetThreadName(SDL_Thread * thread)
    7.94 +{
    7.95 +    return thread->name;
    7.96 +}
    7.97 +
    7.98  int
    7.99  SDL_SetThreadPriority(SDL_ThreadPriority priority)
   7.100  {
   7.101 @@ -308,6 +323,7 @@
   7.102              *status = thread->status;
   7.103          }
   7.104          SDL_DelThread(thread);
   7.105 +        SDL_free(thread->name);
   7.106          SDL_free(thread);
   7.107      }
   7.108  }
     8.1 --- a/src/thread/SDL_thread_c.h	Tue Sep 27 23:16:04 2011 -0400
     8.2 +++ b/src/thread/SDL_thread_c.h	Sun Oct 02 00:29:16 2011 -0400
     8.3 @@ -51,6 +51,7 @@
     8.4      SYS_ThreadHandle handle;
     8.5      int status;
     8.6      SDL_error errbuf;
     8.7 +    char *name;
     8.8      void *data;
     8.9  };
    8.10  
     9.1 --- a/src/thread/beos/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
     9.2 +++ b/src/thread/beos/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
     9.3 @@ -65,8 +65,13 @@
     9.4  int
     9.5  SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
     9.6  {
     9.7 +    /* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */
     9.8 +    char name[B_OS_NAME_LENGTH];
     9.9 +    SDL_snprintf(name, sizeof (name), "%s", thread->name);
    9.10 +    name[sizeof (name) - 1] = '\0';
    9.11 +
    9.12      /* Create the thread and go! */
    9.13 -    thread->handle = spawn_thread(RunThread, "SDL", B_NORMAL_PRIORITY, args);
    9.14 +    thread->handle = spawn_thread(RunThread, name, B_NORMAL_PRIORITY, args);
    9.15      if ((thread->handle == B_NO_MORE_THREADS) ||
    9.16          (thread->handle == B_NO_MEMORY)) {
    9.17          SDL_SetError("Not enough resources to create thread");
    9.18 @@ -77,8 +82,9 @@
    9.19  }
    9.20  
    9.21  void
    9.22 -SDL_SYS_SetupThread(void)
    9.23 +SDL_SYS_SetupThread(const char *name)
    9.24  {
    9.25 +    /* We set the thread name during SDL_SYS_CreateThread(). */
    9.26      /* Mask asynchronous signals for this thread */
    9.27      SDL_MaskSignals(NULL);
    9.28  }
    10.1 --- a/src/thread/generic/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
    10.2 +++ b/src/thread/generic/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
    10.3 @@ -33,7 +33,7 @@
    10.4  }
    10.5  
    10.6  void
    10.7 -SDL_SYS_SetupThread(void)
    10.8 +SDL_SYS_SetupThread(const char *name)
    10.9  {
   10.10      return;
   10.11  }
    11.1 --- a/src/thread/irix/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
    11.2 +++ b/src/thread/irix/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
    11.3 @@ -50,7 +50,7 @@
    11.4  }
    11.5  
    11.6  void
    11.7 -SDL_SYS_SetupThread(void)
    11.8 +SDL_SYS_SetupThread(const char *name)
    11.9  {
   11.10      int i;
   11.11      sigset_t mask;
    12.1 --- a/src/thread/nds/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
    12.2 +++ b/src/thread/nds/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
    12.3 @@ -38,7 +38,7 @@
    12.4  }
    12.5  
    12.6  void
    12.7 -SDL_SYS_SetupThread(void)
    12.8 +SDL_SYS_SetupThread(const char *name)
    12.9  {
   12.10      return;
   12.11  }
    13.1 --- a/src/thread/pthread/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
    13.2 +++ b/src/thread/pthread/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
    13.3 @@ -21,6 +21,11 @@
    13.4  #include "SDL_config.h"
    13.5  
    13.6  #include <pthread.h>
    13.7 +
    13.8 +#if HAVE_PTHREAD_NP_H
    13.9 +#include <pthread_np.h>
   13.10 +#endif
   13.11 +
   13.12  #include <signal.h>
   13.13  #ifdef __LINUX__
   13.14  #include <sys/time.h>
   13.15 @@ -28,6 +33,7 @@
   13.16  #include <sys/syscall.h>
   13.17  #endif
   13.18  
   13.19 +#include "SDL_platform.h"
   13.20  #include "SDL_thread.h"
   13.21  #include "../SDL_thread_c.h"
   13.22  #include "../SDL_systhread.h"
   13.23 @@ -67,12 +73,27 @@
   13.24      return (0);
   13.25  }
   13.26  
   13.27 +/* make pthread_setname_np() a weak reference even without SDK support. */
   13.28 +#if __MACOSX__ && (MAC_OS_X_VERSION_MAX_ALLOWED < 1060)
   13.29 +int pthread_setname_np(const char*) __attribute__((weak_import,visibility("default")));
   13.30 +#elif __IPHONEOS__ && (__IPHONE_OS_VERSION_MAX_ALLOWED < 30200)
   13.31 +int pthread_setname_np(const char*) __attribute__((weak_import));
   13.32 +#endif
   13.33 +
   13.34  void
   13.35 -SDL_SYS_SetupThread(void)
   13.36 +SDL_SYS_SetupThread(const char *name)
   13.37  {
   13.38      int i;
   13.39      sigset_t mask;
   13.40  
   13.41 +#if __MACOSX__ || __IPHONEOS__
   13.42 +    if (pthread_setname_np != NULL) { pthread_setname_np(name); }
   13.43 +#elif HAVE_PTHREAD_SETNAME_NP
   13.44 +    pthread_setname_np(pthread_self(), name);
   13.45 +#elif HAVE_PTHREAD_SET_NAME_NP
   13.46 +    pthread_set_name_np(pthread_self(), name);
   13.47 +#endif
   13.48 +
   13.49      /* Mask asynchronous signals for this thread */
   13.50      sigemptyset(&mask);
   13.51      for (i = 0; sig_list[i]; ++i) {
    14.1 --- a/src/thread/windows/SDL_systhread.c	Tue Sep 27 23:16:04 2011 -0400
    14.2 +++ b/src/thread/windows/SDL_systhread.c	Sun Oct 02 00:29:16 2011 -0400
    14.3 @@ -146,10 +146,38 @@
    14.4      return (0);
    14.5  }
    14.6  
    14.7 +#ifdef _MSC_VER
    14.8 +#pragma pack(push,8)
    14.9 +typedef struct tagTHREADNAME_INFO
   14.10 +{
   14.11 +    DWORD dwType; /* must be 0x1000 */
   14.12 +    LPCSTR szName; /* pointer to name (in user addr space) */
   14.13 +    DWORD dwThreadID; /* thread ID (-1=caller thread) */
   14.14 +    DWORD dwFlags; /* reserved for future use, must be zero */
   14.15 +} THREADNAME_INFO;
   14.16 +#pragma pack(pop)
   14.17 +#endif
   14.18 +
   14.19  void
   14.20 -SDL_SYS_SetupThread(void)
   14.21 +SDL_SYS_SetupThread(const char *name)
   14.22  {
   14.23 -    return;
   14.24 +#ifdef _MSC_VER  /* !!! FIXME: can we do SEH on other compilers yet? */
   14.25 +    /* This magic tells the debugger to name a thread if it's listening. */
   14.26 +    THREADNAME_INFO inf;
   14.27 +    info.dwType = 0x1000;
   14.28 +    info.szName = name;
   14.29 +    info.dwThreadID = (DWORD) -1;
   14.30 +    info.dwFlags = 0;
   14.31 +
   14.32 +    __try
   14.33 +    {
   14.34 +        RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf);
   14.35 +    }
   14.36 +    except(EXCEPTION_CONTINUE_EXECUTION)
   14.37 +    {
   14.38 +        /* The program itself should ignore this bogus exception. */
   14.39 +    }
   14.40 +#endif
   14.41  }
   14.42  
   14.43  SDL_threadID
    15.1 --- a/src/timer/SDL_timer.c	Tue Sep 27 23:16:04 2011 -0400
    15.2 +++ b/src/timer/SDL_timer.c	Sun Oct 02 00:29:16 2011 -0400
    15.3 @@ -209,6 +209,7 @@
    15.4      SDL_TimerData *data = &SDL_timer_data;
    15.5  
    15.6      if (!data->active) {
    15.7 +        const char *name = "SDLTimer";
    15.8          data->timermap_lock = SDL_CreateMutex();
    15.9          if (!data->timermap_lock) {
   15.10              return -1;
   15.11 @@ -224,9 +225,9 @@
   15.12          /* !!! FIXME: this is nasty. */
   15.13  #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
   15.14  #undef SDL_CreateThread
   15.15 -        data->thread = SDL_CreateThread(SDL_TimerThread, data, NULL, NULL);
   15.16 +        data->thread = SDL_CreateThread(SDL_TimerThread, name, data, NULL, NULL);
   15.17  #else
   15.18 -        data->thread = SDL_CreateThread(SDL_TimerThread, data);
   15.19 +        data->thread = SDL_CreateThread(SDL_TimerThread, name, data);
   15.20  #endif
   15.21          if (!data->thread) {
   15.22              SDL_TimerQuit();
    16.1 --- a/test/testatomic.c	Tue Sep 27 23:16:04 2011 -0400
    16.2 +++ b/test/testatomic.c	Sun Oct 02 00:29:16 2011 -0400
    16.3 @@ -143,7 +143,7 @@
    16.4      SDL_AtomicSet(&threadsRunning, NThreads);
    16.5  
    16.6      while (T--)
    16.7 -        SDL_CreateThread(adder, NULL);
    16.8 +        SDL_CreateThread(adder, "Adder", NULL);
    16.9   
   16.10      while (SDL_AtomicGet(&threadsRunning) > 0)
   16.11          SDL_SemWait(threadDone);
   16.12 @@ -618,7 +618,7 @@
   16.13  #ifdef TEST_SPINLOCK_FIFO
   16.14      /* Start a monitoring thread */
   16.15      if (lock_free) {
   16.16 -        SDL_CreateThread(FIFO_Watcher, &queue);
   16.17 +        SDL_CreateThread(FIFO_Watcher, "FIFOWatcher", &queue);
   16.18      }
   16.19  #endif
   16.20  
   16.21 @@ -627,9 +627,11 @@
   16.22      SDL_zero(readerData);
   16.23      SDL_AtomicSet(&readersRunning, NUM_READERS);
   16.24      for (i = 0; i < NUM_READERS; ++i) {
   16.25 +        char name[64];
   16.26 +        SDL_snprintf(name, sizeof (name), "FIFOReader%d", i);
   16.27          readerData[i].queue = &queue;
   16.28          readerData[i].lock_free = lock_free;
   16.29 -        SDL_CreateThread(FIFO_Reader, &readerData[i]);
   16.30 +        SDL_CreateThread(FIFO_Reader, name, &readerData[i]);
   16.31      }
   16.32  
   16.33      /* Start up the writers */
   16.34 @@ -637,10 +639,12 @@
   16.35      SDL_zero(writerData);
   16.36      SDL_AtomicSet(&writersRunning, NUM_WRITERS);
   16.37      for (i = 0; i < NUM_WRITERS; ++i) {
   16.38 +        char name[64];
   16.39 +        SDL_snprintf(name, sizeof (name), "FIFOWriter%d", i);
   16.40          writerData[i].queue = &queue;
   16.41          writerData[i].index = i;
   16.42          writerData[i].lock_free = lock_free;
   16.43 -        SDL_CreateThread(FIFO_Writer, &writerData[i]);
   16.44 +        SDL_CreateThread(FIFO_Writer, name, &writerData[i]);
   16.45      }
   16.46   
   16.47      /* Wait for the writers */
    17.1 --- a/test/testerror.c	Tue Sep 27 23:16:04 2011 -0400
    17.2 +++ b/test/testerror.c	Sun Oct 02 00:29:16 2011 -0400
    17.3 @@ -58,7 +58,7 @@
    17.4      SDL_SetError("No worries");
    17.5  
    17.6      alive = 1;
    17.7 -    thread = SDL_CreateThread(ThreadFunc, "#1");
    17.8 +    thread = SDL_CreateThread(ThreadFunc, NULL, "#1");
    17.9      if (thread == NULL) {
   17.10          fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError());
   17.11          quit(1);
    18.1 --- a/test/testlock.c	Tue Sep 27 23:16:04 2011 -0400
    18.2 +++ b/test/testlock.c	Sun Oct 02 00:29:16 2011 -0400
    18.3 @@ -112,7 +112,9 @@
    18.4      printf("Main thread: %lu\n", mainthread);
    18.5      atexit(printid);
    18.6      for (i = 0; i < maxproc; ++i) {
    18.7 -        if ((threads[i] = SDL_CreateThread(Run, NULL)) == NULL)
    18.8 +        char name[64];
    18.9 +        SDL_snprintf(name, sizeof (name), "Worker%d", i);
   18.10 +        if ((threads[i] = SDL_CreateThread(Run, name, NULL)) == NULL)
   18.11              fprintf(stderr, "Couldn't create thread!\n");
   18.12      }
   18.13      signal(SIGINT, terminate);
    19.1 --- a/test/testsem.c	Tue Sep 27 23:16:04 2011 -0400
    19.2 +++ b/test/testsem.c	Sun Oct 02 00:29:16 2011 -0400
    19.3 @@ -100,7 +100,9 @@
    19.4             init_sem);
    19.5      /* Create all the threads */
    19.6      for (i = 0; i < NUM_THREADS; ++i) {
    19.7 -        threads[i] = SDL_CreateThread(ThreadFunc, (void *) i);
    19.8 +        char name[64];
    19.9 +        SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i);
   19.10 +        threads[i] = SDL_CreateThread(ThreadFunc, name, (void *) i);
   19.11      }
   19.12  
   19.13      /* Wait 10 seconds */
    20.1 --- a/test/testthread.c	Tue Sep 27 23:16:04 2011 -0400
    20.2 +++ b/test/testthread.c	Sun Oct 02 00:29:16 2011 -0400
    20.3 @@ -63,7 +63,7 @@
    20.4      }
    20.5  
    20.6      alive = 1;
    20.7 -    thread = SDL_CreateThread(ThreadFunc, "#1");
    20.8 +    thread = SDL_CreateThread(ThreadFunc, "One", "#1");
    20.9      if (thread == NULL) {
   20.10          fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError());
   20.11          quit(1);
   20.12 @@ -75,7 +75,7 @@
   20.13  
   20.14      alive = 1;
   20.15      signal(SIGTERM, killed);
   20.16 -    thread = SDL_CreateThread(ThreadFunc, "#2");
   20.17 +    thread = SDL_CreateThread(ThreadFunc, "Two", "#2");
   20.18      if (thread == NULL) {
   20.19          fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError());
   20.20          quit(1);
    21.1 --- a/test/threadwin.c	Tue Sep 27 23:16:04 2011 -0400
    21.2 +++ b/test/threadwin.c	Sun Oct 02 00:29:16 2011 -0400
    21.3 @@ -296,8 +296,8 @@
    21.4      SDL_SetEventFilter(FilterEvents, NULL);
    21.5  
    21.6      /* Create the event handling threads */
    21.7 -    mouse_thread = SDL_CreateThread(HandleMouse, NULL);
    21.8 -    keybd_thread = SDL_CreateThread(HandleKeyboard, NULL);
    21.9 +    mouse_thread = SDL_CreateThread(HandleMouse, "MouseHandler", NULL);
   21.10 +    keybd_thread = SDL_CreateThread(HandleKeyboard, "KeyboardHandler", NULL);
   21.11  
   21.12      /* Set the surface pixels and refresh! */
   21.13      for (i = 0; i < 256; ++i) {
    22.1 --- a/test/torturethread.c	Tue Sep 27 23:16:04 2011 -0400
    22.2 +++ b/test/torturethread.c	Sun Oct 02 00:29:16 2011 -0400
    22.3 @@ -52,8 +52,10 @@
    22.4      fprintf(stderr, "Creating Thread %d\n", tid);
    22.5  
    22.6      for (i = 0; i < NUMTHREADS; i++) {
    22.7 +        char name[64];
    22.8 +        SDL_snprintf(name, sizeof (name), "Child%d_%d", tid, i);
    22.9          flags[i] = 0;
   22.10 -        sub_threads[i] = SDL_CreateThread(SubThreadFunc, &flags[i]);
   22.11 +        sub_threads[i] = SDL_CreateThread(SubThreadFunc, name, &flags[i]);
   22.12      }
   22.13  
   22.14      printf("Thread '%d' waiting for signal\n", tid);
   22.15 @@ -86,8 +88,10 @@
   22.16  
   22.17      signal(SIGSEGV, SIG_DFL);
   22.18      for (i = 0; i < NUMTHREADS; i++) {
   22.19 +        char name[64];
   22.20 +        SDL_snprintf(name, sizeof (name), "Parent%d", i);
   22.21          time_for_threads_to_die[i] = 0;
   22.22 -        threads[i] = SDL_CreateThread(ThreadFunc, (void *) (uintptr_t) i);
   22.23 +        threads[i] = SDL_CreateThread(ThreadFunc, name, (void*) (uintptr_t) i);
   22.24  
   22.25          if (threads[i] == NULL) {
   22.26              fprintf(stderr, "Couldn't create thread: %s\n", SDL_GetError());