Support process shared condition variables

This commit is contained in:
Justine Tunney 2024-07-22 16:33:23 -07:00
parent 3de6632be6
commit 0a9a6f86bb
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
14 changed files with 168 additions and 19 deletions

View file

@ -37,6 +37,7 @@ static errno_t pthread_mutex_lock_impl(pthread_mutex_t *mutex) {
// get current state of lock
word = atomic_load_explicit(&mutex->_word, memory_order_relaxed);
#if PTHREAD_USE_NSYNC
// use fancy nsync mutex if possible
if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && //
MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && //
@ -44,6 +45,7 @@ static errno_t pthread_mutex_lock_impl(pthread_mutex_t *mutex) {
_weaken(nsync_mu_lock)((nsync_mu *)mutex);
return 0;
}
#endif
// implement barebones normal mutexes
if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) {

View file

@ -46,6 +46,7 @@ errno_t pthread_mutex_trylock(pthread_mutex_t *mutex) {
// get current state of lock
word = atomic_load_explicit(&mutex->_word, memory_order_relaxed);
#if PTHREAD_USE_NSYNC
// delegate to *NSYNC if possible
if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL &&
MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && //
@ -56,6 +57,7 @@ errno_t pthread_mutex_trylock(pthread_mutex_t *mutex) {
return EBUSY;
}
}
#endif
// handle normal mutexes
if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) {

View file

@ -45,6 +45,7 @@ errno_t pthread_mutex_unlock(pthread_mutex_t *mutex) {
// get current state of lock
word = atomic_load_explicit(&mutex->_word, memory_order_relaxed);
#if PTHREAD_USE_NSYNC
// use fancy nsync mutex if possible
if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && //
MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && //
@ -52,6 +53,7 @@ errno_t pthread_mutex_unlock(pthread_mutex_t *mutex) {
_weaken(nsync_mu_unlock)((nsync_mu *)mutex);
return 0;
}
#endif
// implement barebones normal mutexes
if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) {

View file

@ -22,6 +22,8 @@
#include "libc/runtime/syslib.internal.h"
#include "libc/thread/thread.h"
void sys_sched_yield(void);
/**
* Yields current thread's remaining timeslice to operating system.
*
@ -30,13 +32,16 @@
int pthread_yield_np(void) {
if (IsXnuSilicon()) {
__syslib->__pthread_yield_np();
} else if (IsOpenbsd()) {
pthread_pause_np(); // sched_yield() is punishingly slow on OpenBSD
} else if (IsOpenbsd() || IsNetbsd()) {
// sched_yield() is punishingly slow on OpenBSD
// it's ruinously slow it'll destroy everything
pthread_pause_np();
} else {
sched_yield();
sys_sched_yield();
}
return 0;
}
__weak_reference(pthread_yield_np, thrd_yield);
__weak_reference(pthread_yield_np, sched_yield);
__weak_reference(pthread_yield_np, pthread_yield);

View file

@ -19,12 +19,11 @@
#include "libc/dce.h"
#include "libc/sysv/consts/nr.h"
#include "libc/macros.internal.h"
.privileged
// Relinquishes scheduled quantum.
//
// @return 0 on success, or -1 w/ errno
sched_yield:
sys_sched_yield:
#ifdef __x86_64__
push %rbp
mov %rsp,%rbp
@ -107,5 +106,5 @@ sched_yield:
#else
#error "arch unsupported"
#endif
.endfn sched_yield,globl
.endfn sys_sched_yield,globl
.previous