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
next prev parent 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).