Skip to content

Commit 88dbafc

Browse files
committed
Add some testing of the emscripten_condvar API. NFC
1 parent 21dc38e commit 88dbafc

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

test/test_browser.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5224,6 +5224,10 @@ def test_wasm_worker_semaphore_waitinf_acquire(self):
52245224
def test_wasm_worker_semaphore_try_acquire(self):
52255225
self.btest_exit('wasm_worker/semaphore_try_acquire.c', cflags=['-sWASM_WORKERS'])
52265226

5227+
@also_with_minimal_runtime
5228+
def test_wasm_worker_condvar_waitinf(self):
5229+
self.btest_exit('wasm_worker/condvar_waitinf.c', cflags=['-sWASM_WORKERS'])
5230+
52275231
# Tests that calling any proxied function in a Wasm Worker will abort at runtime when ASSERTIONS are enabled.
52285232
def test_wasm_worker_proxied_function(self):
52295233
error_msg = "abort:Assertion failed: Attempted to call proxied function '_proxied_js_function' in a Wasm Worker, but in Wasm Worker enabled builds, proxied function architecture is not available!"

test/test_core.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2794,6 +2794,11 @@ def test_emscripten_semaphore_waitinf_acquire(self):
27942794
def test_emscripten_semaphore_try_acquire(self):
27952795
self.do_runf('wasm_worker/semaphore_try_acquire.c', 'done\n', cflags=['-pthread'])
27962796

2797+
@requires_pthreads
2798+
@also_with_wasm_workers
2799+
def test_emscripten_condvar_waitinf(self):
2800+
self.do_runf('wasm_worker/condvar_waitinf.c', 'done\n', cflags=['-pthread'])
2801+
27972802
def test_tcgetattr(self):
27982803
self.do_runf('termios/test_tcgetattr.c', 'success')
27992804

test/wasm_worker/condvar_waitinf.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <assert.h>
2+
#include <emscripten/console.h>
3+
#include <emscripten/threading.h>
4+
#include <stdbool.h>
5+
#include <stdlib.h>
6+
7+
#ifdef __EMSCRIPTEN_PTHREADS__
8+
#include <pthread.h>
9+
#else
10+
#include <emscripten/wasm_worker.h>
11+
#endif
12+
13+
emscripten_condvar_t condvar = EMSCRIPTEN_CONDVAR_T_STATIC_INITIALIZER;
14+
emscripten_lock_t mutex = EMSCRIPTEN_LOCK_T_STATIC_INITIALIZER;
15+
16+
int globalVar = 0;
17+
_Atomic bool waiterStarted = false;
18+
19+
#ifndef __EMSCRIPTEN_PTHREADS__
20+
void do_exit() {
21+
emscripten_out("do_exit");
22+
emscripten_terminate_all_wasm_workers();
23+
emscripten_force_exit(0);
24+
}
25+
#endif
26+
27+
void waiter_main() {
28+
emscripten_out("waiter_main");
29+
emscripten_lock_waitinf_acquire(&mutex);
30+
emscripten_out("waiter: got mutex");
31+
assert(!globalVar);
32+
waiterStarted = true;
33+
34+
while (!globalVar) {
35+
emscripten_out("waiter: condvar wait");
36+
emscripten_condvar_waitinf(&condvar, &mutex);
37+
}
38+
39+
emscripten_out("waiter: done");
40+
emscripten_lock_release(&mutex);
41+
42+
#ifndef __EMSCRIPTEN_PTHREADS__
43+
emscripten_wasm_worker_post_function_v(EMSCRIPTEN_WASM_WORKER_ID_PARENT,
44+
do_exit);
45+
#endif
46+
}
47+
48+
void signaler_main() {
49+
emscripten_out("signaler_main");
50+
while (!waiterStarted) {
51+
// busy-wait for waiter
52+
}
53+
// At this point we know the waiter took the lock already.
54+
// That means that once we acquire the lock here the waiter
55+
// muste be `emscripten_condvar_waitinf`.
56+
57+
emscripten_out("signaler: aquiring lock");
58+
emscripten_lock_waitinf_acquire(&mutex);
59+
60+
emscripten_out("signaler: incrementing globalVar");
61+
globalVar += 1;
62+
63+
emscripten_out("signaler: signaling condition");
64+
emscripten_condvar_signal(&condvar, 1);
65+
66+
emscripten_out("signaler: done");
67+
emscripten_lock_release(&mutex);
68+
}
69+
70+
#ifdef __EMSCRIPTEN_PTHREADS__
71+
void* waiter_pthread(void* arg) {
72+
waiter_main();
73+
return NULL;
74+
}
75+
void* signaler_pthread(void* arg) {
76+
signaler_main();
77+
return NULL;
78+
}
79+
#endif
80+
81+
int main() {
82+
emscripten_out("in main");
83+
84+
#ifdef __EMSCRIPTEN_PTHREADS__
85+
pthread_t waiter;
86+
pthread_t signaler;
87+
pthread_create(&waiter, NULL, waiter_pthread, NULL);
88+
pthread_create(&signaler, NULL, signaler_pthread, NULL);
89+
pthread_join(waiter, NULL);
90+
pthread_join(signaler, NULL);
91+
emscripten_out("done");
92+
#else
93+
emscripten_wasm_worker_t waiter = emscripten_malloc_wasm_worker(1024);
94+
emscripten_wasm_worker_post_function_v(waiter, waiter_main);
95+
96+
emscripten_wasm_worker_t signaler = emscripten_malloc_wasm_worker(1024);
97+
emscripten_wasm_worker_post_function_v(signaler, signaler_main);
98+
#endif
99+
}

0 commit comments

Comments
 (0)