diff options
| author | jacobly0 <jacobly0@users.noreply.github.com> | 2023-06-20 23:14:22 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-20 23:14:22 -0400 |
| commit | e2eabbbc5142f11defc56ad51cd5b8a5e97cdbda (patch) | |
| tree | cc1127bc0a31d50e35d6200c3824cdbbe83f8ebc /lib/libc/musl/src/thread | |
| parent | 8875efe54873b721cc3a6f6d83525b19d1c59ec3 (diff) | |
| parent | 09c7f1bd7c4410948a984f2f155a6e36ff6279fd (diff) | |
| download | zig-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.c | 8 | ||||
| -rw-r--r-- | lib/libc/musl/src/thread/pthread_cancel.c | 9 | ||||
| -rw-r--r-- | lib/libc/musl/src/thread/pthread_create.c | 16 | ||||
| -rw-r--r-- | lib/libc/musl/src/thread/pthread_detach.c | 8 | ||||
| -rw-r--r-- | lib/libc/musl/src/thread/pthread_key_create.c | 8 | ||||
| -rw-r--r-- | lib/libc/musl/src/thread/sem_getvalue.c | 3 | ||||
| -rw-r--r-- | lib/libc/musl/src/thread/sem_post.c | 12 | ||||
| -rw-r--r-- | lib/libc/musl/src/thread/sem_timedwait.c | 10 | ||||
| -rw-r--r-- | lib/libc/musl/src/thread/sem_trywait.c | 6 | ||||
| -rw-r--r-- | lib/libc/musl/src/thread/synccall.c | 2 |
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; |
