Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/atomic/test_wait64_notify.c
4130 views
1
#include <emscripten/atomic.h>
2
#include <emscripten/html5.h> // for emscripten_performance_now()
3
#include <emscripten.h>
4
#include <assert.h>
5
6
#ifdef __EMSCRIPTEN_WASM_WORKERS__
7
#include <emscripten/wasm_worker.h>
8
#else
9
#include <pthread.h>
10
#endif
11
12
// Test emscripten_atomic_wait_u64() and emscripten_atomic_notify() functions.
13
14
volatile int64_t addr = 0;
15
16
void run_test() {
17
emscripten_out("worker_main");
18
emscripten_atomic_store_u64((void*)&addr, 0x100000000ull);
19
20
emscripten_out("Waiting on address with unexpected value should return 'not-equal'");
21
ATOMICS_WAIT_RESULT_T ret = emscripten_atomic_wait_u64((int64_t*)&addr, 0x200000000ull, /*timeout=*/-1);
22
assert(ret == ATOMICS_WAIT_NOT_EQUAL);
23
24
emscripten_out("Waiting on address with unexpected value should return 'not-equal' also if timeout==0");
25
ret = emscripten_atomic_wait_u64((int64_t*)&addr, 0x200000000ull, /*timeout=*/0);
26
assert(ret == ATOMICS_WAIT_NOT_EQUAL);
27
28
emscripten_out("Waiting for 0 nanoseconds should return 'timed-out'");
29
ret = emscripten_atomic_wait_u64((int64_t*)&addr, 0x100000000ull, /*timeout=*/0);
30
assert(ret == ATOMICS_WAIT_TIMED_OUT);
31
32
emscripten_out("Waiting for >0 nanoseconds should return 'timed-out'");
33
ret = emscripten_atomic_wait_u64((int64_t*)&addr, 0x100000000ull, /*timeout=*/1000);
34
assert(ret == ATOMICS_WAIT_TIMED_OUT);
35
36
emscripten_out("Waiting for infinitely long should return 'ok'");
37
emscripten_atomic_store_u64((void*)&addr, 0x300000000ull);
38
ret = emscripten_atomic_wait_u64((int64_t*)&addr, 0x300000000ull, /*timeout=*/-1);
39
assert(ret == ATOMICS_WAIT_OK);
40
41
emscripten_out("Test finished");
42
}
43
44
45
// This test run in both wasm workers and pthreads mode
46
#ifdef __EMSCRIPTEN_WASM_WORKERS__
47
48
char stack[1024];
49
50
void worker_main() {
51
run_test();
52
#ifdef REPORT_RESULT
53
REPORT_RESULT(addr >> 32);
54
#endif
55
}
56
57
#else
58
59
pthread_t t;
60
61
void* thread_main(void* arg) {
62
run_test();
63
return 0;
64
}
65
66
#endif
67
68
bool main_loop(double time, void *userData) {
69
if (addr == 0x300000000ull) {
70
// Burn one second to make sure worker finishes its test.
71
emscripten_out("main: seen worker running");
72
double t0 = emscripten_performance_now();
73
while(emscripten_performance_now() < t0 + 1000);
74
75
// Wake the waiter
76
emscripten_out("main: waking worker");
77
emscripten_atomic_notify((int32_t*)&addr, 1);
78
79
#ifndef __EMSCRIPTEN_WASM_WORKERS__
80
pthread_join(t, NULL);
81
#endif
82
83
return false;
84
}
85
return true;
86
}
87
88
int main() {
89
emscripten_out("main: creating worker");
90
91
#ifdef __EMSCRIPTEN_WASM_WORKERS__
92
emscripten_wasm_worker_t worker = emscripten_create_wasm_worker(stack, sizeof(stack));
93
emscripten_wasm_worker_post_function_v(worker, worker_main);
94
#else
95
pthread_create(&t, NULL, thread_main, NULL);
96
#endif
97
98
emscripten_out("main: entering timeout loop to wait for wasm worker to run");
99
emscripten_set_timeout_loop(main_loop, 50, 0);
100
}
101
102