Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/atomic/test_wait_suspending.c
14365 views
1
#include <emscripten.h>
2
#include <emscripten/wasm_worker.h>
3
#include <emscripten/threading.h>
4
#include <assert.h>
5
6
// Test emscripten_atomic_wait_suspending() function.
7
8
_Atomic int addr = 1;
9
10
void run_test() {
11
emscripten_out("worker running");
12
#if __EMSCRIPTEN_WASM_WORKERS__
13
emscripten_wasm_worker_sleep(1000 * 1000000ull); // Sleep one second.
14
#else
15
emscripten_thread_sleep(1000); // Sleep one second.
16
#endif
17
emscripten_out("worker: addr = 1234");
18
addr = 1234;
19
emscripten_out("worker: notify async waiting main thread");
20
emscripten_atomic_notify((int32_t*)&addr, 1);
21
}
22
23
24
// This test run in both wasm workers and pthreads mode
25
#ifdef __EMSCRIPTEN_WASM_WORKERS__
26
27
void worker_main() {
28
run_test();
29
}
30
31
#else
32
33
pthread_t t;
34
35
bool done = false;
36
37
void keepalive(void* user_data) {
38
if (!done) {
39
emscripten_set_timeout(keepalive, 100, NULL);
40
}
41
}
42
43
void* thread_main(void* arg) {
44
run_test();
45
return 0;
46
}
47
48
#endif
49
50
int main() {
51
emscripten_out("main: creating worker");
52
53
#ifdef __EMSCRIPTEN_WASM_WORKERS__
54
emscripten_wasm_worker_t worker = emscripten_malloc_wasm_worker(4096);
55
emscripten_wasm_worker_post_function_v(worker, worker_main);
56
#else
57
pthread_create(&t, NULL, thread_main, NULL);
58
// This is bit of hack to keep the node process alive. Without this,
59
// the whole node process will exit when we suspend them main thread below.
60
emscripten_set_timeout(keepalive, 100, NULL);
61
#endif
62
63
ATOMICS_WAIT_TOKEN_T ret;
64
65
emscripten_out("Async waiting on address with unexpected value should return 'not-equal'");
66
ret = emscripten_atomic_wait_suspending((int32_t*)&addr, 2, EMSCRIPTEN_WAIT_ASYNC_INFINITY);
67
assert(ret == ATOMICS_WAIT_NOT_EQUAL);
68
69
emscripten_out("Waiting on address with unexpected value should return 'not-equal' also if timeout==0");
70
ret = emscripten_atomic_wait_suspending((int32_t*)&addr, 2, 0);
71
assert(ret == ATOMICS_WAIT_NOT_EQUAL);
72
73
emscripten_out("Waiting for 0 milliseconds should return 'timed-out'");
74
ret = emscripten_atomic_wait_suspending((int32_t*)&addr, 1, 0);
75
assert(ret == ATOMICS_WAIT_TIMED_OUT);
76
77
emscripten_out("Waiting for >0 milliseconds should also timeout");
78
ret = emscripten_atomic_wait_suspending((int32_t*)&addr, 1, 10);
79
assert(ret == ATOMICS_WAIT_TIMED_OUT);
80
81
emscripten_out("Waiting for infinitely long should return once we have been notified");
82
ret = emscripten_atomic_wait_suspending((int32_t*)&addr, 1, EMSCRIPTEN_WAIT_ASYNC_INFINITY);
83
assert(ret == ATOMICS_WAIT_OK);
84
assert(addr == 1234);
85
86
#ifdef __EMSCRIPTEN_WASM_WORKERS__
87
emscripten_terminate_all_wasm_workers();
88
#else
89
done = true;
90
pthread_join(t, NULL);
91
#endif
92
93
emscripten_out("test finished");
94
return 0;
95
}
96
97