
#9684: Broken build on OS X (incompatible pthread_setname_np API) -------------------------------------+------------------------------------- Reporter: mlen | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.9 Keywords: | Operating System: MacOS X pthread_setname_np | Type of failure: Building Architecture: Unknown/Multiple | GHC failed Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: | 674c631ea111233daa929ef63500d75ba0db8858 -------------------------------------+------------------------------------- Build is broken on OS X because it is only possible to set thread name for the current thread and `pthread_setname_np` accepts a single argument. This function appeared in 10.6. If that OS version needs to be supported, the best thing that can be done is conditional compilation. A short summary of inconsistencies between different *nix systems can be found here: http://stackoverflow.com/questions/2369738/can-i-set-the-name-of-a -thread-in-pthreads-linux/7989973#7989973 The error log: {{{ rts/posix/OSThreads.c:138:30: error: too many arguments to function call, expected 1, have 2 pthread_setname_np(*pId, name); ~~~~~~~~~~~~~~~~~~ ^~~~ /usr/include/pthread.h:471:1: note: 'pthread_setname_np' declared here __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2) ^ /usr/include/Availability.h:159:50: note: expanded from macro '__OSX_AVAILABLE_STARTING' #define __OSX_AVAILABLE_STARTING(_osx, _ios) __AVAILABILITY_INTERNAL##_osx ^ <scratch space>:65:1: note: expanded from here __AVAILABILITY_INTERNAL__MAC_10_6 ^ /usr/include/AvailabilityInternal.h:3912:72: note: expanded from macro '__AVAILABILITY_INTERNAL__MAC_10_6' #define __AVAILABILITY_INTERNAL__MAC_10_6 __attribute__((availability(macosx,introduced=10.6))) ^ 1 error generated. }}} I can see two possible solutions for OS X: 1. disable setting thread name by conditional compilation. 2. write some trampoline code to work around the fact that it is only possible to set thread name for the current thread. The latter would look like this: {{{ struct wrapper { char *name; void *param; void *(*cont)(void *); }; void *trampoline(void *ctx) { struct wrapper *params = (struct wrapper *)ctx; void *param = params->param; void *(*cont)(void *) = params->cont; #ifdef MACOSX pthread_setname_np(params->name); #elif pthread_setname_np(pthread_self(), params->name); #endif free(params); return cont(param); } int createOSThread (OSThreadId* pId, char *name, OSThreadProc *startProc, void *param) { struct wrapper *ctx = malloc(sizeof(struct wrapper)); ctx->name = name; ctx->cont = startProc; ctx->param = param; int result = pthread_create(pId, NULL, (void *(*)(void *))trampoline, &ctx); if (!result) { pthread_detach(*pId); } else { free(ctx); } return result; } }}} It looks very hackish and I think it'd be better to go with (1), since the original change was made for debugging purposes. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9684 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler