Skip to content

Commit c40403f

Browse files
authored
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.
1 parent 27ba71f commit c40403f

3 files changed

Lines changed: 32 additions & 1 deletion

File tree

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,17 @@ LIBC_TOP_HALF_MUSL_SOURCES += \
192192
$(addprefix $(LIBC_TOP_HALF_MUSL_SRC_DIR)/, \
193193
thread/__wait.c \
194194
thread/__timedwait.c \
195+
thread/pthread_cleanup_push.c \
196+
thread/pthread_cond_broadcast.c \
197+
thread/pthread_cond_destroy.c \
198+
thread/pthread_cond_init.c \
199+
thread/pthread_cond_signal.c \
200+
thread/pthread_cond_timedwait.c \
201+
thread/pthread_cond_wait.c \
195202
thread/pthread_condattr_destroy.c \
196203
thread/pthread_condattr_init.c \
197204
thread/pthread_condattr_setclock.c \
198205
thread/pthread_condattr_setpshared.c \
199-
thread/pthread_cleanup_push.c \
200206
thread/pthread_mutex_consistent.c \
201207
thread/pthread_mutex_destroy.c \
202208
thread/pthread_mutex_init.c \

expected/wasm32-wasi/posix/defined-symbols.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,10 @@ __polevll
179179
__posix_getopt
180180
__pow_log_data
181181
__powf_log2_data
182+
__private_cond_signal
182183
__progname
183184
__progname_full
185+
__pthread_cond_timedwait
184186
__pthread_mutex_lock
185187
__pthread_mutex_timedlock
186188
__pthread_mutex_trylock
@@ -937,6 +939,12 @@ program_invocation_name
937939
program_invocation_short_name
938940
pselect
939941
psignal
942+
pthread_cond_broadcast
943+
pthread_cond_destroy
944+
pthread_cond_init
945+
pthread_cond_signal
946+
pthread_cond_timedwait
947+
pthread_cond_wait
940948
pthread_condattr_destroy
941949
pthread_condattr_init
942950
pthread_condattr_setclock

libc-top-half/musl/src/thread/pthread_cond_timedwait.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include "pthread_impl.h"
22

3+
#ifndef __wasilibc_unmodified_upstream
4+
#include <common/clock.h>
5+
#endif
6+
37
/*
48
* struct waiter
59
*
@@ -48,9 +52,15 @@ static inline void unlock(volatile int *l)
4852
static inline void unlock_requeue(volatile int *l, volatile int *r, int w)
4953
{
5054
a_store(l, 0);
55+
#ifdef __wasilibc_unmodified_upstream
5156
if (w) __wake(l, 1, 1);
5257
else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS
5358
|| __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r);
59+
#else
60+
// Always wake due to lack of requeue system call in WASI
61+
// This can impact the performance, so we might need to re-visit that decision
62+
__wake(l, 1, 1);
63+
#endif
5464
}
5565

5666
enum {
@@ -63,6 +73,9 @@ int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restri
6373
{
6474
struct waiter node = { 0 };
6575
int e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp;
76+
#ifndef __wasilibc_unmodified_upstream
77+
struct __clockid clock_id = { .id = clock };
78+
#endif
6679
volatile int *fut;
6780

6881
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
97110
__pthread_setcancelstate(PTHREAD_CANCEL_MASKED, &cs);
98111
if (cs == PTHREAD_CANCEL_DISABLE) __pthread_setcancelstate(cs, 0);
99112

113+
#ifdef __wasilibc_unmodified_upstream
100114
do e = __timedwait_cp(fut, seq, clock, ts, !shared);
115+
#else
116+
do e = __timedwait_cp(fut, seq, &clock_id, ts, !shared);
117+
#endif
101118
while (*fut==seq && (!e || e==EINTR));
102119
if (e == EINTR) e = 0;
103120

0 commit comments

Comments
 (0)