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

Add canonical thread.* builtins #291

Merged
merged 14 commits into from
Mar 8, 2024
2 changes: 2 additions & 0 deletions design/mvp/Binary.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ canon ::= 0x00 0x00 f:<core:funcidx> opts:<opts> ft:<typeidx> => (canon lift
| 0x02 rt:<typeidx> => (canon resource.new rt (core func))
| 0x03 rt:<typdidx> => (canon resource.drop rt (core func))
| 0x04 rt:<typeidx> => (canon resource.rep rt (core func))
| 0x05 ft:<typeidx> => (canon thread.spawn ft (core func))
| 0x06 => (canon thread.hw_concurrency (core func))
opts ::= opt*:vec(<canonopt>) => opt*
canonopt ::= 0x00 => string-encoding=utf8
| 0x01 => string-encoding=utf16
Expand Down
70 changes: 70 additions & 0 deletions design/mvp/CanonicalABI.md
Original file line number Diff line number Diff line change
Expand Up @@ -1697,7 +1697,73 @@ def canon_resource_rep(inst, rt, i):
Note that the "locally-defined" requirement above ensures that only the
component instance defining a resource can access its representation.

### 🧵 `canon thread.spawn`

For a canonical definition:
```wasm
(canon thread.spawn (type $ft) (core func $st))
```
validation specifies:
* `$ft` must refer to a `shared` function type; initially, only the type `(func
shared (param $c i32))` is allowed (see explanation below)
* `$st` is given type `(func (param $f (ref null $ft)) (param $c i32) (result $e
i32))`.

> Note: ideally, a thread could be spawned with [arbitrary thread parameters].
> To import polymorphic versions of `$st`, a naming scheme is necessary to
> differentiate between the imports with varying `$ft`. Since many languages can
> use `$c` to address a memory region containing multiple values (the current
> [wasi-libc convention]), the initial version restricts `$ft` to `[i32] -> []`.
lukewagner marked this conversation as resolved.
Show resolved Hide resolved
abrown marked this conversation as resolved.
Show resolved Hide resolved
> The inclusion of `$ft` ensures backwards compatibility for when arbitrary
> parameters are allowed.

Calling `$st` checks that the reference `$f` is not null. Then, it spawns a
thread which:
- invokes `$f` with `$c`
- executes `$f` until completion or trap in a `shared` context as described by
the [shared-everything threads] proposal.
lukewagner marked this conversation as resolved.
Show resolved Hide resolved

In pseudocode, `$st` looks like:

```python
def canon_thread_spawn(f, c):
trap_if(f is None)
if DETERMINISTIC_PROFILE:
return -1

def thread_start():
try:
f(c)
except CoreWebAssemblyException:
trap()

if spawn(thread_start):
return 0
else:
return -1
```

### 🧵 `canon thread.hw_concurrency`

For a canonical definition:
```wasm
(canon thread.hw_concurrency (core func $f))
```
validation specifies:
* `$f` is given type `(func shared (result i32))`.

Calling `$f` returns the number of threads the underlying hardware can be
abrown marked this conversation as resolved.
Show resolved Hide resolved
expected to execute concurrently. This value can be artificially limited by
engine configuration and is not allowed to change over the lifetime of a
component instance.

```python
def canon_thread_hw_concurrency():
if DETERMINISTIC_PROFILE:
return 1
else:
return NUM_ALLOWED_THREADS
```

[Canonical Definitions]: Explainer.md#canonical-definitions
[`canonopt`]: Explainer.md#canonical-definitions
Expand Down Expand Up @@ -1730,3 +1796,7 @@ component instance defining a resource can access its representation.

[`import_name`]: https://clang.llvm.org/docs/AttributeReference.html#import-name
[`export_name`]: https://clang.llvm.org/docs/AttributeReference.html#export-name

[Arbitrary Thread Parameters]: https://github.com/WebAssembly/shared-everything-threads/discussions/3
[wasi-libc Convention]: https://github.com/WebAssembly/wasi-libc/blob/925ad6d7/libc-top-half/musl/src/thread/pthread_create.c#L318
[Shared-Everything Threads]: https://github.com/WebAssembly/shared-everything-threads/blob/main/proposals/shared-everything-threads/Overview.md
21 changes: 21 additions & 0 deletions design/mvp/Explainer.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ emoji symbols listed below; these emojis will be removed once they are
implemented, considered stable and included in a future milestone:
* 🪙: value imports/exports and component-level start function
* 🪺: nested namespaces and packages in import/export names
* 🧵: threading built-ins

(Based on the previous [scoping and layering] proposal to the WebAssembly CG,
this repo merges and supersedes the [module-linking] and [interface-types]
Expand Down Expand Up @@ -1219,7 +1220,12 @@ canon ::= ...
| (canon resource.new <typeidx> (core func <id>?))
| (canon resource.drop <typeidx> (core func <id>?))
| (canon resource.rep <typeidx> (core func <id>?))
| (canon thread.spawn <typeidx> (core func <id>?)) 🧵
| (canon thread.hw_concurrency (core func <id>?)) 🧵
```

##### Resources

The `resource.new` built-in has type `[i32] -> [i32]` and creates a new
resource (with resource type `typeidx`) with the given `i32` value as its
representation and returning the `i32` index of a new handle pointing to this
Expand Down Expand Up @@ -1262,6 +1268,20 @@ Here, the `i32` returned by `resource.new`, which is an index into the
component's handle-table, is immediately returned by `make_R`, thereby
transferring ownership of the newly-created resource to the export's caller.

##### 🧵 Threads

The [shared-everything-threads] proposal adds component model built-ins for
thread management. These are specified as built-ins and not core WebAssembly
instructions because browsers expect this functionality to come from existing
Web/JS APIs.
lukewagner marked this conversation as resolved.
Show resolved Hide resolved

The `thread.spawn` built-in has type `[f:(ref null $f) c:i32] -> [i32]` and
spawns a new thread by invoking the shared function `f` while passing `c` to it,
returning whether a thread was successfully spawned.

The `resource.hw_concurrency` built-in has type `[] -> [i32]` and returns the
number of threads that can be expected to execute concurrently.

See the [CanonicalABI.md](CanonicalABI.md#canonical-definitions) for detailed
definitions of each of these built-ins and their interactions.

Expand Down Expand Up @@ -1927,6 +1947,7 @@ and will be added over the coming months to complete the MVP proposal:
[stack-switching]: https://github.com/WebAssembly/stack-switching/blob/main/proposals/stack-switching/Overview.md
[esm-integration]: https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration
[gc]: https://github.com/WebAssembly/gc/blob/main/proposals/gc/MVP.md
[shared-everything-threads]: https://github.com/WebAssembly/shared-everything-threads
[WASI Preview 2]: https://github.com/WebAssembly/WASI/tree/main/preview2

[Adapter Functions]: FutureFeatures.md#custom-abis-via-adapter-functions
Expand Down
Loading