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 1/9] interface additions for the C thread implementation
Date: Mon, 01 Sep 2014 00:45:47 +0200	[thread overview]
Message-ID: <cb03e88ca7f717c106c0aa7283202fd2f7c7f327.1409524413.git.Jens.Gustedt@inria.fr> (raw)
In-Reply-To: <cover.1409524413.git.Jens.Gustedt@inria.fr>

This adds all the constant, type and function interfaces.

It makes pthread_mutex_t, mtx_t, pthread_cond_t and cnd_t different
types.

This only works because

 - under hood the corresponding pairs of types use exactly the same
   definition for the type

 - the types are a struct types without tag name

 - no comparison or assignment is allowed for any of these types. For
   the POSIX types this interdiction is written in the standard. For the
   C thread types, this is an extension that this implementation
   imposes, but which might be integrated in a later version of the C
   standard.

 - initialization is default initialization of an array of int. For the
   POSIX types, initialization expressions are provided. For C thread
   types the only initialization foreseen by the standard are the init
   functions.

 - any calls to standard functions use pointers, and because pointer
   representations for struct types are the same.

For the C++ API/ABI, these also are different types, now, with type names
(that are used for name mangling, e.g) as listed above.

Somebody better versed in C++ could perhaps contribute code that
overloads the comparison and assignment operators such that a compilation
that tries to compare or copy these types fails.
---
 arch/arm/bits/alltypes.h.in        |   10 +++-
 arch/i386/bits/alltypes.h.in       |   10 +++-
 arch/microblaze/bits/alltypes.h.in |   10 +++-
 arch/mips/bits/alltypes.h.in       |   10 +++-
 arch/or1k/bits/alltypes.h.in       |   10 +++-
 arch/powerpc/bits/alltypes.h.in    |   10 +++-
 arch/sh/bits/alltypes.h.in         |   10 +++-
 arch/x32/bits/alltypes.h.in        |   10 +++-
 arch/x86_64/bits/alltypes.h.in     |   10 +++-
 include/alltypes.h.in              |   10 ++++
 include/threads.h                  |  110 ++++++++++++++++++++++++++++++++++++
 include/time.h                     |   11 ++++
 12 files changed, 212 insertions(+), 9 deletions(-)
 create mode 100644 include/threads.h

diff --git a/arch/arm/bits/alltypes.h.in b/arch/arm/bits/alltypes.h.in
index 183c4c4..1dcb920 100644
--- a/arch/arm/bits/alltypes.h.in
+++ b/arch/arm/bits/alltypes.h.in
@@ -18,8 +18,16 @@ TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
 TYPEDEF long time_t;
 TYPEDEF long suseconds_t;
 
-TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync.
+ *
+ * Also this only works because the underlying struct has no struct
+ * tag. Don't introduce one. */
 TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
 TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } cnd_t;
+
+TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[8]; void *__p[8]; } __u; } pthread_rwlock_t;
 TYPEDEF struct { union { int __i[5]; void *__p[5]; } __u; } pthread_barrier_t;
diff --git a/arch/i386/bits/alltypes.h.in b/arch/i386/bits/alltypes.h.in
index 8ba8f6f..6fe9d05 100644
--- a/arch/i386/bits/alltypes.h.in
+++ b/arch/i386/bits/alltypes.h.in
@@ -32,8 +32,16 @@ TYPEDEF struct { _Alignas(8) long long __ll; long double __ld; } max_align_t;
 TYPEDEF long time_t;
 TYPEDEF long suseconds_t;
 
-TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync.
+ *
+ * Also this only works because the underlying struct has no struct
+ * tag. Don't introduce one. */
 TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
 TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } cnd_t;
+
+TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[8]; void *__p[8]; } __u; } pthread_rwlock_t;
 TYPEDEF struct { union { int __i[5]; void *__p[5]; } __u; } pthread_barrier_t;
diff --git a/arch/microblaze/bits/alltypes.h.in b/arch/microblaze/bits/alltypes.h.in
index a03e1b8..ad4d898 100644
--- a/arch/microblaze/bits/alltypes.h.in
+++ b/arch/microblaze/bits/alltypes.h.in
@@ -18,8 +18,16 @@ TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
 TYPEDEF long time_t;
 TYPEDEF long suseconds_t;
 
-TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync.
+ *
+ * Also this only works because the underlying struct has no struct
+ * tag. Don't introduce one. */
 TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
 TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } cnd_t;
