Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit README for clarity #27

Merged
merged 6 commits into from
Jan 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 30 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ _TODO before entering Phase 2._
- [Use case: support various languages](#use-case-support-various-languages)
- [Use case: support thread-local storage](#use-case-support-thread-local-storage)
- [Detailed design discussion](#detailed-design-discussion)
- [Design choice: thread IDs](#design-choice-thread-ids)
- [Design choice: termination](#design-choice-termination)
- [Design choice: pthreads](#design-choice-pthreads)
- [Design choice: instance-per-thread](#design-choice-instance-per-thread)
- [Considered alternatives](#considered-alternatives)
Expand Down Expand Up @@ -90,9 +92,9 @@ The API consists of a single function. In pseudo-code:
status wasi_thread_spawn(thread_start_arg* start_arg);
```

where the `status` is a unique non-negative integer thread ID of the new
thread or negative number representing an error in case the thread failed to
start.
where the `status` is a unique non-negative integer thread ID (TID) of the new
thread (see [Design choice: thread IDs](#design-choice-thread-ids)) or a
negative number representing an error if the host failed to spawn the thread.
The host implementing `wasi_thread_spawn` will call a predetermined function
export (`wasi_thread_start`) in a new WebAssembly instance. Any necessary
locking/signaling/thread-local storage will be implemented using existing
Expand Down Expand Up @@ -127,13 +129,10 @@ TLS bookkeeping (this is not much different than how C starts threads natively).

### Detailed design discussion

Threads are tricky to implement. This proposal relies on a specific WebAssembly
convention in order to work correctly.

When instantiating a module which is expected to run with wasi-threads,
the WASI host must:

1. create and provide shared memories to satisfy the module's imports.
Threads are tricky to implement. This proposal relies on a specific convention
in order to work correctly. When instantiating a module which is expected to run
with `wasi-threads`, the WASI host must first allocate shared memories to
satisfy the module's imports.

Upon a call to `wasi_thread_spawn`, the WASI host must:

Expand All @@ -152,69 +151,32 @@ Upon a call to `wasi_thread_spawn`, the WASI host must:
A WASI host that implements the above should be able to spawn threads for a
variety of languages.

### TID (thread ID)

TID is a 32-bit integer to identify threads created with `wasi_thread_spawn`.

* TIDs are managed and provided by host.

* TID 0 is reserved. `wasi_thread_spawn` should not return this value.

* It's widely assumed in musl/wasi-libc.

* The upper-most 3-bits of TID are always 0.
`wasi_thread_spawn` should not return values with these bits set.

* The most significant bit is the sign bit. As `wasi_thread_spawn` uses
signed integer and uses negative values to indicate errors, a TID needs
to be positive.

* The second bit need to be 0 in order to be compatible with the TID-based
locking implementation in musl/wasi-libc.

* The third bit need to be 0 in order to make an extra room for other
reserved values in wasi-libc.
For example, it can be used to indicate the main thread, which doesn't
have a TID in the current version of this proposal.

### Process

* A process is a group of threads.

* The main thread starts with a process which only contains
the main thread.

* Threads created by a thread in a process using `wasi_thread_spawn`
are added to the process.

* When a thread is terminated, it's removed from the process.

### Voluntary thread termination

A thread can terminate itself voluntarily by returning from
`wasi_thread_start`.

### Changes to WASI `proc_exit`

With this proposal, the `proc_exit` function takes extra responsibility
to terminate all threads in the process, not only the calling one.

Any of the threads in the process can call `proc_exit`.
#### Design choice: thread IDs

### Traps
When `wasi_thread_spawn` successfully spawns a thread, it returns a thread ID
(TID) — 32-bit integer with several restrictions. TIDs are managed and
provided by the WASI host. To avoid leaking information, the host may choose to
return arbitrary TIDs (as opposed to leaking OS TIDs).

When a trap occurs in any thread, the entire process is terminated.
Valid TIDs fall in the range $[1, 2^{29})$. Some considerations apply:
- `0` is reserved for compatibility reasons with existing libraries (e.g.,
wasi-libc) and must not be returned by `wasi_thread_spawn`
- the uppermost three bits of a valid TID must always be `0`. The most
significant bit is the sign bit and recall that `wasi_thread_spawn` uses
negative values to indicate errors. The remaining bits are reserved for
compatibility with existing language implementations.

### Process exit status
#### Design choice: termination

If one or more threads call WASI `proc_exit` or raise a trap,
one of them is chosen by the runtime to represent the exit status
of the process.
It's non deterministic which one is chosen.
A `wasi-threads` module initially executes a single thread — the main
thread. As `wasi_thread_spawn` is called, more threads begin to execute. Threads
terminate in the following ways:

If all the threads in the process have been terminated without calling
`proc_exit` or raising a trap, it's treated as if the last thread called
`proc_exit` with exit code 0.
- __upon return__ from `wasi_thread_start`, and other threads continue to
execute
- __upon a trap__ in any thread; all threads are immediately terminated
- __upon a `proc_exit` call__ in any thread; all threads are immediately
terminated.

#### Design choice: pthreads

Expand Down