From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/5991 Path: news.gmane.org!not-for-mail From: Jens Gustedt Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH 7/8] add the thrd_xxxxxx functions Date: Sat, 30 Aug 2014 20:47:32 +0200 Message-ID: <22215ff2f880382340930f78cc746565a625a806.1409423162.git.Jens.Gustedt@inria.fr> References: Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1409424454 6282 80.91.229.3 (30 Aug 2014 18:47:34 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 30 Aug 2014 18:47:34 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-5998-gllmg-musl=m.gmane.org@lists.openwall.com Sat Aug 30 20:47:28 2014 Return-path: Envelope-to: gllmg-musl@plane.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1XNngM-0000nr-RD for gllmg-musl@plane.gmane.org; Sat, 30 Aug 2014 20:47:26 +0200 Original-Received: (qmail 5929 invoked by uid 550); 30 Aug 2014 18:47:24 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 5921 invoked from network); 30 Aug 2014 18:47:24 -0000 X-IronPort-AV: E=Sophos;i="5.04,432,1406584800"; d="scan'208";a="92267862" In-Reply-To: Resent-From: Jens Gustedt Resent-To: musl@lists.openwall.com X-Mailer: Evolution 3.4.4-3 Xref: news.gmane.org gmane.linux.lib.musl.general:5991 Archived-At: The major difficulty with C threads versus pthread is that the thread start functions have different signatures. Basing the C threads implementation on pthreads therefore needs to do some ugly cast with function pointers and function results. We try to be the least intrusive for the existing pthreads implementation, to make sure we don't break anything and also to ease maintenance and simultaneous improvement of the code base later on. --- src/sched/thrd_yield.c | 7 +++++++ src/thread/pthread_create.c | 41 ++++++++++++++++++++++++++++++++++++++--- src/thread/thrd_current.c | 11 +++++++++++ src/thread/thrd_detach.c | 12 ++++++++++++ src/thread/thrd_equal.c | 6 ++++++ src/thread/thrd_join.c | 16 ++++++++++++++++ 6 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 src/sched/thrd_yield.c create mode 100644 src/thread/thrd_current.c create mode 100644 src/thread/thrd_detach.c create mode 100644 src/thread/thrd_equal.c create mode 100644 src/thread/thrd_join.c diff --git a/src/sched/thrd_yield.c b/src/sched/thrd_yield.c new file mode 100644 index 0000000..301e953 --- /dev/null +++ b/src/sched/thrd_yield.c @@ -0,0 +1,7 @@ +#include +#include "syscall.h" + +void thrd_yield() +{ + (void)syscall(SYS_sched_yield); +} diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index ed265fb..3212502 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -4,11 +4,14 @@ #include "libc.h" #include #include +#include void *__mmap(void *, size_t, int, int, int, off_t); int __munmap(void *, size_t); int __mprotect(void *, size_t, int); +#define __THRD_C11 ((void*)(uintptr_t)-1) + static void dummy_0() { } @@ -123,6 +126,19 @@ static int start(void *p) return 0; } +static _Noreturn void __thrd_exit(int result) { + __pthread_exit((void*)(intptr_t)result); +} + + +static int start_c11(void *p) +{ + thrd_t self = p; + int (*start)(void*) = (int(*)(void*)) self->start; + __thrd_exit(start(self->start_arg)); + return 0; +} + #define ROUND(x) (((x)+PAGE_SIZE-1)&-PAGE_SIZE) /* pthread_key_create.c overrides this */ @@ -145,8 +161,8 @@ void *__copy_tls(unsigned char *); static int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp, void *(*entry)(void *), void *restrict arg) { - int ret; - size_t size, guard; + int ret, c11 = (attrp == __THRD_C11); + size_t size, guard = 0; struct pthread *self, *new; unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit; unsigned flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND @@ -167,6 +183,9 @@ static int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restr self->tsd = (void **)__pthread_tsd_main; libc.threaded = 1; } + if (c11) { + attrp = 0; + } if (attrp) attr = *attrp; __acquire_ptc(); @@ -234,7 +253,10 @@ static int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restr new->canary = self->canary; a_inc(&libc.threads_minus_1); - ret = __clone(start, stack, flags, new, &new->tid, TP_ADJ(new), &new->tid); + if (c11) + ret = __clone(start_c11, stack, flags, new, &new->tid, TP_ADJ(new), &new->tid); + else + ret = __clone(start, stack, flags, new, &new->tid, TP_ADJ(new), &new->tid); __release_ptc(); @@ -263,5 +285,18 @@ fail: return EAGAIN; } +static int __thrd_create(thrd_t *thr, + thrd_start_t func, + void *arg) { + /* In the best of all worlds this is a tail call. */ + int ret = __pthread_create(thr, __THRD_C11, (void * (*)(void *))func, arg); + if (thrd_success) + return ret ? thrd_error : thrd_success; + /* In case of UB may also return ENOSYS or EAGAIN. */ + return ret; +} + weak_alias(__pthread_exit, pthread_exit); weak_alias(__pthread_create, pthread_create); +weak_alias(__thrd_create, thrd_create); +weak_alias(__thrd_exit, thrd_exit); diff --git a/src/thread/thrd_current.c b/src/thread/thrd_current.c new file mode 100644 index 0000000..1728535 --- /dev/null +++ b/src/thread/thrd_current.c @@ -0,0 +1,11 @@ +#include "pthread_impl.h" +#include + +/* Not all arch have __pthread_self as a symbol. On some this results + in some magic. So this "call" to __pthread_self is not necessary a + tail call. In particular, other than the appearance, thrd_current + can not be implemented as a weak symbol. */ +pthread_t thrd_current() +{ + return __pthread_self(); +} diff --git a/src/thread/thrd_detach.c b/src/thread/thrd_detach.c new file mode 100644 index 0000000..72cdfba --- /dev/null +++ b/src/thread/thrd_detach.c @@ -0,0 +1,12 @@ +#include + +int __pthread_detach(thrd_t t); + +int thrd_detach(thrd_t t) +{ + /* In the best of all worlds this is a tail call. */ + int ret = __pthread_detach(t); + if (thrd_success) + return ret ? thrd_error : thrd_success; + return ret; +} diff --git a/src/thread/thrd_equal.c b/src/thread/thrd_equal.c new file mode 100644 index 0000000..ac49a44 --- /dev/null +++ b/src/thread/thrd_equal.c @@ -0,0 +1,6 @@ +#include + +int (thrd_equal)(thrd_t a, thrd_t b) +{ + return a==b; +} diff --git a/src/thread/thrd_join.c b/src/thread/thrd_join.c new file mode 100644 index 0000000..a8c7aed --- /dev/null +++ b/src/thread/thrd_join.c @@ -0,0 +1,16 @@ +#include "pthread_impl.h" +#include +#include + +int __munmap(void *, size_t); + +/* C11 threads cannot be canceled, so there is no need for a + cancelation function pointer, here. */ +int thrd_join(thrd_t t, int *res) +{ + int tmp; + while ((tmp = t->tid)) __timedwait(&t->tid, tmp, 0, 0, 0, 0, 0); + if (res) *res = (int)(intptr_t)t->result; + if (t->map_base) __munmap(t->map_base, t->map_size); + return thrd_success; +} -- 1.7.10.4