Skip to content

Enable emscripten_futex API for Wasm Workers#26325

Merged
sbc100 merged 1 commit intoemscripten-core:mainfrom
sbc100:futex_wait_wasm_workers
Feb 25, 2026
Merged

Enable emscripten_futex API for Wasm Workers#26325
sbc100 merged 1 commit intoemscripten-core:mainfrom
sbc100:futex_wait_wasm_workers

Conversation

@sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Feb 23, 2026

This involves also including emscripten_thread_state.S which provides
APIs such as emscripten_is_main_runtime_thread and
emscripten_is_main_browser_thread` which now also work in Wasm Workers.

There is a minor code size hit here of ~80 bytes, but I think its
worth it to have these low level APIs available everywhere.

Depends on: #26309
Fixes: #26314

@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 24, 2026

Can you also take a look at #26309 which this change depends on ?

@sbc100 sbc100 force-pushed the futex_wait_wasm_workers branch from dae5acb to 8351a68 Compare February 24, 2026 01:12
@juj
Copy link
Collaborator

juj commented Feb 24, 2026

There is a minor code size hit here of ~80 bytes, but I think its
worth it to have these low level APIs available everywhere.

Maybe a better approach would be to implement emscripten_futex_wait/wake in terms of emscripten_atomic_wait_u32() and emscripten_atomic_notify() without bringing the overhead? The overhead here is about POSIX emulation, and avoiding that was exactly why Wasm Workers exists.

@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 24, 2026

There is a minor code size hit here of ~80 bytes, but I think its
worth it to have these low level APIs available everywhere.

Maybe a better approach would be to implement emscripten_futex_wait/wake in terms of emscripten_atomic_wait_u32() and emscripten_atomic_notify() without bringing the overhead? The overhead here is about POSIX emulation, and avoiding that was exactly why Wasm Workers exists.

I think they overhead is more about being able to run on the main thread.

emscripten_atomic_wait_u32 doesnt' work on the main thread, so emscripten_futex_wait instead has to busy wait on the main thread.

So at the very least we need to have _emscripten_thread_supports_atomics_wait working in wasm workers so we can know if its safe to call emscripten_atomic_wait_u32 or not.

@sbc100 sbc100 force-pushed the futex_wait_wasm_workers branch from 8351a68 to 326873c Compare February 24, 2026 19:52
This involves also including `emscripten_thread_state.S` which provides
APIs such as `emscripten_is_main_runtime_thread` and
emscripten_is_main_browser_thread` which now also work in Wasm Workers.

There is a minor code size hit here of ~80 bytes, but I think its
worth it to have these low level APIs available everywhere.
@sbc100 sbc100 force-pushed the futex_wait_wasm_workers branch from 326873c to b2e07e5 Compare February 24, 2026 21:12
@sbc100 sbc100 changed the title Enable emscripten_futex API for wasm workers Enable emscripten_futex API for Wasm Workers Feb 24, 2026
@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 24, 2026

OK, I jumped through some hoops to ensure that the cost of tracking the tread state is only payed for programs that use these APIs.

@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 25, 2026

@dschuff @kripken PTAL, this doesn't have the code size regression anymore so should no issue I hope.

@sbc100 sbc100 merged commit dc80f64 into emscripten-core:main Feb 25, 2026
36 checks passed
@sbc100 sbc100 deleted the futex_wait_wasm_workers branch February 25, 2026 01:17
.functype _emscripten_thread_supports_atomics_wait () -> (i32)
#if WASM_WORKERS_ONLY
call lazy_init_thread_state
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there might be a solution that would use the __postset construct, with a

init_thread_state__postset: '__do_set_thread_state()',
emscripten_futex_wait__deps: ['init_thread_state'],
emscripten_futex_wake__deps: ['init_thread_state'],
emscripten_is_main_runtime_thread__deps: ['init_thread_state'],
emscripten_is_main_browser_thread__deps: ['init_thread_state'],

This way we would avoid the complexity of the lazy init, but still, only emit the thread state initialization if any of the functions needing it would be called?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds like a good idea if it could be made to work.

Its tricky because those function are not JS function so they can't currently have __deps entries like that.

But yes, it would be good find a solution that was dependency graph based rather than based on a runtime flag.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this "thread state" is just a handful of wasm globals so I'm hoping maybe the cost if very marginal for real programs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can/should we make emscripten_futex_wait/wake API work in Wasm Workers.

3 participants