Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/pthread/emscripten_futex_wake.c
6173 views
1
/*
2
* Copyright 2021 The Emscripten Authors. All rights reserved.
3
* Emscripten is available under two separate licenses, the MIT license and the
4
* University of Illinois/NCSA Open Source License. Both these licenses can be
5
* found in the LICENSE file.
6
*/
7
8
#include <assert.h>
9
#include <errno.h>
10
#include <limits.h>
11
#include <atomic.h>
12
#include <emscripten/threading.h>
13
14
// Stores the memory address that the main thread is waiting on, if any. If
15
// the main thread is waiting, we wake it up before waking up any workers.
16
void* _emscripten_main_thread_futex;
17
18
// Returns the number of threads (>= 0) woken up, or the value -EINVAL on error.
19
// Pass count == INT_MAX to wake up all threads.
20
int emscripten_futex_wake(volatile void *addr, int count) {
21
if (!addr || (((intptr_t)addr) & 3) != 0 || count < 0) {
22
return -EINVAL;
23
}
24
if (count == 0) {
25
return 0;
26
}
27
28
// See if main thread is waiting on this address? If so, wake it up by
29
// resetting its wake location to zero. Note that this is not a fair
30
// procedure, since we always wake main thread first before any workers, so
31
// this scheme does not adhere to real queue-based waiting.
32
int main_thread_woken = 0;
33
if (a_cas_p(&_emscripten_main_thread_futex, (void*)addr, 0) == addr) {
34
// The main browser thread must never try to wake itself up!
35
assert(!emscripten_is_main_browser_thread());
36
if (count != INT_MAX) {
37
--count;
38
main_thread_woken = 1;
39
if (count <= 0) {
40
return 1;
41
}
42
}
43
}
44
45
// Wake any workers waiting on this address.
46
int ret = __builtin_wasm_memory_atomic_notify((int*)addr, count);
47
assert(ret >= 0);
48
return ret + main_thread_woken;
49
}
50
51