-
Notifications
You must be signed in to change notification settings - Fork 51
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
Consider using wasm threads in the wasm node #91
Comments
More notes:
|
Unfortunately, the Rust side is a bit of a shitshow. See rust-lang/rust#77839 for more info. |
Opened rust-lang/rust#109727 |
It seems that Wasi isn't really https://github.com/rust-lang/rust/blob/master/library/std/src/sys/wasi/mod.rs#L32-L36 |
Maybe one way forward would be to first finish #133 EDIT: no that's not going to lead anywhere, as |
It seems that the direction is actually to add a new They were blocked on LLVM16 support in Rust, which has now landed. |
I have managed to compile a version of Rust that compiles for multithreaded wasi. Here is the diff to apply on the diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 65dfc325a11..b13e9270066 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1197,6 +1197,8 @@ fn new(mut cmd: Command, sess: &'a Session) -> WasmLd<'a> {
cmd.arg("--export=__tls_size");
cmd.arg("--export=__tls_align");
cmd.arg("--export=__tls_base");
+ } else {
+ cmd.arg("--export=wasi_thread_start");
}
}
WasmLd { cmd, sess }
diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs
index a0476d542e6..ec7f6a398ef 100644
--- a/compiler/rustc_target/src/spec/wasm32_wasi.rs
+++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs
@@ -79,7 +79,7 @@ pub fn target() -> Target {
let mut options = wasm_base::options();
options.os = "wasi".into();
- options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi"]);
+ options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi-threads"]);
options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();
@@ -96,6 +96,8 @@ pub fn target() -> Target {
options.crt_static_default = true;
options.crt_static_respected = true;
+ options.singlethread = false;
+
// Allow `+crt-static` to create a "cdylib" output which is just a wasm file
// without a main function.
options.crt_static_allows_dylibs = true;
@@ -109,7 +111,7 @@ pub fn target() -> Target {
options.entry_name = "__main_void".into();
Target {
- llvm_target: "wasm32-wasi".into(),
+ llvm_target: "wasm32-wasi-threads".into(),
pointer_width: 32,
data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20".into(),
arch: "wasm32".into(),
diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs
index c468ae395fc..d27cd66cb26 100644
--- a/library/std/src/sys/wasi/mod.rs
+++ b/library/std/src/sys/wasi/mod.rs
@@ -29,8 +29,6 @@
#[path = "../wasm/atomics/futex.rs"]
pub mod futex;
pub mod io;
-#[path = "../unsupported/locks/mod.rs"]
-pub mod locks;
pub mod net;
pub mod os;
#[path = "../unix/os_str.rs"]
@@ -50,7 +48,20 @@
pub mod time;
cfg_if::cfg_if! {
- if #[cfg(not(target_feature = "atomics"))] {
+ if #[cfg(target_feature = "atomics")] {
+ #[path = "../unix/locks"]
+ pub mod locks {
+ #![allow(unsafe_op_in_unsafe_fn)]
+ mod futex_condvar;
+ mod futex_mutex;
+ mod futex_rwlock;
+ pub(crate) use futex_condvar::Condvar;
+ pub(crate) use futex_mutex::Mutex;
+ pub(crate) use futex_rwlock::RwLock;
+ }
+ } else {
+ #[path = "../unsupported/locks/mod.rs"]
+ pub mod locks;
#[path = "../unsupported/once.rs"]
pub mod once;
}
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 7d2a6862500..2321707afe3 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -275,7 +275,7 @@ fn copy_self_contained_objects(
.unwrap_or_else(|| {
panic!("Target {:?} does not have a \"wasi-root\" key", target.triple)
})
- .join("lib/wasm32-wasi");
+ .join("lib/wasm32-wasi-threads");
for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] {
copy_and_stamp(
builder,
@@ -377,7 +377,7 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
if target.ends_with("-wasi") {
if let Some(p) = builder.wasi_root(target) {
- let root = format!("native={}/lib/wasm32-wasi", p.to_str().unwrap());
+ let root = format!("native={}/lib/wasm32-wasi-threads", p.to_str().unwrap());
cargo.rustflag("-L").rustflag(&root);
}
} It must also be compiled with the [rust]
lld = true
[target.wasm32-wasi]
wasi-root = "/path/to/wasi-sysroot" # download from <https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sysroot-20.0.tar.gz> And with command: |
#494 is a draft of the plan highlighted here. Unfortunately, the two HTTP headers required for However, this means that smoldot needs to entirely run within the worker. This isn't really compatible with an API where you first start smoldot then call For this reason, I think that the API should change: instead of adding a
|
Another idea is to add a new field to |
About panics handling: First of all, the panic strategy has to be "abort". Unwinding requires the "exceptions handling" wasm proposal which, while it is implemented in browsers, is as far as I know not supported by Rust at the moment. When a thread panics, everything is left in place as it is. In other words, from a logical point of view a panic is similar to a call to Therefore, as long as the thread that panics doesn't call back into the Wasm, it's not possible to have any logic error caused by panicking. The panicking thread has all the time in the world to indicate to the other threads that they should abort. However, "aborting" is easier said than done. The main thread is fortunately guaranteed to never perform any blocking I/O operation (such as waiting), so we are sure that it can be aborted in one way or another. Workers have a The last possible issue I can see is a situation where the main thread is spin-looping waiting for another to do some atomic operation. However, nobody in their right might would actually implement spin-looping to wait for a long-lived mutex lock to be released. When a spin-loop is used, it is because another thread is performing a very short operation, and this very short operation is most likely provable to never panic. So all this explanation means that in principle the |
One other thing to remember (so many) is that at the moment locking a mutex is implemented using |
I've now closed #494 due to too many conflicts. As a summary of the changes to make in the future:
|
|
Looks like |
I'm going to close this, and opened #1128 instead for specifically the changes that would use It seems that we have three directions concerning the wasm: Using more than one thread for the wasm seems overkill to me right now. The fact that it's possible to have a frontend and a worker are IMO more than enough, and if it isn't then we should probably look into why. TL;DR: we want to migrate to |
paritytech/smoldot#1774
The text was updated successfully, but these errors were encountered: