I've recently learned that the wasm32-unknown-emscripten target doesn't (yet) support threads. Since Emscripten as a platform does support threads, I thought I might start to poke around rustc to see what it might take to it working. But I could use a hint or two to a good starting point to dive in. I'm not sure if this would be something that would have most of the effort on the rustc side of things, or if there would be something needed on the LLVM side.
Here is a brief overview of where I've started so far. I cloned the rust git, ran the x.py build script as a shakeout, and it built without issue. Then I went and haphazardly changed the file:
rust/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
..adding a line to the TargetOptions
to include "singlethread: false" (see here),
to override the option set in wasm_base.rs, just to see what might happen.
// Wasm doesn't have atomics yet, so tell LLVM that we're in a single
// threaded model which will legalize atomics to normal operations.
singlethread: true,
That comment about atomics is interesting, since I need to have rustflags set to include "target-feature=+atomics,+bulk-memory" in order to get the target program to get as far as it does in the compilation process.
I then built the compiler again with the x.py script, and (unfortunately?) it built without problems. An error might have given something to look at next. So then I tried to see if the setting change "took" by invoking:
rustc -Z unstable-options --target=wasm32-unknown-emscripten --print target-spec-json
...using the new executable that ended up in my:
rust/build/x86_64-unknown-linux-gnu/stage1/bin
...directory. Now the "singlethread:" option is missing from the report, which I take as a good sign.
Anyway, when then trying use the new compiler to build a simple threaded program, I get link errors about thread local storage (same as with the stock compiler) with wasm-ld
complaining about:
relocation R_WASM_MEMORY_ADDR_TLS_SLEB cannot be used against non-TLS symbol 'std::io::stdio::OUTPUT_CAPTURE::__getit::__KEY::h776cf75763f0fad1
...etc.. "wasm-base" has a section in TargetOptions
:
// When the atomics feature is activated then these two keys matter,
// otherwise they're basically ignored by the standard library. In this
// mode, however, the `#[thread_local]` attribute works (i.e.
// `has_elf_tls`) and we need to get it to work by specifying
// `local-exec` as that's all that's implemented in LLVM today for wasm.
has_elf_tls: true,
tls_model: TlsModel::LocalExec,
...which doesn't strike me as obviously incorrect. There is more information about the linker problem described here.. If you have any advice as to documentation to read, or pointers of where to start looking next, or a better forum or list to post to, I'd appreciate it.
Thanks!