Skip to content

Commit 859062b

Browse files
Opt-in busywait mode for futexes (#562)
We are heavily using wasi-libc + wasip1-threads on browsers. Since wasi-libc uses `memory.atomic.wait32` to implement futex, and the usage of `memory.atomic.wait32` on the main thread is prohibited on browsers, we currently need to write code carefully not to reach the instruction. Emscripten addresses this limitation by [employing a busy-wait on the main thread](https://github.com/emscripten-core/emscripten/blob/058a9fff/system/lib/pthread/emscripten_futex_wait.c#L111-L150) as a workaround. Rust has [always employs busywait regardless of the current thread is main](https://github.com/rust-lang/rust/blob/a47555110cf09b3ed59811d9b02235443e76a595/library/std/src/sys/alloc/wasm.rs#L75-L144). This approach, while effective for browsers, introduces unnecessary overhead in environments where memory.atomic.wait32 is permitted. This change provides a similar solution by introducing an opt-in busy-wait mode for futexes. By making this an optional feature, we avoid imposing the overhead of busy-waiting in non-browser environments while ensuring compatibility with browser-based restrictions. ```c #include <wasi/libc-busywait.h> /// Enable busywait in futex on current thread. void __wasilibc_enable_futex_busywait_on_current_thread(void); ``` This change slightly adds some runtime overheads in futex to check if we should use busywait, but it can be optimized away as long as `__wasilibc_enable_futex_busywait_on_current_thread` is not used by user program and LTO is enabled.
1 parent a3a9596 commit 859062b

File tree

16 files changed

+191
-5
lines changed

16 files changed

+191
-5
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ LIBC_TOP_HALF_MUSL_SOURCES += \
367367
thread/sem_trywait.c \
368368
thread/sem_wait.c \
369369
thread/wasm32/wasi_thread_start.s \
370+
thread/wasm32/__wasilibc_busywait.c \
370371
)
371372
endif
372373
ifeq ($(THREAD_MODEL), single)

expected/wasm32-wasip1-threads/defined-symbols.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,13 +362,16 @@ __wasilibc_cwd_lock
362362
__wasilibc_cwd_unlock
363363
__wasilibc_deinitialize_environ
364364
__wasilibc_dttoif
365+
__wasilibc_enable_futex_busywait_on_current_thread
365366
__wasilibc_ensure_environ
366367
__wasilibc_environ
367368
__wasilibc_fd_renumber
368369
__wasilibc_find_abspath
369370
__wasilibc_find_relpath
370371
__wasilibc_find_relpath_alloc
371372
__wasilibc_futex_wait
373+
__wasilibc_futex_wait_atomic_wait
374+
__wasilibc_futex_wait_maybe_busy
372375
__wasilibc_get_environ
373376
__wasilibc_iftodt
374377
__wasilibc_initialize_environ
@@ -400,6 +403,7 @@ __wasilibc_rmdirat
400403
__wasilibc_stat
401404
__wasilibc_tell
402405
__wasilibc_unlinkat
406+
__wasilibc_use_busy_futex
403407
__wasilibc_utimens
404408
__wasm_call_dtors
405409
__wcscoll_l

expected/wasm32-wasip1-threads/include-all.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
#include <utime.h>
168168
#include <values.h>
169169
#include <wasi/api.h>
170+
#include <wasi/libc-busywait.h>
170171
#include <wasi/libc-environ.h>
171172
#include <wasi/libc-find-relpath.h>
172173
#include <wasi/libc-nocwd.h>

expected/wasm32-wasip1-threads/predefined-macros.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3131,6 +3131,7 @@
31313131
#define __va_copy(d,s) __builtin_va_copy(d,s)
31323132
#define __wasi__ 1
31333133
#define __wasi_api_h
3134+
#define __wasi_libc_busywait_h
31343135
#define __wasi_libc_environ_h
31353136
#define __wasi_libc_find_relpath_h
31363137
#define __wasi_libc_h

expected/wasm32-wasip1/include-all.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
#include <utime.h>
168168
#include <values.h>
169169
#include <wasi/api.h>
170+
#include <wasi/libc-busywait.h>
170171
#include <wasi/libc-environ.h>
171172
#include <wasi/libc-find-relpath.h>
172173
#include <wasi/libc-nocwd.h>

expected/wasm32-wasip1/predefined-macros.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3124,6 +3124,7 @@
31243124
#define __va_copy(d,s) __builtin_va_copy(d, s)
31253125
#define __wasi__ 1
31263126
#define __wasi_api_h
3127+
#define __wasi_libc_busywait_h
31273128
#define __wasi_libc_environ_h
31283129
#define __wasi_libc_find_relpath_h
31293130
#define __wasi_libc_h

expected/wasm32-wasip2/include-all.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
#include <utime.h>
169169
#include <values.h>
170170
#include <wasi/api.h>
171+
#include <wasi/libc-busywait.h>
171172
#include <wasi/libc-environ.h>
172173
#include <wasi/libc-find-relpath.h>
173174
#include <wasi/libc-nocwd.h>

expected/wasm32-wasip2/predefined-macros.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3276,6 +3276,7 @@
32763276
#define __va_copy(d,s) __builtin_va_copy(d, s)
32773277
#define __wasi__ 1
32783278
#define __wasi_api_h
3279+
#define __wasi_libc_busywait_h
32793280
#define __wasi_libc_environ_h
32803281
#define __wasi_libc_find_relpath_h
32813282
#define __wasi_libc_h

libc-bottom-half/headers/public/wasi/libc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ int __wasilibc_rename_oldat(int olddirfd, const char *oldpath, const char *newpa
6464
int __wasilibc_rename_newat(const char *oldpath, int newdirfd, const char *newpath)
6565
__attribute__((__warn_unused_result__));
6666

67+
/// Enable busywait in futex on current thread.
68+
void __wasilibc_enable_futex_busywait_on_current_thread(void);
69+
6770
#ifdef __cplusplus
6871
}
6972
#endif
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef __wasi_libc_busywait_h
2+
#define __wasi_libc_busywait_h
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
/// Enable busywait in futex on current thread.
9+
void __wasilibc_enable_futex_busywait_on_current_thread(void);
10+
11+
#ifdef __cplusplus
12+
}
13+
#endif
14+
15+
#endif

0 commit comments

Comments
 (0)