+
+TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[8]; void *__p[8]; } __u; } pthread_rwlock_t;
 TYPEDEF struct { union { int __i[5]; void *__p[5]; } __u; } pthread_barrier_t;
diff --git a/arch/mips/bits/alltypes.h.in b/arch/mips/bits/alltypes.h.in
index a03e1b8..ad4d898 100644
--- a/arch/mips/bits/alltypes.h.in
+++ b/arch/mips/bits/alltypes.h.in
@@ -18,8 +18,16 @@ TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
 TYPEDEF long time_t;
 TYPEDEF long suseconds_t;
 
-TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync.
+ *
+ * Also this only works because the underlying struct has no struct
+ * tag. Don't introduce one. */
 TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
 TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } cnd_t;
+
+TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[8]; void *__p[8]; } __u; } pthread_rwlock_t;
 TYPEDEF struct { union { int __i[5]; void *__p[5]; } __u; } pthread_barrier_t;
diff --git a/arch/or1k/bits/alltypes.h.in b/arch/or1k/bits/alltypes.h.in
index 183c4c4..1dcb920 100644
--- a/arch/or1k/bits/alltypes.h.in
+++ b/arch/or1k/bits/alltypes.h.in
@@ -18,8 +18,16 @@ TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
 TYPEDEF long time_t;
 TYPEDEF long suseconds_t;
 
-TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync.
+ *
+ * Also this only works because the underlying struct has no struct
+ * tag. Don't introduce one. */
 TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
 TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } cnd_t;
+
+TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[8]; void *__p[8]; } __u; } pthread_rwlock_t;
 TYPEDEF struct { union { int __i[5]; void *__p[5]; } __u; } pthread_barrier_t;
diff --git a/arch/powerpc/bits/alltypes.h.in b/arch/powerpc/bits/alltypes.h.in
index ee7f137..63f88ca 100644
--- a/arch/powerpc/bits/alltypes.h.in
+++ b/arch/powerpc/bits/alltypes.h.in
@@ -18,8 +18,16 @@ TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
 TYPEDEF long time_t;
 TYPEDEF long suseconds_t;
 
-TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync.
+ *
+ * Also this only works because the underlying struct has no struct
+ * tag. Don't introduce one. */
 TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
 TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } cnd_t;
+
+TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[8]; void *__p[8]; } __u; } pthread_rwlock_t;
 TYPEDEF struct { union { int __i[5]; void *__p[5]; } __u; } pthread_barrier_t;
diff --git a/arch/sh/bits/alltypes.h.in b/arch/sh/bits/alltypes.h.in
index ee7f137..63f88ca 100644
--- a/arch/sh/bits/alltypes.h.in
+++ b/arch/sh/bits/alltypes.h.in
@@ -18,8 +18,16 @@ TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
 TYPEDEF long time_t;
 TYPEDEF long suseconds_t;
 
-TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync.
+ *
+ * Also this only works because the underlying struct has no struct
+ * tag. Don't introduce one. */
 TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
 TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; void *__p[12]; } __u; } cnd_t;
+
+TYPEDEF struct { union { int __i[9]; unsigned __s[9]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[8]; void *__p[8]; } __u; } pthread_rwlock_t;
 TYPEDEF struct { union { int __i[5]; void *__p[5]; } __u; } pthread_barrier_t;
diff --git a/arch/x32/bits/alltypes.h.in b/arch/x32/bits/alltypes.h.in
index 8e396c9..3e8f086 100644
--- a/arch/x32/bits/alltypes.h.in
+++ b/arch/x32/bits/alltypes.h.in
@@ -23,8 +23,16 @@ TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
 TYPEDEF long long time_t;
 TYPEDEF long long suseconds_t;
 
