aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/musl/src/thread
diff options
context:
space:
mode:
authorjacobly0 <jacobly0@users.noreply.github.com>2023-06-20 23:14:22 -0400
committerGitHub <noreply@github.com>2023-06-20 23:14:22 -0400
commite2eabbbc5142f11defc56ad51cd5b8a5e97cdbda (patch)
treecc1127bc0a31d50e35d6200c3824cdbbe83f8ebc /lib/libc/musl/src/thread
parent8875efe54873b721cc3a6f6d83525b19d1c59ec3 (diff)
parent09c7f1bd7c4410948a984f2f155a6e36ff6279fd (diff)
downloadzig-e2eabbbc5142f11defc56ad51cd5b8a5e97cdbda.tar.gz
zig-e2eabbbc5142f11defc56ad51cd5b8a5e97cdbda.zip
Merge pull request #16098 from ziglang/musl-v1.2.4
update musl from v1.2.3 to v1.2.4
Diffstat (limited to 'lib/libc/musl/src/thread')
-rw-r--r--lib/libc/musl/src/thread/pthread_atfork.c8
-rw-r--r--lib/libc/musl/src/thread/pthread_cancel.c9
-rw-r--r--lib/libc/musl/src/thread/pthread_create.c16
-rw-r--r--lib/libc/musl/src/thread/pthread_detach.c8
-rw-r--r--lib/libc/musl/src/thread/pthread_key_create.c8
-rw-r--r--lib/libc/musl/src/thread/sem_getvalue.c3
-rw-r--r--lib/libc/musl/src/thread/sem_post.c12
-rw-r--r--lib/libc/musl/src/thread/sem_timedwait.c10
-rw-r--r--lib/libc/musl/src/thread/sem_trywait.c6
-rw-r--r--lib/libc/musl/src/thread/synccall.c2
10 files changed, 58 insertions, 24 deletions
diff --git a/lib/libc/musl/src/thread/pthread_atfork.c b/lib/libc/musl/src/thread/pthread_atfork.c
index 7649740165..26d325438c 100644
--- a/lib/libc/musl/src/thread/pthread_atfork.c
+++ b/lib/libc/musl/src/thread/pthread_atfork.c
@@ -1,7 +1,13 @@
#include <pthread.h>
+#include <errno.h>
#include "libc.h"
#include "lock.h"
+#define malloc __libc_malloc
+#define calloc undef
+#define realloc undef
+#define free undef
+
static struct atfork_funcs {
void (*prepare)(void);
void (*parent)(void);
@@ -34,7 +40,7 @@ void __fork_handler(int who)
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
{
struct atfork_funcs *new = malloc(sizeof *new);
- if (!new) return -1;
+ if (!new) return ENOMEM;
LOCK(lock);
new->next = funcs;
diff --git a/lib/libc/musl/src/thread/pthread_cancel.c b/lib/libc/musl/src/thread/pthread_cancel.c
index 2f9d5e975f..139a6fc84e 100644
--- a/lib/libc/musl/src/thread/pthread_cancel.c
+++ b/lib/libc/musl/src/thread/pthread_cancel.c
@@ -56,7 +56,12 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx)
_sigaddset(&uc->uc_sigmask, SIGCANCEL);
- if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {
+ if (self->cancelasync) {
+ pthread_sigmask(SIG_SETMASK, &uc->uc_sigmask, 0);
+ __cancel();
+ }
+
+ if (pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {
uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel;
#ifdef CANCEL_GOT
uc->uc_mcontext.MC_GOT = CANCEL_GOT;
@@ -77,7 +82,7 @@ void __testcancel()
static void init_cancellation()
{
struct sigaction sa = {
- .sa_flags = SA_SIGINFO | SA_RESTART,
+ .sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK,
.sa_sigaction = cancel_handler
};
memset(&sa.sa_mask, -1, _NSIG/8);
diff --git a/lib/libc/musl/src/thread/pthread_create.c b/lib/libc/musl/src/thread/pthread_create.c
index 6f187ee89d..087f6206d5 100644
--- a/lib/libc/musl/src/thread/pthread_create.c
+++ b/lib/libc/musl/src/thread/pthread_create.c
@@ -107,6 +107,16 @@ _Noreturn void __pthread_exit(void *result)
/* At this point we are committed to thread termination. */
+ /* After the kernel thread exits, its tid may be reused. Clear it
+ * to prevent inadvertent use and inform functions that would use
+ * it that it's no longer available. At this point the killlock
+ * may be released, since functions that use it will consistently
+ * see the thread as having exited. Release it now so that no
+ * remaining locks (except thread list) are held if we end up
+ * resetting need_locks below. */
+ self->tid = 0;
+ UNLOCK(self->killlock);
+
/* Process robust list in userspace to handle non-pshared mutexes
* and the detached thread case where the robust list head will
* be invalid when the kernel would process it. */
@@ -159,12 +169,6 @@ _Noreturn void __pthread_exit(void *result)
a_store(&self->detach_state, DT_EXITED);
__wake(&self->detach_state, 1, 1);
- /* After the kernel thread exits, its tid may be reused. Clear it
- * to prevent inadvertent use and inform functions that would use
- * it that it's no longer available. */
- self->tid = 0;
- UNLOCK(self->killlock);
-
for (;;) __syscall(SYS_exit, 0);
}
diff --git a/lib/libc/musl/src/thread/pthread_detach.c b/lib/libc/musl/src/thread/pthread_detach.c
index 77772af2c6..d73a500e79 100644
--- a/lib/libc/musl/src/thread/pthread_detach.c
+++ b/lib/libc/musl/src/thread/pthread_detach.c
@@ -5,8 +5,12 @@ static int __pthread_detach(pthread_t t)
{
/* If the cas fails, detach state is either already-detached
* or exiting/exited, and pthread_join will trap or cleanup. */
- if (a_cas(&t->detach_state, DT_JOINABLE, DT_DETACHED) != DT_JOINABLE)
- return __pthread_join(t, 0);
+ if (a_cas(&t->detach_state, DT_JOINABLE, DT_DETACHED) != DT_JOINABLE) {
+ int cs;
+ __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+ __pthread_join(t, 0);
+ __pthread_setcancelstate(cs, 0);
+ }
return 0;
}
diff --git a/lib/libc/musl/src/thread/pthread_key_create.c b/lib/libc/musl/src/thread/pthread_key_create.c
index d112094122..39770c7a3c 100644
--- a/lib/libc/musl/src/thread/pthread_key_create.c
+++ b/lib/libc/musl/src/thread/pthread_key_create.c
@@ -1,4 +1,5 @@
#include "pthread_impl.h"
+#include "fork_impl.h"
volatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX;
void *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 };
@@ -20,6 +21,13 @@ static void dummy_0(void)
weak_alias(dummy_0, __tl_lock);
weak_alias(dummy_0, __tl_unlock);
+void __pthread_key_atfork(int who)
+{
+ if (who<0) __pthread_rwlock_rdlock(&key_lock);
+ else if (!who) __pthread_rwlock_unlock(&key_lock);
+ else key_lock = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER;
+}
+
int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
{
pthread_t self = __pthread_self();
diff --git a/lib/libc/musl/src/thread/sem_getvalue.c b/lib/libc/musl/src/thread/sem_getvalue.c
index d9d8307177..c0b7762d3e 100644
--- a/lib/libc/musl/src/thread/sem_getvalue.c
+++ b/lib/libc/musl/src/thread/sem_getvalue.c
@@ -1,8 +1,9 @@
#include <semaphore.h>
+#include <limits.h>
int sem_getvalue(sem_t *restrict sem, int *restrict valp)
{
int val = sem->__val[0];
- *valp = val < 0 ? 0 : val;
+ *valp = val & SEM_VALUE_MAX;
return 0;
}
diff --git a/lib/libc/musl/src/thread/sem_post.c b/lib/libc/musl/src/thread/sem_post.c
index 31e3293d20..5c2517f236 100644
--- a/lib/libc/musl/src/thread/sem_post.c
+++ b/lib/libc/musl/src/thread/sem_post.c
@@ -1,17 +1,21 @@
#include <semaphore.h>
+#include <limits.h>
#include "pthread_impl.h"
int sem_post(sem_t *sem)
{
- int val, waiters, priv = sem->__val[2];
+ int val, new, waiters, priv = sem->__val[2];
do {
val = sem->__val[0];
waiters = sem->__val[1];
- if (val == SEM_VALUE_MAX) {
+ if ((val & SEM_VALUE_MAX) == SEM_VALUE_MAX) {
errno = EOVERFLOW;
return -1;
}
- } while (a_cas(sem->__val, val, val+1+(val<0)) != val);
- if (val<0 || waiters) __wake(sem->__val, 1, priv);
+ new = val + 1;
+ if (waiters <= 1)
+ new &= ~0x80000000;
+ } while (a_cas(sem->__val, val, new) != val);
+ if (val<0) __wake(sem->__val, waiters>1 ? 1 : -1, priv);
return 0;
}
diff --git a/lib/libc/musl/src/thread/sem_timedwait.c b/lib/libc/musl/src/thread/sem_timedwait.c
index 58d3ebfefc..aa67376c2d 100644
--- a/lib/libc/musl/src/thread/sem_timedwait.c
+++ b/lib/libc/musl/src/thread/sem_timedwait.c
@@ -1,4 +1,5 @@
#include <semaphore.h>
+#include <limits.h>
#include "pthread_impl.h"
static void cleanup(void *p)
@@ -13,14 +14,15 @@ int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at)
if (!sem_trywait(sem)) return 0;
int spins = 100;
- while (spins-- && sem->__val[0] <= 0 && !sem->__val[1]) a_spin();
+ while (spins-- && !(sem->__val[0] & SEM_VALUE_MAX) && !sem->__val[1])
+ a_spin();
while (sem_trywait(sem)) {
- int r;
+ int r, priv = sem->__val[2];
a_inc(sem->__val+1);
- a_cas(sem->__val, 0, -1);
+ a_cas(sem->__val, 0, 0x80000000);
pthread_cleanup_push(cleanup, (void *)(sem->__val+1));
- r = __timedwait_cp(sem->__val, -1, CLOCK_REALTIME, at, sem->__val[2]);
+ r = __timedwait_cp(sem->__val, 0x80000000, CLOCK_REALTIME, at, priv);
pthread_cleanup_pop(1);
if (r) {
errno = r;
diff --git a/lib/libc/musl/src/thread/sem_trywait.c b/lib/libc/musl/src/thread/sem_trywait.c
index 04edf46b52..beb435da7c 100644
--- a/lib/libc/musl/src/thread/sem_trywait.c
+++ b/lib/libc/musl/src/thread/sem_trywait.c
@@ -1,12 +1,12 @@
#include <semaphore.h>
+#include <limits.h>
#include "pthread_impl.h"
int sem_trywait(sem_t *sem)
{
int val;
- while ((val=sem->__val[0]) > 0) {
- int new = val-1-(val==1 && sem->__val[1]);
- if (a_cas(sem->__val, val, new)==val) return 0;
+ while ((val=sem->__val[0]) & SEM_VALUE_MAX) {
+ if (a_cas(sem->__val, val, val-1)==val) return 0;
}
errno = EAGAIN;
return -1;
diff --git a/lib/libc/musl/src/thread/synccall.c b/lib/libc/musl/src/thread/synccall.c
index d58c851fcf..a6b177c06f 100644
--- a/lib/libc/musl/src/thread/synccall.c
+++ b/lib/libc/musl/src/thread/synccall.c
@@ -45,7 +45,7 @@ void __synccall(void (*func)(void *), void *ctx)
{
sigset_t oldmask;
int cs, i, r;
- struct sigaction sa = { .sa_flags = SA_RESTART, .sa_handler = handler };
+ struct sigaction sa = { .sa_flags = SA_RESTART | SA_ONSTACK, .sa_handler = handler };
pthread_t self = __pthread_self(), td;
int count = 0;