summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rts/posix/OSThreads.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/rts/posix/OSThreads.c b/rts/posix/OSThreads.c
index 20064910ad..3d3fe98611 100644
--- a/rts/posix/OSThreads.c
+++ b/rts/posix/OSThreads.c
@@ -186,22 +186,48 @@ shutdownThread(void)
pthread_exit(NULL);
}
-int
-createOSThread (OSThreadId* pId, char *name STG_UNUSED,
- OSThreadProc *startProc, void *param)
+struct ThreadDesc {
+ OSThreadProc *startProc;
+ void *param;
+ char *name;
+};
+
+// N.B. Darwin's pthread_setname_np only allows the name of the
+// calling thread to be set. Consequently we must use this
+// trampoline.
+static void *
+start_thread (void *param)
{
- int result = pthread_create(pId, NULL, startProc, param);
- if (!result) {
- pthread_detach(*pId);
+ struct ThreadDesc desc = *(struct ThreadDesc *) param;
+ stgFree(param);
+
#if defined(HAVE_PTHREAD_SET_NAME_NP)
- pthread_set_name_np(*pId, name);
+ pthread_set_name_np(pthread_self(), desc.name);
#elif defined(HAVE_PTHREAD_SETNAME_NP)
- pthread_setname_np(*pId, name);
+ pthread_setname_np(pthread_self(), desc.name);
#elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN)
- pthread_setname_np(name);
+ pthread_setname_np(desc.name);
#elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD)
- pthread_setname_np(*pId, "%s", name);
+ pthread_setname_np(pthread_self(), "%s", desc.name);
#endif
+
+ return desc.startProc(desc.param);
+}
+
+int
+createOSThread (OSThreadId* pId, char *name STG_UNUSED,
+ OSThreadProc *startProc, void *param)
+{
+ struct ThreadDesc *desc = stgMallocBytes(sizeof(struct ThreadDesc), "createOSThread");
+ desc->startProc = startProc;
+ desc->param = param;
+ desc->name = name;
+
+ int result = pthread_create(pId, NULL, start_thread, desc);
+ if (!result) {
+ pthread_detach(*pId);
+ } else {
+ stgFree(desc);
}
return result;
}