-TYPEDEF struct { union { int __i[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync.
+ *
+ * Also this only works because the underlying struct has no struct
+ * tag. Don't introduce one. */
 TYPEDEF struct { union { int __i[10]; volatile void *volatile __p[5]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[10]; volatile void *volatile __p[5]; } __u; } mtx_t;
 TYPEDEF struct { union { int __i[12]; void *__p[6]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; void *__p[6]; } __u; } cnd_t;
+
+TYPEDEF struct { union { int __i[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[14]; void *__p[7]; } __u; } pthread_rwlock_t;
 TYPEDEF struct { union { int __i[8]; void *__p[4]; } __u; } pthread_barrier_t;
diff --git a/arch/x86_64/bits/alltypes.h.in b/arch/x86_64/bits/alltypes.h.in
index 7b4f3e7..c0169c7 100644
--- a/arch/x86_64/bits/alltypes.h.in
+++ b/arch/x86_64/bits/alltypes.h.in
@@ -23,8 +23,16 @@ TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
 TYPEDEF long time_t;
 TYPEDEF long suseconds_t;
 
-TYPEDEF struct { union { int __i[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync.
+ *
+ * Also this only works because the underlying struct has no struct
+ * tag. Don't introduce one. */
 TYPEDEF struct { union { int __i[10]; volatile void *volatile __p[5]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[10]; volatile void *volatile __p[5]; } __u; } mtx_t;
 TYPEDEF struct { union { int __i[12]; void *__p[6]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; void *__p[6]; } __u; } cnd_t;
+
+TYPEDEF struct { union { int __i[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[14]; void *__p[7]; } __u; } pthread_rwlock_t;
 TYPEDEF struct { union { int __i[8]; void *__p[4]; } __u; } pthread_barrier_t;
diff --git a/include/alltypes.h.in b/include/alltypes.h.in
index c4ca5d5..94364e8 100644
--- a/include/alltypes.h.in
+++ b/include/alltypes.h.in
@@ -43,13 +43,23 @@ TYPEDEF unsigned gid_t;
 TYPEDEF int key_t;
 TYPEDEF unsigned useconds_t;
 
+/* The pairs of equivalent definitions for pthread and C thread types
+ * should always be kept in sync. */
 #ifdef __cplusplus
 TYPEDEF unsigned long pthread_t;
+TYPEDEF unsigned long thrd_t;
 #else
 TYPEDEF struct __pthread * pthread_t;
+TYPEDEF struct __pthread * thrd_t;
 #endif
 TYPEDEF int pthread_once_t;
+TYPEDEF int once_flag;
 TYPEDEF unsigned pthread_key_t;
+TYPEDEF unsigned tss_t;
+
+TYPEDEF pthread_cond_t cnd_t;
+TYPEDEF pthread_mutex_t mtx_t;
+
 TYPEDEF int pthread_spinlock_t;
 TYPEDEF struct { unsigned __attr; } pthread_mutexattr_t;
 TYPEDEF struct { unsigned __attr; } pthread_condattr_t;
diff --git a/include/threads.h b/include/threads.h
new file mode 100644
index 0000000..0e99443
--- /dev/null
+++ b/include/threads.h
@@ -0,0 +1,110 @@
+#ifndef _THREADS_H
+#define _THREADS_H
+
+/* This one is explicitly allowed to be included. */
+#include <time.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These may or may not be implemented to be the same as some POSIX
+ * types. Don't rely on any assumption about that, in particular if
+ * you happen to use both interfaces in the same code. */
+
+#define __NEED_cnd_t
+#define __NEED_mtx_t
+#define __NEED_once_flag
+#define __NEED_thrd_t
+#define __NEED_tss_t
+
+#include <bits/alltypes.h>
+
+typedef int (*thrd_start_t)(void*);
+typedef void (*tss_dtor_t)(void*);
+
+/* This should be a keyword for C++11 */
+#ifndef __cplusplus
+# define thread_local _Thread_local
+#endif
+
+  /* The following list of 10 integer constants makes up for the binary
+     compatibility of this C thread implementation. You must never
+     link code against versions of the C library that do not agree
+     upon these ABI parameters.
+
+     Additionally this implementation assumes that the 5 types have
+     the same size across C libraries and that these types can be
+     initialized by the default initializer.
+
+     The values for the 10 parameters are those that we proposed to
+     glibc, in the hope that they will agree.
+  */
+
+#define TSS_DTOR_ITERATIONS 4
+
+enum {
+  thrd_success  = 0,
+  thrd_busy     = 1,
+  thrd_error    = 2,
+  thrd_nomem    = 3,
+  thrd_timedout = 4,
+};
+
+enum {
+  mtx_plain     = 0,
+  mtx_recursive = 1,
+  // all mutexes are timed, here. so this is a no-op
+  mtx_timed     = 2,
+};
+
+#define ONCE_FLAG_INIT { 0 }
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int thrd_create(thrd_t *, thrd_start_t, void *);
+_Noreturn void thrd_exit(int);
+
+int thrd_detach(thrd_t);
+int thrd_join(thrd_t, int *);
+
+int thrd_sleep(const struct timespec *, struct timespec *);
+void thrd_yield(void);
+
+thrd_t thrd_current(void);
+int thrd_equal(thrd_t, thrd_t);
+#define thrd_equal(A, B) ((A) == (B))
+
+void call_once(once_flag *, void (*)(void));
+
+int mtx_init(mtx_t *, int);
+void mtx_destroy(mtx_t *);
+
+int mtx_lock(mtx_t *);
+int mtx_timedlock(mtx_t *restrict, const struct timespec *restrict);
+int mtx_trylock(mtx_t *);
+int mtx_unlock(mtx_t *);
+
+int cnd_init(cnd_t *);
+void cnd_destroy(cnd_t *);
+
+int cnd_broadcast(cnd_t *);
+int cnd_signal(cnd_t *);
+
+int cnd_timedwait(cnd_t *restrict, mtx_t *restrict, const struct timespec *restrict);
+int cnd_wait(cnd_t *, mtx_t *);
+
+int tss_create(tss_t *, tss_dtor_t);
+void tss_delete(tss_t key);
+
+int tss_set(tss_t, void *);
+void *tss_get(tss_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/time.h b/include/time.h
index dc88070..9ea9c73 100644
--- a/include/time.h
+++ b/include/time.h
@@ -129,6 +129,17 @@ int stime(const time_t *);
 time_t timegm(struct tm *);
 #endif
 
+  /* Implementation specific choice: The epoch that the TIME_UTC clock
+     is based upon is the Unix Epoch, that is a struct timespec
+     represents the number of seconds that have elapsed since 00:00:00
+     Coordinated Universal Time (UTC), Thursday, 1 January
+     1970. Because of differences in leap seconds this is not
+     completely equivalent to UTC. */
+  /* Beware that the TIME_UTC constant itself per the standard must be
+     greater than 0. */
+#define TIME_UTC 1
+int timespec_get(struct timespec *, int);
+
 #ifdef __cplusplus
 }
 #endif
-- 
1.7.10.4



  reply	other threads:[~2014-08-31 22:45 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-31 22:45 [PATCH 0/9] C thread patch series, v. 8.6 and 9.7 Jens Gustedt
2014-08-31 22:45 ` Jens Gustedt [this message]
2014-09-07  0:21   ` [PATCH 1/9] interface additions for the C thread implementation Rich Felker
2014-09-07  9:13     ` Jens Gustedt
2014-09-07 10:05       ` Alexander Monakov
2014-09-07 11:16         ` Jens Gustedt
2014-09-07 11:31           ` Alexander Monakov
2014-09-07 11:32           ` Rich Felker
2014-09-07 14:45             ` Jens Gustedt
2014-09-07 15:16               ` Rich Felker
2014-09-07 16:51                 ` Jens Gustedt
2014-09-07 16:55                   ` Rich Felker
2014-09-07  1:19   ` Rich Felker
2014-08-31 22:46 ` [PATCH 2/9] additions to src/time and some implied minor changes here and there Jens Gustedt
2014-09-06 17:44   ` Rich Felker
2014-08-31 22:46 ` [PATCH 3/9] use weak symbols for the POSIX functions that will be used by C threads Jens Gustedt
2014-09-06 18:52   ` Rich Felker
2014-08-31 22:46 ` [PATCH 4/9] add the functions for tss_t and once_flag Jens Gustedt
2014-08-31 22:46 ` [PATCH 5/9] add the functions for mtx_t Jens Gustedt
2014-09-07  1:51   ` Rich Felker
2014-09-07  1:54   ` Rich Felker
2014-08-31 22:47 ` [PATCH 6/9] add the functions for cnd_t Jens Gustedt
2014-08-31 22:47 ` [PATCH 7/9] add the thrd_xxxxxx functions Jens Gustedt
2014-09-07 14:24   ` Rich Felker
2014-09-07 14:52     ` Jens Gustedt
2014-09-07 15:17       ` Rich Felker
2014-08-31 22:47 ` [PATCH 8/9] separate pthread_create and pthread_exit in two different TU Jens Gustedt
2014-08-31 22:48 ` [PATCH 9/9] 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=cb03e88ca7f717c106c0aa7283202fd2f7c7f327.1409524413.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).