File: test_wait32_notify.c

package info (click to toggle)
emscripten 3.1.69%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 121,860 kB
  • sloc: ansic: 636,110; cpp: 425,974; javascript: 78,401; python: 58,404; sh: 49,154; pascal: 5,237; makefile: 3,366; asm: 2,415; lisp: 1,869
file content (100 lines) | stat: -rw-r--r-- 2,717 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <emscripten/atomic.h>
#include <emscripten/html5.h>
#include <assert.h>

#ifdef __EMSCRIPTEN_WASM_WORKERS__
#include <emscripten/wasm_worker.h>
#else
#include <pthread.h>
#endif

// Test emscripten_atomic_wait_u32() and emscripten_atomic_notify() functions.

volatile int32_t addr = 0;

void run_test() {
  emscripten_out("worker_main");
  emscripten_atomic_store_u32((void*)&addr, 1);

  emscripten_out("Waiting on address with unexpected value should return 'not-equal'");
  ATOMICS_WAIT_RESULT_T ret = emscripten_atomic_wait_u32((int32_t*)&addr, 2, /*timeout=*/-1);
  assert(ret == ATOMICS_WAIT_NOT_EQUAL);

  emscripten_out("Waiting on address with unexpected value should return 'not-equal' also if timeout==0");
  ret = emscripten_atomic_wait_u32((int32_t*)&addr, 2, /*timeout=*/0);
  assert(ret == ATOMICS_WAIT_NOT_EQUAL);

  emscripten_out("Waiting for 0 nanoseconds should return 'timed-out'");
  ret = emscripten_atomic_wait_u32((int32_t*)&addr, 1, /*timeout=*/0);
  assert(ret == ATOMICS_WAIT_TIMED_OUT);

  emscripten_out("Waiting for >0 nanoseconds should return 'timed-out'");
  ret = emscripten_atomic_wait_u32((int32_t*)&addr, 1, /*timeout=*/1000);
  assert(ret == ATOMICS_WAIT_TIMED_OUT);

  emscripten_out("Waiting for infinitely long should return 'ok'");
  emscripten_atomic_store_u32((void*)&addr, 3);
  ret = emscripten_atomic_wait_u32((int32_t*)&addr, 3, /*timeout=*/-1);
  assert(ret == ATOMICS_WAIT_OK);

  emscripten_out("Test finished");
}


// This test run in both wasm workers and pthreads mode
#ifdef __EMSCRIPTEN_WASM_WORKERS__

void worker_main() {
  run_test();

#ifdef REPORT_RESULT
  REPORT_RESULT(addr);
#endif
}

#else

pthread_t t;

void* thread_main(void* arg) {
  run_test();
  return 0;
}

#endif


bool main_loop(double time, void *userData) {
  if (addr == 3) {
    // Burn one second to make sure worker finishes its test.
    emscripten_out("main: seen worker running");
    double t0 = emscripten_performance_now();
    while(emscripten_performance_now() < t0 + 1000);

    // Wake the waiter
    emscripten_out("main: waking worker");
    emscripten_atomic_notify((int32_t*)&addr, 1);

#ifndef __EMSCRIPTEN_WASM_WORKERS__
    pthread_join(t, NULL);
#endif

    return false;
  }
  return true;
}

int main() {
  emscripten_out("main: creating worker");

#ifdef __EMSCRIPTEN_WASM_WORKERS__
  static char stack[1024];
  emscripten_wasm_worker_t worker = emscripten_create_wasm_worker(stack, sizeof(stack));
  emscripten_wasm_worker_post_function_v(worker, worker_main);
#else
  pthread_create(&t, NULL, thread_main, NULL);
#endif

  emscripten_out("main: entering timeout loop to wait for wasm worker to run");
  emscripten_set_timeout_loop(main_loop, 50, 0);
}