]> git.proxmox.com Git - wasi-libc.git/commitdiff
threads: implement support for conditional variables (#323)
authorMarcin Kolny <mkolny@amazon.com>
Tue, 6 Sep 2022 21:21:06 +0000 (23:21 +0200)
committerGitHub <noreply@github.com>
Tue, 6 Sep 2022 21:21:06 +0000 (14:21 -0700)
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.

Makefile
expected/wasm32-wasi/posix/defined-symbols.txt
libc-top-half/musl/src/thread/pthread_cond_timedwait.c

index 116d74f799eb3075f6ee8915bc9042b467433b07..6017cd5e471da6ca94461fc70f573a11bf7eb107 100644 (file)
--- a/Makefile
+++ b/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 \
index 931dc1bc7f6041ee973b883be8af05d58a112b95..538e6224bc0845b8bdf5ae24f566aaa190836257 100644 (file)
@@ -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
index 6b761455c47f0f8c8afde4e2d57768208efc06ba..ba985f9116943129c25c890f87483091f0f6a39b 100644 (file)
@@ -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;