Skip to content

Commit 11c56df

Browse files
committed
Add design doc: Wasm Worker Pthread Compatibility
See #26631
1 parent ecb9e39 commit 11c56df

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Design Doc: Wasm Worker Pthread Compatibility
2+
3+
- **Status**: Draft
4+
- **Bug**: https://github.com/emscripten-core/emscripten/issues/26631
5+
6+
## Context
7+
Wasm Workers in Emscripten are a lightweight alternative to pthreads. They use
8+
the same memory and can use the same synchronization primitives, but they do not
9+
have a full `struct pthread` and thus many pthread-based APIs (like
10+
`pthread_self()`) currently do not work when called from a Wasm Worker.
11+
12+
This is not an issue in pure Wasm Workers programs but we also support hybrid
13+
programs that run both pthreads and Wasm Workers. In this cases the pthread
14+
API is avilable, but will fail in undefined ways if called from Wasm Workers.
15+
16+
This document proposes a plan to improve the hybrid mode by adding the pthread
17+
metadata (`struct pthread`) to each Wasm Worker, allowing the pthread API (or at
18+
least some subset of it) APIs to used from Wasm Workers.
19+
20+
## Proposed Changes
21+
22+
### 1. Memory Layout
23+
Currently, Wasm Workers allocate space for TLS and stack: `[TLS data] [Stack]`.
24+
We propose to change this to: `[struct pthread] [TLS data] [Stack]`.
25+
26+
The `struct pthread` will be located at the very beginning of the allocated
27+
memory block for each Wasm Worker.
28+
29+
### 2. `struct pthread` Initialization
30+
The `struct pthread` will be initialized by the creator thread in `emscripten_create_wasm_worker` (or `emscripten_malloc_wasm_worker`).
31+
This includes:
32+
- Zero-initializing the structure.
33+
- Setting the `self` pointer to the start of the `struct pthread`.
34+
- Initializing essential fields like `tid`.
35+
36+
On the worker thread side, `_emscripten_wasm_worker_initialize` will need to set
37+
the thread-local pointer (returned by `__get_tp()`) to the `struct pthread`
38+
location.
39+
40+
### 3. `__get_tp` Support
41+
We will modify `system/lib/pthread/emscripten_thread_state.S` to provide a
42+
`__get_tp` implementation for Wasm workers that returns the address of the
43+
`struct pthread`. This will allow `__pthread_self()` and other related functions
44+
to work correctly.
45+
46+
### 4. Supported Pthread API Subset
47+
We intend to support a subset of the pthread API within Wasm workers:
48+
- `pthread_self()`: Returns the worker's `struct pthread` pointer.
49+
- `pthread_equal()`: Works normally.
50+
- `pthread_getspecific()` / `pthread_setspecific()`: TSD (Thread Specific Data) should work if `tsd` field in `struct pthread` is initialized.
51+
- `pthread_mutex_*`: Mutexes will work as they rely on `struct pthread` for owner tracking.
52+
- `pthread_cond_*`: Condition variables will work as they rely on `struct pthread` for waiter tracking.
53+
- Low-level synchronization primitives that use `struct pthread` (e.g., some internal locks).
54+
55+
APIs that will NOT be supported (or will have limited support):
56+
- `pthread_create()` / `pthread_join()` / `pthread_detach()`: Wasm workers have their own creation and lifecycle management.
57+
- `pthread_cancel()`: Not supported in Wasm workers.
58+
- `pthread_kill()`: Not supported in Wasm workers.
59+
60+
## Implementation Plan
61+
62+
1. Modify `emscripten_create_wasm_worker` in `system/lib/wasm_worker/library_wasm_worker.c` to account for `sizeof(struct pthread)` in memory allocation and initialize the structure.
63+
2. Update `_emscripten_wasm_worker_initialize` in `system/lib/wasm_worker/wasm_worker_initialize.S` to set the thread pointer.
64+
3. Modify `system/lib/pthread/emscripten_thread_state.S` to enable `__get_tp` for Wasm workers.
65+
4. Review and test essential pthread functions (like TSD) in Wasm workers.
66+
5. Document the supported and unsupported pthread APIs for Wasm workers.
67+
68+
## Verification
69+
- Add a new test that makes use of `pthread_self()` and low level synchronization APIs from a Wasm Worker.
70+
- Verify that existing Wasm worker tests still pass.

0 commit comments

Comments
 (0)