summaryrefslogtreecommitdiff
path: root/src/thread/pthread_create.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-09-07 10:28:08 -0400
committerRich Felker <dalias@aerifal.cx>2014-09-07 10:28:08 -0400
commit23614b0fcb4cd4d7b2e4148d3b1887b642169765 (patch)
treeffee3db90209dedcc61b1afdd255be2af2d39b8a /src/thread/pthread_create.c
parent14397cec2c8429b504b17aaf92509b48da3681b9 (diff)
downloadmusl-23614b0fcb4cd4d7b2e4148d3b1887b642169765.tar.gz
add C11 thread creation and related thread functions
based on patch by Jens Gustedt. the main difficulty here is handling the difference between start function signatures and thread return types for C11 threads versus POSIX threads. pointers to void are assumed to be able to represent faithfully all values of int. the function pointer for the thread start function is cast to an incorrect type for passing through pthread_create, but is cast back to its correct type before calling so that the behavior of the call is well-defined. changes to the existing threads implementation were kept minimal to reduce the risk of regressions, and duplication of code that carries implementation-specific assumptions was avoided for ease and safety of future maintenance.
Diffstat (limited to 'src/thread/pthread_create.c')
-rw-r--r--src/thread/pthread_create.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
index c170a999..1a47ed15 100644
--- a/src/thread/pthread_create.c
+++ b/src/thread/pthread_create.c
@@ -119,7 +119,15 @@ static int start(void *p)
if (self->unblock_cancel)
__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
SIGPT_SET, 0, _NSIG/8);
- pthread_exit(self->start(self->start_arg));
+ __pthread_exit(self->start(self->start_arg));
+ return 0;
+}
+
+static int start_c11(void *p)
+{
+ pthread_t self = p;
+ int (*start)(void*) = (int(*)(void*)) self->start;
+ __pthread_exit((void *)(uintptr_t)start(self->start_arg));
return 0;
}
@@ -145,7 +153,7 @@ void *__copy_tls(unsigned char *);
int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp, void *(*entry)(void *), void *restrict arg)
{
- int ret;
+ int ret, c11 = (attrp == __ATTRP_C11_THREAD);
size_t size, guard;
struct pthread *self, *new;
unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit;
@@ -167,7 +175,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
self->tsd = (void **)__pthread_tsd_main;
libc.threaded = 1;
}
- if (attrp) attr = *attrp;
+ if (attrp && !c11) attr = *attrp;
__acquire_ptc();
@@ -234,7 +242,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
new->canary = self->canary;
a_inc(&libc.threads_minus_1);
- ret = __clone(start, stack, flags, new, &new->tid, TP_ADJ(new), &new->tid);
+ ret = __clone((c11 ? start_c11 : start), stack, flags, new, &new->tid, TP_ADJ(new), &new->tid);
__release_ptc();