diff --git a/design/mvp/Binary.md b/design/mvp/Binary.md index 8561c071..5eaf86c0 100644 --- a/design/mvp/Binary.md +++ b/design/mvp/Binary.md @@ -267,6 +267,8 @@ canon ::= 0x00 0x00 f: opts: ft: => (canon lift | 0x02 rt: => (canon resource.new rt (core func)) | 0x03 rt: => (canon resource.drop rt (core func)) | 0x04 rt: => (canon resource.rep rt (core func)) + | 0x05 ft: => (canon thread.spawn ft (core func)) + | 0x06 => (canon thread.hw_concurrency (core func)) opts ::= opt*:vec() => opt* canonopt ::= 0x00 => string-encoding=utf8 | 0x01 => string-encoding=utf16 diff --git a/design/mvp/CanonicalABI.md b/design/mvp/CanonicalABI.md index d4dd01a5..4757ef79 100644 --- a/design/mvp/CanonicalABI.md +++ b/design/mvp/CanonicalABI.md @@ -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]. +> Currently, that would require additional work in the toolchain to support so, +> for simplicity, the current proposal simply fixes a single `i32` parameter type. +> However, `thread.spawn` could be extended to allow arbitrary thread parameters +> in the future, once it's concretely beneficial to the toolchain. +> 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. + +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 +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 @@ -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 diff --git a/design/mvp/Explainer.md b/design/mvp/Explainer.md index ad410472..dd3bca39 100644 --- a/design/mvp/Explainer.md +++ b/design/mvp/Explainer.md @@ -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] @@ -1219,7 +1220,12 @@ canon ::= ... | (canon resource.new (core func ?)) | (canon resource.drop (core func ?)) | (canon resource.rep (core func ?)) + | (canon thread.spawn (core func ?)) 🧵 + | (canon thread.hw_concurrency (core func ?)) 🧵 ``` + +##### 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 @@ -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. + +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. @@ -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