Skip to content

Commit 101782c

Browse files
committed
wasi-threads: add an initial implementation
This change is a first step toward implementing `wasi-threads` in Wasmtime. We may find that it has some missing pieces, but the core functionality is there: when `wasi::thread_spawn` is called by a running WebAssembly module, a function named `wasi_thread_start` is found in the module's exports and called in a new instance. The shared memory of the original instance is reused in the new instance. This new WASI proposal is in its early stages and details are still being hashed out in the [spec] and [wasi-libc] repositories. Due to its experimental state, the `wasi-threads` functionality is hidden behind both a compile-time and runtime flag: one must build with `--features wasi-threads` but also run the Wasmtime CLI with `--wasm-features threads` and `--wasi-modules experimental-wasi-threads`. One can experiment with `wasi-threads` by running: ```console $ cargo run --features wasi-threads -- \ --wasm-features threads --wasi-modules experimental-wasi-threads \ <a threads-enabled module> ``` Threads-enabled Wasm modules are not yet easy to build. Hopefully this is resolved soon, but in the meantime see the use of `THREAD_MODEL=posix` in the [wasi-libc] repository for some clues on what is necessary. Wiggle complicates things by requiring the Wasm memory to be exported with a certain name and `wasi-threads` also expects that memory to be imported; this build-time obstacle can be overcome with the `--import-memory --export-memory` flags only available in the latest Clang tree. Due to all of this, the included tests are written directly in WAT--run these with: ```console $ cargo test --features wasi-threads -p wasmtime-cli -- cli_tests ``` [spec]: https://github.com/WebAssembly/wasi-threads [wasi-libc]: https://github.com/WebAssembly/wasi-libc This change does not protect the WASI implementations themselves from concurrent access. This is already complete in previous commits or left for future commits in certain cases (e.g., wasi-nn).
1 parent 31c178e commit 101782c

File tree

10 files changed

+581
-41
lines changed

10 files changed

+581
-41
lines changed

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ wasmtime-wast = { workspace = true }
3131
wasmtime-wasi = { workspace = true }
3232
wasmtime-wasi-crypto = { workspace = true, optional = true }
3333
wasmtime-wasi-nn = { workspace = true, optional = true }
34+
wasmtime-wasi-threads = { workspace = true, optional = true }
3435
clap = { workspace = true, features = ["color", "suggestions", "derive"] }
3536
anyhow = { workspace = true }
3637
target-lexicon = { workspace = true }
@@ -87,6 +88,7 @@ members = [
8788
"crates/bench-api",
8889
"crates/c-api",
8990
"crates/cli-flags",
91+
"crates/wasi-threads",
9092
"crates/environ/fuzz",
9193
"crates/jit-icache-coherence",
9294
"crates/winch",
@@ -123,6 +125,7 @@ wasmtime-wast = { path = "crates/wast", version = "=6.0.0" }
123125
wasmtime-wasi = { path = "crates/wasi", version = "6.0.0" }
124126
wasmtime-wasi-crypto = { path = "crates/wasi-crypto", version = "6.0.0" }
125127
wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "6.0.0" }
128+
wasmtime-wasi-threads = { path = "crates/wasi-threads", version = "6.0.0" }
126129
wasmtime-component-util = { path = "crates/component-util", version = "=6.0.0" }
127130
wasmtime-component-macro = { path = "crates/component-macro", version = "=6.0.0" }
128131
wasmtime-asm-macros = { path = "crates/asm-macros", version = "=6.0.0" }
@@ -191,13 +194,13 @@ default = [
191194
"wasmtime/wat",
192195
"wasmtime/parallel-compilation",
193196
"vtune",
194-
"wasi-nn",
195197
"pooling-allocator",
196198
]
197199
jitdump = ["wasmtime/jitdump"]
198200
vtune = ["wasmtime/vtune"]
199201
wasi-crypto = ["dep:wasmtime-wasi-crypto"]
200202
wasi-nn = ["dep:wasmtime-wasi-nn"]
203+
wasi-threads = ["dep:wasmtime-wasi-threads"]
201204
pooling-allocator = ["wasmtime/pooling-allocator", "wasmtime-cli-flags/pooling-allocator"]
202205
all-arch = ["wasmtime/all-arch"]
203206
posix-signals-on-macos = ["wasmtime/posix-signals-on-macos"]

