Skip to content

Commit 5549780

Browse files
abrownlukewagner
andauthored
Add canonical thread.* builtins (#291)
* Add canonical `thread.*` builtins This change adds the `thread.spawn` and `thread.hw_concurrency` builtins in line with what was proposed in the shared-everything threads [proposal]. [proposal]: https://github.com/WebAssembly/shared-everything-threads/blob/main/proposals/shared-everything-threads/Overview.md#thread-management-builtins * Update design/mvp/Explainer.md Co-authored-by: Luke Wagner <mail@lukewagner.name> * Update design/mvp/CanonicalABI.md Co-authored-by: Luke Wagner <mail@lukewagner.name> * Link to shared-everything-threads proposal * Restrict `thread.hw_concurrency` values; mention deterministic profile * Clarify null check timing * Add binary encoding * Document deterministic profile validation * Allow `thread.spawn` to fail * Update design/mvp/CanonicalABI.md Co-authored-by: Luke Wagner <mail@lukewagner.name> * Remove `n` thread spawning * Adopt @lukewagner's review suggestions Co-authored-by: Luke Wagner <mail@lukewagner.name> * Convert exceptions to traps * Improve wording of parameter limitation Co-authored-by: Luke Wagner <mail@lukewagner.name> --------- Co-authored-by: Luke Wagner <mail@lukewagner.name>
1 parent 71eac54 commit 5549780

3 files changed

Lines changed: 93 additions & 0 deletions

File tree

design/mvp/Binary.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ canon ::= 0x00 0x00 f:<core:funcidx> opts:<opts> ft:<typeidx> => (canon lift
267267
| 0x02 rt:<typeidx> => (canon resource.new rt (core func))
268268
| 0x03 rt:<typdidx> => (canon resource.drop rt (core func))
269269
| 0x04 rt:<typeidx> => (canon resource.rep rt (core func))
270+
| 0x05 ft:<typeidx> => (canon thread.spawn ft (core func))
271+
| 0x06 => (canon thread.hw_concurrency (core func))
270272
opts ::= opt*:vec(<canonopt>) => opt*
271273
canonopt ::= 0x00 => string-encoding=utf8
272274
| 0x01 => string-encoding=utf16

design/mvp/CanonicalABI.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,7 +1697,73 @@ def canon_resource_rep(inst, rt, i):
16971697
Note that the "locally-defined" requirement above ensures that only the
16981698
component instance defining a resource can access its representation.
16991699

1700+
### 🧵 `canon thread.spawn`
17001701

1702+
For a canonical definition:
1703+
```wasm
1704+
(canon thread.spawn (type $ft) (core func $st))
1705+
```
1706+
validation specifies:
1707+
* `$ft` must refer to a `shared` function type; initially, only the type `(func
1708+
shared (param $c i32))` is allowed (see explanation below)
1709+
* `$st` is given type `(func (param $f (ref null $ft)) (param $c i32) (result $e
1710+
i32))`.
1711+
1712+
> Note: ideally, a thread could be spawned with [arbitrary thread parameters].
1713+
> Currently, that would require additional work in the toolchain to support so,
1714+
> for simplicity, the current proposal simply fixes a single `i32` parameter type.
1715+
> However, `thread.spawn` could be extended to allow arbitrary thread parameters
1716+
> in the future, once it's concretely beneficial to the toolchain.
1717+
> The inclusion of `$ft` ensures backwards compatibility for when arbitrary
1718+
> parameters are allowed.
1719+
1720+
Calling `$st` checks that the reference `$f` is not null. Then, it spawns a
1721+
thread which:
1722+
- invokes `$f` with `$c`
1723+
- executes `$f` until completion or trap in a `shared` context as described by
1724+
the [shared-everything threads] proposal.
1725+
1726+
In pseudocode, `$st` looks like:
1727+
1728+
```python
1729+
def canon_thread_spawn(f, c):
1730+
trap_if(f is None)
1731+
if DETERMINISTIC_PROFILE:
1732+
return -1
1733+
1734+
def thread_start():
1735+
try:
1736+
f(c)
1737+
except CoreWebAssemblyException:
1738+
trap()
1739+
1740+
if spawn(thread_start):
1741+
return 0
1742+
else:
1743+
return -1
1744+
```
1745+
1746+
### 🧵 `canon thread.hw_concurrency`
1747+
1748+
For a canonical definition:
1749+
```wasm
1750+
(canon thread.hw_concurrency (core func $f))
1751+
```
1752+
validation specifies:
1753+
* `$f` is given type `(func shared (result i32))`.
1754+
1755+
Calling `$f` returns the number of threads the underlying hardware can be
1756+
expected to execute concurrently. This value can be artificially limited by
1757+
engine configuration and is not allowed to change over the lifetime of a
1758+
component instance.
1759+
1760+
```python
1761+
def canon_thread_hw_concurrency():
1762+
if DETERMINISTIC_PROFILE:
1763+
return 1
1764+
else:
1765+
return NUM_ALLOWED_THREADS
1766+
```
17011767

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

17311797
[`import_name`]: https://clang.llvm.org/docs/AttributeReference.html#import-name
17321798
[`export_name`]: https://clang.llvm.org/docs/AttributeReference.html#export-name
1799+
1800+
[Arbitrary Thread Parameters]: https://github.com/WebAssembly/shared-everything-threads/discussions/3
1801+
[wasi-libc Convention]: https://github.com/WebAssembly/wasi-libc/blob/925ad6d7/libc-top-half/musl/src/thread/pthread_create.c#L318
1802+
[Shared-Everything Threads]: https://github.com/WebAssembly/shared-everything-threads/blob/main/proposals/shared-everything-threads/Overview.md

design/mvp/Explainer.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ emoji symbols listed below; these emojis will be removed once they are
4242
implemented, considered stable and included in a future milestone:
4343
* 🪙: value imports/exports and component-level start function
4444
* 🪺: nested namespaces and packages in import/export names
45+
* 🧵: threading built-ins
4546

4647
(Based on the previous [scoping and layering] proposal to the WebAssembly CG,
4748
this repo merges and supersedes the [module-linking] and [interface-types]
@@ -1261,7 +1262,12 @@ canon ::= ...
12611262
| (canon resource.new <typeidx> (core func <id>?))
12621263
| (canon resource.drop <typeidx> (core func <id>?))
12631264
| (canon resource.rep <typeidx> (core func <id>?))
1265+
| (canon thread.spawn <typeidx> (core func <id>?)) 🧵
1266+
| (canon thread.hw_concurrency (core func <id>?)) 🧵
12641267
```
1268+
1269+
##### Resources
1270+
12651271
The `resource.new` built-in has type `[i32] -> [i32]` and creates a new
12661272
resource (with resource type `typeidx`) with the given `i32` value as its
12671273
representation and returning the `i32` index of a new handle pointing to this
@@ -1304,6 +1310,20 @@ Here, the `i32` returned by `resource.new`, which is an index into the
13041310
component's handle-table, is immediately returned by `make_R`, thereby
13051311
transferring ownership of the newly-created resource to the export's caller.
13061312

1313+
##### 🧵 Threads
1314+
1315+
The [shared-everything-threads] proposal adds component model built-ins for
1316+
thread management. These are specified as built-ins and not core WebAssembly
1317+
instructions because browsers expect this functionality to come from existing
1318+
Web/JS APIs.
1319+
1320+
The `thread.spawn` built-in has type `[f:(ref null $f) c:i32] -> [i32]` and
1321+
spawns a new thread by invoking the shared function `f` while passing `c` to it,
1322+
returning whether a thread was successfully spawned.
1323+
1324+
The `resource.hw_concurrency` built-in has type `[] -> [i32]` and returns the
1325+
number of threads that can be expected to execute concurrently.
1326+
13071327
See the [CanonicalABI.md](CanonicalABI.md#canonical-definitions) for detailed
13081328
definitions of each of these built-ins and their interactions.
13091329

@@ -1957,6 +1977,7 @@ and will be added over the coming months to complete the MVP proposal:
19571977
[stack-switching]: https://github.com/WebAssembly/stack-switching/blob/main/proposals/stack-switching/Overview.md
19581978
[esm-integration]: https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration
19591979
[gc]: https://github.com/WebAssembly/gc/blob/main/proposals/gc/MVP.md
1980+
[shared-everything-threads]: https://github.com/WebAssembly/shared-everything-threads
19601981
[WASI Preview 2]: https://github.com/WebAssembly/WASI/tree/main/preview2
19611982

19621983
[Adapter Functions]: FutureFeatures.md#custom-abis-via-adapter-functions

0 commit comments

Comments
 (0)