Skip to content

Support per-task TLS in wasip3 - #872

Merged
alexcrichton merged 2 commits into
WebAssembly:mainfrom
alexcrichton:per-task-tls
Aug 19, 2026
Merged

alexcrichton merged 2 commits into
WebAssembly:mainfrom
alexcrichton:per-task-tls

Conversation

@alexcrichton

@alexcrichton alexcrichton commented Aug 19, 2026 •

Copy link
Copy Markdown
Collaborator

This commit is another update to how TLS is handled on the WASIp3 target
in wasi-libc. The problem being addressed here is that bindings
generators (aka wit-bindgen) currently use context slot 0 as
task-local storage but this is being co-opted for the stack pointer (and
slot 1 is the TLS base) on WASIp3 targets. This means that bindings
generators don't actually have anywhere to put task-local information
and the previous scheme of implicit threads always using the main thread
TLS meant that there was no way to distinguish anything.

To resolve this the __wasm_task_hook, which already exists, now
manages TLS-per-task. This is implemented to work with the full matrix
of {single,multi-module} x {coop-threads,no-coop-threads} through some
refactoring and such. Effectively TLS is dynamically allocated at task
startup and then deallocated when a task completes. Some hooks, like
resource destructors, _initialize, post-return, etc, all run with the
"main thread" TLS as before. Tasks can now, on WASIp3 targets, use
normal TLS storage to store task-local data.

Note: this is built on a number of other PRs which are otherwise blocked on an updated wasm-tools being published, so only the last commit here is exclusively part of this PR.

@alexcrichton
alexcrichton requested a review from dicej August 19, 2026 00:29
// If this is a multi-module program then `main_tls` is actually an array base
// pointers for each library. Swap that with the old main thread's values in
// `saved_ptr`.
void **ret = saved_ptr;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'll never get used to how C silently, implicitly converts from void* to any pointer type.

This commit is another update to how TLS is handled on the WASIp3 target
in wasi-libc. The problem being addressed here is that bindings
generators (aka `wit-bindgen`) currently use context slot 0 as
task-local storage but this is being co-opted for the stack pointer (and
slot 1 is the TLS base) on WASIp3 targets. This means that bindings
generators don't actually have anywhere to put task-local information
and the previous scheme of implicit threads always using the main thread
TLS meant that there was no way to distinguish anything.

To resolve this the `__wasm_task_hook`, which already exists, now
manages TLS-per-task. This is implemented to work with the full matrix
of {single,multi-module} x {coop-threads,no-coop-threads} through some
refactoring and such. Effectively TLS is dynamically allocated at task
startup and then deallocated when a task completes. Some hooks, like
resource destructors, `_initialize`, post-return, etc, all run with the
"main thread" TLS as before. Tasks can now, on WASIp3 targets, use
normal TLS storage to store task-local data.
@alexcrichton
alexcrichton enabled auto-merge (squash) August 19, 2026 17:49
@alexcrichton
alexcrichton merged commit 2e6fb9d into WebAssembly:main Aug 19, 2026
36 checks passed
@alexcrichton
alexcrichton deleted the per-task-tls branch August 19, 2026 17:56
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.

2 participants