blob: 66bc6a104bc711af4324cb7f6247ece6e22c2dfa [file]
#include <assert.h>
#include <emscripten/console.h>
#include <emscripten/threading.h>
#include <stdbool.h>
#include <stdlib.h>
#ifdef __EMSCRIPTEN_PTHREADS__
#include <pthread.h>
#else
#include <emscripten/wasm_worker.h>
#endif
emscripten_condvar_t condvar = EMSCRIPTEN_CONDVAR_T_STATIC_INITIALIZER;
emscripten_lock_t mutex = EMSCRIPTEN_LOCK_T_STATIC_INITIALIZER;
int globalVar = 0;
_Atomic bool waiterStarted = false;
#ifndef __EMSCRIPTEN_PTHREADS__
void do_exit() {
emscripten_out("do_exit");
emscripten_terminate_all_wasm_workers();
emscripten_force_exit(0);
}
#endif
void waiter_main() {
emscripten_out("waiter_main");
emscripten_lock_waitinf_acquire(&mutex);
emscripten_out("waiter: got mutex");
assert(!globalVar);
waiterStarted = true;
while (!globalVar) {
emscripten_out("waiter: condvar wait");
emscripten_condvar_waitinf(&condvar, &mutex);
}
emscripten_out("waiter: done");
emscripten_lock_release(&mutex);
#ifndef __EMSCRIPTEN_PTHREADS__
emscripten_wasm_worker_post_function_v(EMSCRIPTEN_WASM_WORKER_ID_PARENT,
do_exit);
#endif
}
void signaler_main() {
emscripten_out("signaler_main");
while (!waiterStarted) {
// busy-wait for waiter
}
// At this point we know the waiter took the lock already.
// That means that once we acquire the lock here the waiter
// must be `emscripten_condvar_waitinf`.
emscripten_out("signaler: aquiring lock");
emscripten_lock_waitinf_acquire(&mutex);
emscripten_out("signaler: incrementing globalVar");
globalVar += 1;
emscripten_out("signaler: signaling condition");
emscripten_condvar_signal(&condvar, 1);
emscripten_out("signaler: done");
emscripten_lock_release(&mutex);
}
#ifdef __EMSCRIPTEN_PTHREADS__
void* waiter_pthread(void* arg) {
waiter_main();
return NULL;
}
void* signaler_pthread(void* arg) {
signaler_main();
return NULL;
}
#endif
int main() {
emscripten_out("in main");
#ifdef __EMSCRIPTEN_PTHREADS__
pthread_t waiter;
pthread_t signaler;
pthread_create(&waiter, NULL, waiter_pthread, NULL);
pthread_create(&signaler, NULL, signaler_pthread, NULL);
pthread_join(waiter, NULL);
pthread_join(signaler, NULL);
emscripten_out("done");
#else
emscripten_wasm_worker_t waiter = emscripten_malloc_wasm_worker(4096);
emscripten_wasm_worker_post_function_v(waiter, waiter_main);
emscripten_wasm_worker_t signaler = emscripten_malloc_wasm_worker(4096);
emscripten_wasm_worker_post_function_v(signaler, signaler_main);
#endif
}