Introduce cosmo_futex_wait and cosmo_futex_wake

Cosmopolitan Futexes are now exposed as a public API.
This commit is contained in:
Justine Tunney 2024-11-22 11:08:29 -08:00
parent 729f7045e3
commit 9ddbfd921e
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
66 changed files with 886 additions and 917 deletions

View file

@ -17,11 +17,11 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/blockcancel.internal.h"
#include "libc/cosmo.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
#include "libc/limits.h"
#include "libc/thread/thread.h"
#include "third_party/nsync/futex.internal.h"
/**
* Waits for all threads to arrive at barrier.
@ -54,14 +54,14 @@ errno_t pthread_barrier_wait(pthread_barrier_t *barrier) {
atomic_store_explicit(&barrier->_counter, barrier->_count,
memory_order_release);
atomic_store_explicit(&barrier->_waiters, 0, memory_order_release);
nsync_futex_wake_(&barrier->_waiters, INT_MAX, barrier->_pshared);
cosmo_futex_wake(&barrier->_waiters, INT_MAX, barrier->_pshared);
return PTHREAD_BARRIER_SERIAL_THREAD;
}
// wait for everyone else to arrive at barrier
BLOCK_CANCELATION;
while ((n = atomic_load_explicit(&barrier->_waiters, memory_order_acquire)))
nsync_futex_wait_(&barrier->_waiters, n, barrier->_pshared, 0, 0);
cosmo_futex_wait(&barrier->_waiters, n, barrier->_pshared, 0, 0);
ALLOW_CANCELATION;
return 0;

View file

@ -16,12 +16,12 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/cosmo.h"
#include "libc/dce.h"
#include "libc/intrin/atomic.h"
#include "libc/limits.h"
#include "libc/thread/thread.h"
#include "third_party/nsync/cv.h"
#include "third_party/nsync/futex.internal.h"
__static_yoink("nsync_mu_lock");
__static_yoink("nsync_mu_unlock");
@ -63,6 +63,6 @@ errno_t pthread_cond_broadcast(pthread_cond_t *cond) {
// roll forward the monotonic sequence
atomic_fetch_add_explicit(&cond->_sequence, 1, memory_order_acq_rel);
if (atomic_load_explicit(&cond->_waiters, memory_order_acquire))
nsync_futex_wake_((atomic_int *)&cond->_sequence, INT_MAX, cond->_pshared);
cosmo_futex_wake((atomic_int *)&cond->_sequence, INT_MAX, cond->_pshared);
return 0;
}

View file

@ -16,11 +16,11 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/cosmo.h"
#include "libc/dce.h"
#include "libc/intrin/atomic.h"
#include "libc/thread/thread.h"
#include "third_party/nsync/cv.h"
#include "third_party/nsync/futex.internal.h"
__static_yoink("nsync_mu_lock");
__static_yoink("nsync_mu_unlock");
@ -62,6 +62,6 @@ errno_t pthread_cond_signal(pthread_cond_t *cond) {
// roll forward the monotonic sequence
atomic_fetch_add_explicit(&cond->_sequence, 1, memory_order_acq_rel);
if (atomic_load_explicit(&cond->_waiters, memory_order_acquire))
nsync_futex_wake_((atomic_int *)&cond->_sequence, 1, cond->_pshared);
cosmo_futex_wake((atomic_int *)&cond->_sequence, 1, cond->_pshared);
return 0;
}

View file

@ -18,6 +18,8 @@
*/
#include "libc/calls/calls.h"
#include "libc/calls/cp.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/cosmo.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
@ -28,7 +30,6 @@
#include "libc/thread/thread2.h"
#include "third_party/nsync/common.internal.h"
#include "third_party/nsync/cv.h"
#include "third_party/nsync/futex.internal.h"
#include "third_party/nsync/time.h"
__static_yoink("nsync_mu_lock");
@ -74,8 +75,8 @@ static errno_t pthread_cond_timedwait_impl(pthread_cond_t *cond,
int rc;
struct PthreadWait waiter = {cond, mutex};
pthread_cleanup_push(pthread_cond_leave, &waiter);
rc = nsync_futex_wait_((atomic_int *)&cond->_sequence, seq1, cond->_pshared,
cond->_clock, abstime);
rc = cosmo_futex_wait((atomic_int *)&cond->_sequence, seq1, cond->_pshared,
cond->_clock, abstime);
pthread_cleanup_pop(true);
if (rc == -EAGAIN)
rc = 0;

View file

@ -18,6 +18,7 @@
*/
#include "libc/assert.h"
#include "libc/atomic.h"
#include "libc/cosmo.h"
#include "libc/cxxabi.h"
#include "libc/dce.h"
#include "libc/intrin/atomic.h"
@ -33,7 +34,6 @@
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#include "third_party/nsync/futex.internal.h"
#include "third_party/nsync/wait_s.internal.h"
/**
@ -137,8 +137,8 @@ wontreturn void pthread_exit(void *rc) {
// note that the main thread is joinable by child threads
if (pt->pt_flags & PT_STATIC) {
atomic_store_explicit(&tib->tib_tid, 0, memory_order_release);
nsync_futex_wake_((atomic_int *)&tib->tib_tid, INT_MAX,
!IsWindows() && !IsXnu());
cosmo_futex_wake((atomic_int *)&tib->tib_tid, INT_MAX,
!IsWindows() && !IsXnu());
_Exit1(0);
}

View file

@ -20,6 +20,8 @@
#include "libc/calls/cp.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/cosmo.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/atomic.h"
@ -30,7 +32,6 @@
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread2.h"
#include "libc/thread/tls.h"
#include "third_party/nsync/futex.internal.h"
static const char *DescribeReturnValue(char buf[30], int err, void **value) {
char *p = buf;
@ -75,8 +76,8 @@ static errno_t _pthread_wait(atomic_int *ctid, struct timespec *abstime) {
if (!(err = pthread_testcancel_np())) {
BEGIN_CANCELATION_POINT;
while ((x = atomic_load_explicit(ctid, memory_order_acquire))) {
e = nsync_futex_wait_(ctid, x, !IsWindows() && !IsXnu(), CLOCK_REALTIME,
abstime);
e = cosmo_futex_wait(ctid, x, !IsWindows() && !IsXnu(), CLOCK_REALTIME,
abstime);
if (e == -ECANCELED) {
err = ECANCELED;
break;

View file

@ -19,6 +19,7 @@
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/cosmo.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
@ -26,7 +27,6 @@
#include "libc/runtime/syslib.internal.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/semaphore.h"
#include "third_party/nsync/futex.internal.h"
/**
* Unlocks semaphore.
@ -46,7 +46,7 @@ int sem_post(sem_t *sem) {
old = atomic_fetch_add_explicit(&sem->sem_value, 1, memory_order_acq_rel);
unassert(old > INT_MIN);
if (old >= 0) {
wakeups = nsync_futex_wake_(&sem->sem_value, 1, sem->sem_pshared);
wakeups = cosmo_futex_wake(&sem->sem_value, 1, sem->sem_pshared);
npassert(wakeups >= 0);
rc = 0;
} else {

View file

@ -22,6 +22,7 @@
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/cosmo.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
@ -32,7 +33,6 @@
#include "libc/sysv/errfuns.h"
#include "libc/thread/semaphore.h"
#include "libc/thread/thread.h"
#include "third_party/nsync/futex.internal.h"
static void sem_delay(int n) {
volatile int i;
@ -119,8 +119,8 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime) {
do {
if (!(v = atomic_load_explicit(&sem->sem_value, memory_order_relaxed))) {
rc = nsync_futex_wait_(&sem->sem_value, v, sem->sem_pshared,
CLOCK_REALTIME, abstime);
rc = cosmo_futex_wait(&sem->sem_value, v, sem->sem_pshared,
CLOCK_REALTIME, abstime);
if (rc == -EINTR || rc == -ECANCELED) {
errno = -rc;
rc = -1;