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 |