Broken build on OS X (incompatible pthread_setname_np API)
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:
- disable setting thread name by conditional compilation.
- 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.
Trac metadata
Trac field | Value |
---|---|
Version | 7.9 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | hvr, simonmar |
Operating system | |
Architecture |