mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Jens Gustedt <Jens.Gustedt@inria.fr>
To: musl@lists.openwall.com
Subject: [PATCH 7/8] add the thrd_xxxxxx functions
Date: Sat, 30 Aug 2014 20:47:32 +0200	[thread overview]
Message-ID: <22215ff2f880382340930f78cc746565a625a806.1409423162.git.Jens.Gustedt@inria.fr> (raw)
In-Reply-To: <cover.1409423162.git.Jens.Gustedt@inria.fr>

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 <sched.h>
+#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 <sys/mman.h>
 #include <string.h>
+#include <threads.h>
 
 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 <threads.h>
+
+/* 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 <threads.h>
+
+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 <threads.h>
+
+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 <sys/mman.h>
+#include <threads.h>
+
+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



  parent reply	other threads:[~2014-08-30 18:47 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-30 18:46 [PATCH 0/8] C thread patch series, v. 8.3 and 9.4 Jens Gustedt
2014-08-30 18:46 ` [PATCH 1/8] interface additions for the C thread implementation Jens Gustedt
2014-08-30 18:46 ` [PATCH 2/8] additions to src/time Jens Gustedt
2014-08-31  0:13   ` Rich Felker
2014-08-31  7:15     ` Jens Gustedt
2014-08-31 12:45       ` Rich Felker
2014-08-30 18:46 ` [PATCH 3/8] use weak symbols for the POSIX functions that will be used by C threads Jens Gustedt
2014-08-31  0:17   ` Rich Felker
2014-08-31  7:18     ` Jens Gustedt
2014-08-30 18:47 ` [PATCH 4/8] add the functions for tss_t and once_flag Jens Gustedt
2014-08-30 18:47 ` [PATCH 5/8] add the functions for mtx_t Jens Gustedt
2014-08-30 18:47 ` [PATCH 6/8] add the functions for cnd_t Jens Gustedt
2014-08-31  0:35   ` Rich Felker
2014-08-31  7:26     ` Jens Gustedt
2014-08-30 18:47 ` Jens Gustedt [this message]
2014-08-31  0:46   ` [PATCH 7/8] add the thrd_xxxxxx functions Rich Felker
2014-08-31  7:57     ` Jens Gustedt
2014-08-31  9:51       ` Alexander Monakov
2014-08-31 10:50         ` Jens Gustedt
2014-08-31 11:06           ` Alexander Monakov
2014-08-31 11:31             ` Szabolcs Nagy
2014-08-31 12:57       ` Rich Felker
2014-08-31 13:19         ` Jens Gustedt
2014-08-31 14:05           ` Rich Felker
2014-08-31 15:07             ` Jens Gustedt
2014-08-31 16:06               ` Rich Felker
2014-08-31 16:36                 ` Jens Gustedt
2014-08-31 17:02                   ` Rich Felker
2014-08-31 19:10                     ` Jens Gustedt
2014-09-01  0:04                       ` Rich Felker
2014-08-30 18:47 ` [PATCH 8/8] Separate pthread_create and thrd_create Jens Gustedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=22215ff2f880382340930f78cc746565a625a806.1409423162.git.Jens.Gustedt@inria.fr \
    --to=jens.gustedt@inria.fr \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).