Path: blob/main/system/lib/pthread/emscripten_futex_wake.c
6173 views
/*1* Copyright 2021 The Emscripten Authors. All rights reserved.2* Emscripten is available under two separate licenses, the MIT license and the3* University of Illinois/NCSA Open Source License. Both these licenses can be4* found in the LICENSE file.5*/67#include <assert.h>8#include <errno.h>9#include <limits.h>10#include <atomic.h>11#include <emscripten/threading.h>1213// Stores the memory address that the main thread is waiting on, if any. If14// the main thread is waiting, we wake it up before waking up any workers.15void* _emscripten_main_thread_futex;1617// Returns the number of threads (>= 0) woken up, or the value -EINVAL on error.18// Pass count == INT_MAX to wake up all threads.19int emscripten_futex_wake(volatile void *addr, int count) {20if (!addr || (((intptr_t)addr) & 3) != 0 || count < 0) {21return -EINVAL;22}23if (count == 0) {24return 0;25}2627// See if main thread is waiting on this address? If so, wake it up by28// resetting its wake location to zero. Note that this is not a fair29// procedure, since we always wake main thread first before any workers, so30// this scheme does not adhere to real queue-based waiting.31int main_thread_woken = 0;32if (a_cas_p(&_emscripten_main_thread_futex, (void*)addr, 0) == addr) {33// The main browser thread must never try to wake itself up!34assert(!emscripten_is_main_browser_thread());35if (count != INT_MAX) {36--count;37main_thread_woken = 1;38if (count <= 0) {39return 1;40}41}42}4344// Wake any workers waiting on this address.45int ret = __builtin_wasm_memory_atomic_notify((int*)addr, count);46assert(ret >= 0);47return ret + main_thread_woken;48}495051