Skip to content

Commit c28bd43

Browse files
committed
Only use futex_wait_busy on the main browser thread
When I ported this code from JS back in #15742 I mistakenly changed the semantics here. This change restores the previous behaviour of using atomic.wait except in on the main browser thread. The `futex_wait_busy` can clearly only be used a single main thread and is not appropriate for using in cases where there are other threads in the system that also don't support `atomic.wait` (such as IIUC audio worklets). To support that case we would need a different busy wait function that didn't depend on some global singleton like _emscripten_main_thread_futex.
1 parent 6988f7a commit c28bd43

File tree

2 files changed

+10
-10
lines changed

2 files changed

+10
-10
lines changed

system/lib/pthread/emscripten_futex_wait.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515

1616
extern void* _emscripten_main_thread_futex;
1717

18-
int _emscripten_thread_supports_atomics_wait(void);
19-
20-
static int futex_wait_busy(volatile void *addr, uint32_t val, double timeout) {
18+
static int futex_wait_main_browser_thread(volatile void* addr,
19+
uint32_t val,
20+
double timeout) {
2121
// Atomics.wait is not available in the main browser thread, so simulate it
2222
// via busy spinning.
2323
double now = emscripten_get_now();
@@ -119,11 +119,10 @@ int emscripten_futex_wait(volatile void *addr, uint32_t val, double max_wait_ms)
119119
int ret;
120120
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_RUNNING, EM_THREAD_STATUS_WAITFUTEX);
121121

122-
// For threads that cannot block (i.e. the main browser thread) we can't use
123-
// __builtin_wasm_memory_atomic_wait32 so we call out the JS function that
124-
// will busy wait.
125-
if (!_emscripten_thread_supports_atomics_wait()) {
126-
ret = futex_wait_busy(addr, val, max_wait_ms);
122+
// For the main browser thread we can't use
123+
// __builtin_wasm_memory_atomic_wait32 so we have busy wait instead.
124+
if (emscripten_is_main_browser_thread()) {
125+
ret = futex_wait_main_browser_thread(addr, val, max_wait_ms);
127126
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_WAITFUTEX, EM_THREAD_STATUS_RUNNING);
128127
return ret;
129128
}

test/core/pthread/emscripten_futexes.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@
22
#include <emscripten/threading.h>
33
#include <errno.h>
44
#include <limits.h>
5+
#include <math.h>
56
#include <stdio.h>
67

78
int main() {
89
// This should return -EWOULDBLOCK.
910
int futex_value = 42;
10-
int rc = emscripten_futex_wait(&futex_value, futex_value + 1, 0);
11+
int rc = emscripten_futex_wait(&futex_value, futex_value + 1, INFINITY);
1112
assert(rc == -EWOULDBLOCK);
1213

1314
// This should return -ETIMEDOUT.
1415
rc = emscripten_futex_wait(&futex_value, futex_value, 1);
1516
assert(rc == -ETIMEDOUT);
1617

1718
// Check that this thread has removed itself from the wait queue.
18-
rc = emscripten_futex_wake(&futex_value, INT_MAX);
19+
rc = emscripten_futex_wake(&futex_value, INFINITY);
1920
assert(rc == 0);
2021

2122
// Check that the wait address is checked for validity.

0 commit comments

Comments
 (0)