mirror of
https://git.proxmox.com/git/wasi-libc
synced 2025-08-03 02:00:43 +00:00
threads: implement support for conditional variables (#323)
The implementation is not as efficient as for native Linux platform due to lack of FUTEX_REQUEUE-like system call in WASI. For now we wake all the waiters which is inefficient; if that becomes a bottleneck, I suggest we'll revisit the implementation.
This commit is contained in:
parent
27ba71f95e
commit
c40403f9b0
8
Makefile
8
Makefile
@ -192,11 +192,17 @@ LIBC_TOP_HALF_MUSL_SOURCES += \
|
||||
$(addprefix $(LIBC_TOP_HALF_MUSL_SRC_DIR)/, \
|
||||
thread/__wait.c \
|
||||
thread/__timedwait.c \
|
||||
thread/pthread_cleanup_push.c \
|
||||
thread/pthread_cond_broadcast.c \
|
||||
thread/pthread_cond_destroy.c \
|
||||
thread/pthread_cond_init.c \
|
||||
thread/pthread_cond_signal.c \
|
||||
thread/pthread_cond_timedwait.c \
|
||||
thread/pthread_cond_wait.c \
|
||||
thread/pthread_condattr_destroy.c \
|
||||
thread/pthread_condattr_init.c \
|
||||
thread/pthread_condattr_setclock.c \
|
||||
thread/pthread_condattr_setpshared.c \
|
||||
thread/pthread_cleanup_push.c \
|
||||
thread/pthread_mutex_consistent.c \
|
||||
thread/pthread_mutex_destroy.c \
|
||||
thread/pthread_mutex_init.c \
|
||||
|
@ -179,8 +179,10 @@ __polevll
|
||||
__posix_getopt
|
||||
__pow_log_data
|
||||
__powf_log2_data
|
||||
__private_cond_signal
|
||||
__progname
|
||||
__progname_full
|
||||
__pthread_cond_timedwait
|
||||
__pthread_mutex_lock
|
||||
__pthread_mutex_timedlock
|
||||
__pthread_mutex_trylock
|
||||
@ -937,6 +939,12 @@ program_invocation_name
|
||||
program_invocation_short_name
|
||||
pselect
|
||||
psignal
|
||||
pthread_cond_broadcast
|
||||
pthread_cond_destroy
|
||||
pthread_cond_init
|
||||
pthread_cond_signal
|
||||
pthread_cond_timedwait
|
||||
pthread_cond_wait
|
||||
pthread_condattr_destroy
|
||||
pthread_condattr_init
|
||||
pthread_condattr_setclock
|
||||
|
@ -1,5 +1,9 @@
|
||||
#include "pthread_impl.h"
|
||||
|
||||
#ifndef __wasilibc_unmodified_upstream
|
||||
#include <common/clock.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* struct waiter
|
||||
*
|
||||
@ -48,9 +52,15 @@ static inline void unlock(volatile int *l)
|
||||
static inline void unlock_requeue(volatile int *l, volatile int *r, int w)
|
||||
{
|
||||
a_store(l, 0);
|
||||
#ifdef __wasilibc_unmodified_upstream
|
||||
if (w) __wake(l, 1, 1);
|
||||
else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS
|
||||
|| __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r);
|
||||
#else
|
||||
// Always wake due to lack of requeue system call in WASI
|
||||
// This can impact the performance, so we might need to re-visit that decision
|
||||
__wake(l, 1, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
enum {
|
||||
@ -63,6 +73,9 @@ int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restri
|
||||
{
|
||||
struct waiter node = { 0 };
|
||||
int e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp;
|
||||
#ifndef __wasilibc_unmodified_upstream
|
||||
struct __clockid clock_id = { .id = clock };
|
||||
#endif
|
||||
volatile int *fut;
|
||||
|
||||
if ((m->_m_type&15) && (m->_m_lock&INT_MAX) != __pthread_self()->tid)
|
||||
@ -97,7 +110,11 @@ int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restri
|
||||
__pthread_setcancelstate(PTHREAD_CANCEL_MASKED, &cs);
|
||||
if (cs == PTHREAD_CANCEL_DISABLE) __pthread_setcancelstate(cs, 0);
|
||||
|
||||
#ifdef __wasilibc_unmodified_upstream
|
||||
do e = __timedwait_cp(fut, seq, clock, ts, !shared);
|
||||
#else
|
||||
do e = __timedwait_cp(fut, seq, &clock_id, ts, !shared);
|
||||
#endif
|
||||
while (*fut==seq && (!e || e==EINTR));
|
||||
if (e == EINTR) e = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user