diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/internal/pthread_impl.h | 2 | ||||
| -rw-r--r-- | src/thread/pthread_create.c | 16 | ||||
| -rw-r--r-- | src/thread/pthread_detach.c | 4 | ||||
| -rw-r--r-- | src/thread/pthread_equal.c | 7 | ||||
| -rw-r--r-- | src/thread/pthread_self.c | 7 | ||||
| -rw-r--r-- | src/thread/thrd_create.c | 14 | ||||
| -rw-r--r-- | src/thread/thrd_exit.c | 9 | ||||
| -rw-r--r-- | src/thread/thrd_join.c | 12 | ||||
| -rw-r--r-- | src/thread/thrd_sleep.c | 13 | ||||
| -rw-r--r-- | src/thread/thrd_yield.c | 7 | 
10 files changed, 84 insertions, 7 deletions
| diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index 74c62cce..ae6e60b5 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -128,4 +128,6 @@ void __restore_sigs(void *);  #define DEFAULT_STACK_SIZE 81920  #define DEFAULT_GUARD_SIZE PAGE_SIZE +#define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1) +  #endif 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(); diff --git a/src/thread/pthread_detach.c b/src/thread/pthread_detach.c index 4e454634..ed77f74d 100644 --- a/src/thread/pthread_detach.c +++ b/src/thread/pthread_detach.c @@ -1,8 +1,9 @@  #include "pthread_impl.h" +#include <threads.h>  int __pthread_join(pthread_t, void **); -int __pthread_detach(pthread_t t) +static int __pthread_detach(pthread_t t)  {  	/* Cannot detach a thread that's already exiting */  	if (a_swap(t->exitlock, 1)) @@ -13,3 +14,4 @@ int __pthread_detach(pthread_t t)  }  weak_alias(__pthread_detach, pthread_detach); +weak_alias(__pthread_detach, thrd_detach); diff --git a/src/thread/pthread_equal.c b/src/thread/pthread_equal.c index 3e3df4fd..7c31482a 100644 --- a/src/thread/pthread_equal.c +++ b/src/thread/pthread_equal.c @@ -1,6 +1,11 @@  #include <pthread.h> +#include <threads.h> +#include "libc.h" -int (pthread_equal)(pthread_t a, pthread_t b) +static int __pthread_equal(pthread_t a, pthread_t b)  {  	return a==b;  } + +weak_alias(__pthread_equal, pthread_equal); +weak_alias(__pthread_equal, thrd_equal); diff --git a/src/thread/pthread_self.c b/src/thread/pthread_self.c index 5f9e6516..241a6202 100644 --- a/src/thread/pthread_self.c +++ b/src/thread/pthread_self.c @@ -1,6 +1,11 @@  #include "pthread_impl.h" +#include <threads.h> +#include "libc.h" -pthread_t pthread_self() +static pthread_t __pthread_self_internal()  {  	return __pthread_self();  } + +weak_alias(__pthread_self_internal, pthread_self); +weak_alias(__pthread_self_internal, thrd_current); diff --git a/src/thread/thrd_create.c b/src/thread/thrd_create.c new file mode 100644 index 00000000..e0336695 --- /dev/null +++ b/src/thread/thrd_create.c @@ -0,0 +1,14 @@ +#include "pthread_impl.h" +#include <threads.h> + +int __pthread_create(pthread_t *restrict, const pthread_attr_t *restrict, void *(*)(void *), void *restrict); + +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) +{ +	int ret = __pthread_create(thr, __ATTRP_C11_THREAD, (void *(*)(void *))func, arg); +	switch (ret) { +	case 0:      return thrd_success; +	case EAGAIN: return thrd_nomem; +	default:     return thrd_error; +	} +} diff --git a/src/thread/thrd_exit.c b/src/thread/thrd_exit.c new file mode 100644 index 00000000..b66bd996 --- /dev/null +++ b/src/thread/thrd_exit.c @@ -0,0 +1,9 @@ +#include "pthread_impl.h" +#include <threads.h> + +_Noreturn void __pthread_exit(void *); + +_Noreturn void thrd_exit(int result) +{ +	__pthread_exit((void*)(intptr_t)result); +} diff --git a/src/thread/thrd_join.c b/src/thread/thrd_join.c new file mode 100644 index 00000000..ac667893 --- /dev/null +++ b/src/thread/thrd_join.c @@ -0,0 +1,12 @@ +#include <stdint.h> +#include <threads.h> + +int __pthread_join(thrd_t, void**); + +int thrd_join(thrd_t t, int *res) +{ +        void *pthread_res; +        __pthread_join(t, &pthread_res); +        if (res) *res = (int)(intptr_t)pthread_res; +        return thrd_success; +} diff --git a/src/thread/thrd_sleep.c b/src/thread/thrd_sleep.c new file mode 100644 index 00000000..e8dfe400 --- /dev/null +++ b/src/thread/thrd_sleep.c @@ -0,0 +1,13 @@ +#include <threads.h> +#include <errno.h> +#include "syscall.h" + +int thrd_sleep(const struct timespec *req, struct timespec *rem) +{ +	int ret = __syscall(SYS_nanosleep, req, rem); +	switch (ret) { +	case 0:      return 0; +	case -EINTR: return -1; /* value specified by C11 */ +	default:     return -2; +	} +} diff --git a/src/thread/thrd_yield.c b/src/thread/thrd_yield.c new file mode 100644 index 00000000..f7ad1321 --- /dev/null +++ b/src/thread/thrd_yield.c @@ -0,0 +1,7 @@ +#include <threads.h> +#include "syscall.h" + +void thrd_yield() +{ +	__syscall(SYS_sched_yield); +} | 
