[musl] Make tss_t the source of truth, not pthread_key_t
Change-Id: I5272f676e3c9ea045a65841f4126356ffb85d39c
diff --git a/third_party/ulib/musl/musl-rules.mk b/third_party/ulib/musl/musl-rules.mk
index 19ed516..66cbc69 100644
--- a/third_party/ulib/musl/musl-rules.mk
+++ b/third_party/ulib/musl/musl-rules.mk
@@ -80,7 +80,7 @@
$(LOCAL_DIR)/pthread/pthread_getcpuclockid.c \
$(LOCAL_DIR)/pthread/pthread_getspecific.c \
$(LOCAL_DIR)/pthread/pthread_join.c \
- $(LOCAL_DIR)/pthread/pthread_key_create.c \
+ $(LOCAL_DIR)/pthread/pthread_key.c \
$(LOCAL_DIR)/pthread/pthread_kill.c \
$(LOCAL_DIR)/pthread/pthread_mutex_consistent.c \
$(LOCAL_DIR)/pthread/pthread_mutex_destroy.c \
@@ -821,8 +821,7 @@
$(LOCAL_DIR)/src/thread/thrd_join.c \
$(LOCAL_DIR)/src/thread/thrd_sleep.c \
$(LOCAL_DIR)/src/thread/thrd_yield.c \
- $(LOCAL_DIR)/src/thread/tss_create.c \
- $(LOCAL_DIR)/src/thread/tss_delete.c \
+ $(LOCAL_DIR)/src/thread/tss.c \
$(LOCAL_DIR)/src/thread/tss_set.c \
$(LOCAL_DIR)/src/time/__asctime.c \
$(LOCAL_DIR)/src/time/__map_file.c \
diff --git a/third_party/ulib/musl/pthread/pthread_create.c b/third_party/ulib/musl/pthread/pthread_create.c
index 6cc8df5..a9593c9 100644
--- a/third_party/ulib/musl/pthread/pthread_create.c
+++ b/third_party/ulib/musl/pthread/pthread_create.c
@@ -169,7 +169,7 @@
__tls_run_dtors();
- __pthread_tsd_run_dtors();
+ __thread_tsd_run_dtors();
__dl_thread_cleanup();
diff --git a/third_party/ulib/musl/pthread/pthread_key.c b/third_party/ulib/musl/pthread/pthread_key.c
new file mode 100644
index 0000000..f9b3f44
--- /dev/null
+++ b/third_party/ulib/musl/pthread/pthread_key.c
@@ -0,0 +1,14 @@
+#include "threads_impl.h"
+
+#include <assert.h>
+
+static_assert(TSS_DTOR_ITERATIONS == PTHREAD_DESTRUCTOR_ITERATIONS, "");
+
+int pthread_key_create(pthread_key_t* k, void (*dtor)(void*)) {
+ return tss_create(k, dtor) == thrd_success ? 0 : EAGAIN;
+}
+
+int pthread_key_delete(pthread_key_t k) {
+ tss_delete(k);
+ return 0;
+}
diff --git a/third_party/ulib/musl/pthread/pthread_key_create.c b/third_party/ulib/musl/pthread/pthread_key_create.c
deleted file mode 100644
index 53e619b..0000000
--- a/third_party/ulib/musl/pthread/pthread_key_create.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#include "threads_impl.h"
-
-typedef void (*key_t)(void*);
-static _Atomic(key_t) keys[PTHREAD_KEYS_MAX];
-
-static void nodtor(void* dummy) {}
-
-int __pthread_key_create(pthread_key_t* k, void (*dtor)(void*)) {
- unsigned i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
- unsigned j = i;
-
- if (!dtor)
- dtor = nodtor;
- do {
- key_t expected = NULL;
- if (atomic_compare_exchange_strong(&keys[j], &expected, dtor)) {
- *k = j;
- return 0;
- }
- } while ((j = (j + 1) % PTHREAD_KEYS_MAX) != i);
- return EAGAIN;
-}
-
-int __pthread_key_delete(pthread_key_t k) {
- atomic_store(&keys[k], NULL);
- return 0;
-}
-
-void __pthread_tsd_run_dtors(void) {
- pthread_t self = __pthread_self();
- int i, j, not_finished = self->tsd_used;
- for (j = 0; not_finished && j < PTHREAD_DESTRUCTOR_ITERATIONS; j++) {
- not_finished = 0;
- for (i = 0; i < PTHREAD_KEYS_MAX; i++) {
- if (self->tsd[i] && atomic_load(&keys[i])) {
- void* tmp = self->tsd[i];
- self->tsd[i] = 0;
- atomic_load(&keys[i])(tmp);
- not_finished = 1;
- }
- }
- }
-}
-
-weak_alias(__pthread_key_delete, pthread_key_delete);
-weak_alias(__pthread_key_create, pthread_key_create);
diff --git a/third_party/ulib/musl/src/conf/sysconf.c b/third_party/ulib/musl/src/conf/sysconf.c
index 5db672d..b45d234 100644
--- a/third_party/ulib/musl/src/conf/sysconf.c
+++ b/third_party/ulib/musl/src/conf/sysconf.c
@@ -3,6 +3,7 @@
#include <limits.h>
#include <signal.h>
#include <stdint.h>
+#include <threads.h>
#include <unistd.h>
#include <zircon/syscalls.h>
@@ -80,7 +81,7 @@
[_SC_GETPW_R_SIZE_MAX] = -1,
[_SC_LOGIN_NAME_MAX] = 256,
[_SC_TTY_NAME_MAX] = TTY_NAME_MAX,
- [_SC_THREAD_DESTRUCTOR_ITERATIONS] = PTHREAD_DESTRUCTOR_ITERATIONS,
+ [_SC_THREAD_DESTRUCTOR_ITERATIONS] = TSS_DTOR_ITERATIONS,
[_SC_THREAD_KEYS_MAX] = PTHREAD_KEYS_MAX,
[_SC_THREAD_STACK_MIN] = PTHREAD_STACK_MIN,
[_SC_THREAD_THREADS_MAX] = -1,
diff --git a/third_party/ulib/musl/src/internal/threads_impl.h b/third_party/ulib/musl/src/internal/threads_impl.h
index 00c7671..f78dbea 100644
--- a/third_party/ulib/musl/src/internal/threads_impl.h
+++ b/third_party/ulib/musl/src/internal/threads_impl.h
@@ -159,9 +159,6 @@
// Signal n (or all, for -1) threads on a pthread_cond_t or cnd_t.
void __private_cond_signal(void* condvar, int n) ATTR_LIBC_VISIBILITY;
-int __pthread_key_create(tss_t*, void (*)(void*)) ATTR_LIBC_VISIBILITY;
-int __pthread_key_delete(tss_t k) ATTR_LIBC_VISIBILITY;
-
// This is guaranteed to only return 0, EINVAL, or ETIMEDOUT.
int __timedwait(atomic_int*, int, clockid_t, const struct timespec*)
ATTR_LIBC_VISIBILITY;
@@ -174,7 +171,7 @@
void __thread_allocation_inhibit(void) ATTR_LIBC_VISIBILITY;
void __thread_allocation_release(void) ATTR_LIBC_VISIBILITY;
-void __pthread_tsd_run_dtors(void) ATTR_LIBC_VISIBILITY;
+void __thread_tsd_run_dtors(void) ATTR_LIBC_VISIBILITY;
#define DEFAULT_PTHREAD_ATTR \
((pthread_attr_t){ \
diff --git a/third_party/ulib/musl/src/thread/tss.c b/third_party/ulib/musl/src/thread/tss.c
new file mode 100644
index 0000000..606840b
--- /dev/null
+++ b/third_party/ulib/musl/src/thread/tss.c
@@ -0,0 +1,49 @@
+#include "threads_impl.h"
+
+// C11 does not define any way for applications to know the maximum
+// number of tss_t slots. pthreads, however, does, via the
+// PTHREAD_KEYS_MAX constant. So we allow that bit of pthreads to
+// bleed over here (and into sysconf, which also reports the value)
+// rather than go through some circuituous pattern to define an
+// internal constant that's just the same as the pthread one.
+
+typedef void (*key_t)(void*);
+static _Atomic(key_t) keys[PTHREAD_KEYS_MAX];
+
+static void nodtor(void* dummy) {}
+
+int tss_create(tss_t* k, void (*dtor)(void*)) {
+ unsigned i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
+ unsigned j = i;
+
+ if (!dtor)
+ dtor = nodtor;
+ do {
+ key_t expected = NULL;
+ if (atomic_compare_exchange_strong(&keys[j], &expected, dtor)) {
+ *k = j;
+ return 0;
+ }
+ } while ((j = (j + 1) % PTHREAD_KEYS_MAX) != i);
+ return EAGAIN;
+}
+
+void tss_delete(tss_t k) {
+ atomic_store(&keys[k], NULL);
+}
+
+void __thread_tsd_run_dtors(void) {
+ thrd_t self = __thrd_current();
+ int i, j, not_finished = self->tsd_used;
+ for (j = 0; not_finished && j < TSS_DTOR_ITERATIONS; j++) {
+ not_finished = 0;
+ for (i = 0; i < PTHREAD_KEYS_MAX; i++) {
+ if (self->tsd[i] && atomic_load(&keys[i])) {
+ void* tmp = self->tsd[i];
+ self->tsd[i] = 0;
+ atomic_load(&keys[i])(tmp);
+ not_finished = 1;
+ }
+ }
+ }
+}