crates/cli-flags/src/lib.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,17 @@ pub const SUPPORTED_WASI_MODULES: &[(&str, &str)] = &[
5050
"wasi-common",
5151
"enables support for the WASI common APIs, see https://github.com/WebAssembly/WASI",
5252
),
53+
(
54+
"experimental-wasi-crypto",
55+
"enables support for the WASI cryptography APIs (experimental), see https://github.com/WebAssembly/wasi-crypto",
56+
),
5357
(
5458
"experimental-wasi-nn",
5559
"enables support for the WASI neural network API (experimental), see https://github.com/WebAssembly/wasi-nn",
5660
),
5761
(
58-
"experimental-wasi-crypto",
59-
"enables support for the WASI cryptography APIs (experimental), see https://github.com/WebAssembly/wasi-crypto",
62+
"experimental-wasi-threads",
63+
"enables support for the WASI threading API (experimental), see https://github.com/WebAssembly/wasi-threads",
6064
),
6165
];
6266

@@ -466,8 +470,9 @@ fn parse_wasi_modules(modules: &str) -> Result<WasiModules> {
466470
let mut set = |module: &str, enable: bool| match module {
467471
"" => Ok(()),
468472
"wasi-common" => Ok(wasi_modules.wasi_common = enable),
469-
"experimental-wasi-nn" => Ok(wasi_modules.wasi_nn = enable),
470473
"experimental-wasi-crypto" => Ok(wasi_modules.wasi_crypto = enable),
474+
"experimental-wasi-nn" => Ok(wasi_modules.wasi_nn = enable),
475+
"experimental-wasi-threads" => Ok(wasi_modules.wasi_threads = enable),
471476
"default" => bail!("'default' cannot be specified with other WASI modules"),
472477
_ => bail!("unsupported WASI module '{}'", module),
473478
};
@@ -494,19 +499,23 @@ pub struct WasiModules {
494499
/// parts once the implementation allows for it (e.g. wasi-fs, wasi-clocks, etc.).
495500
pub wasi_common: bool,
496501

497-
/// Enable the experimental wasi-nn implementation
502+
/// Enable the experimental wasi-crypto implementation.
503+
pub wasi_crypto: bool,
504+
505+
/// Enable the experimental wasi-nn implementation.
498506
pub wasi_nn: bool,
499507

500-
/// Enable the experimental wasi-crypto implementation
501-
pub wasi_crypto: bool,
508+
/// Enable the experimental wasi-threads implementation.
509+
pub wasi_threads: bool,
502510
}
503511

504512
impl Default for WasiModules {
505513
fn default() -> Self {
506514
Self {
507515
wasi_common: true,
508-
wasi_nn: false,
509516
wasi_crypto: false,
517+
wasi_nn: false,
518+
wasi_threads: false,
510519
}
511520
}
512521
}
@@ -518,6 +527,7 @@ impl WasiModules {
518527
wasi_common: false,
519528
wasi_nn: false,
520529
wasi_crypto: false,
530+
wasi_threads: false,
521531
}
522532
}
523533
}
@@ -663,8 +673,9 @@ mod test {
663673
options.wasi_modules.unwrap(),
664674
WasiModules {
665675
wasi_common: true,
676+
wasi_crypto: false,
666677
wasi_nn: false,
667-
wasi_crypto: false
678+
wasi_threads: false
668679
}
669680
);
670681
}
@@ -676,8 +687,9 @@ mod test {
676687
options.wasi_modules.unwrap(),
677688
WasiModules {
678689
wasi_common: true,
690+
wasi_crypto: false,
679691
wasi_nn: false,
680-
wasi_crypto: false
692+
wasi_threads: false
681693
}
682694
);
683695
}
@@ -693,8 +705,9 @@ mod test {
693705
options.wasi_modules.unwrap(),
694706
WasiModules {
695707
wasi_common: false,
708+
wasi_crypto: false,
696709
wasi_nn: true,
697-
wasi_crypto: false
710+
wasi_threads: false
698711
}
699712
);
700713
}
@@ -707,8 +720,9 @@ mod test {
707720
options.wasi_modules.unwrap(),
708721
WasiModules {
709722
wasi_common: false,
723+
wasi_crypto: false,
710724
wasi_nn: false,
711-
wasi_crypto: false
725+
wasi_threads: false
712726
}
713727
);
714728
}

crates/wasi-threads/Cargo.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "wasmtime-wasi-threads"
3+
version.workspace = true
4+
authors.workspace = true
5+
description = "Wasmtime implementation of the wasi-threads API"
6+
documentation = "https://docs.rs/wasmtime-wasi-nn"
7+
license = "Apache-2.0 WITH LLVM-exception"
8+
categories = ["wasm", "parallelism", "threads"]
9+
keywords = ["webassembly", "wasm", "neural-network"]
10+
repository = "https://github.com/bytecodealliance/wasmtime"
11+
readme = "README.md"
12+
edition.workspace = true
13+
14+
[dependencies]
15+
anyhow = { workspace = true }
16+
log = { workspace = true }
17+
rand = "0.8"
18+
wasi-common = { workspace = true }
19+
wasmtime = { workspace = true }
20+
21+
[badges]
22+
maintenance = { status = "experimental" }

0 commit comments

Comments
 (0)