Skip to content
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

Updating LLD to use bulk memory for threads #1631

Closed
tlively opened this issue Jun 27, 2019 · 6 comments · Fixed by #1675
Closed

Updating LLD to use bulk memory for threads #1631

tlively opened this issue Jun 27, 2019 · 6 comments · Fixed by #1675

Comments

@tlively
Copy link

tlively commented Jun 27, 2019

In the near future I plan to update LLD to emit passive segments when a shared memory is requested. This will prevent memory from being reinitialized every time a thread is spawned. Currently toolchains need to do something like separate the contents of memory into a separate file and manually initialize memory on the main thread. With this update to LLD, the linker will synthesize a function called __wasm_init_memory. This function will automatically be called at the beginning of __wasm_call_ctors, but @fitzgen reminded me that Rust does not have any global constructors, so you will probably be able to call __wasm_init_memory directly.

The existing memory separation code will probably break since the data segments will no longer declare their own offsets, so I just wanted to give a heads up that this change is coming. It also means that enabling shared memory in Firefox will be insufficient to test multithreaded modules, which may affect your workflow or testing. I filed a Firefox bug about this at https://bugzilla.mozilla.org/show_bug.cgi?id=1561747.

I will update this issue once the change has landed upstream in LLD and when I update the tool-conventions repo with details about this arrangement.

@fitzgen
Copy link
Member

fitzgen commented Jun 27, 2019

Thanks for the heads up @tlively!

cc @alexcrichton

@alexcrichton
Copy link
Contributor

Indeed thanks for the heads up! It'll take a bit for LLD changes to get into rust-lang/rust since we need to update the LLVM compiler in rust-lang/rust before it reaches nightlies or here, so we've definitely got some good runway.

BTW in case you aren't aware @tlively this is actually something that we all handle today in the wasm-bindgen-threads-xform crate internally, and you can see an example of this running online at - https://rustwasm.github.io/wasm-bindgen/exbuild/raytrace-parallel/. We do exactly what you're changing LLD to do which is to switch all memory segments to passive and then manually initialize them.

We don't currently have __wasm_call_ctors it's true (although in theory Rust code could link to C++ and it would show up), but we can definitely arrange our transformation pass to ensure that __wasm_call_ctors or __wasm_init_memory is hooked up to only happen once on the main thread.

In any case once this lands in LLD I'll start working on the update to rust-lang/rust, and in that process I'll make sure we update the passes here to be compatible with it!

@tlively
Copy link
Author

tlively commented Jul 19, 2019

This change to LLD is complete, and although I just landed the last patch today, it should be backported and available on the LLVM 9.0 release branch. The behavior of the linker is documented in the tool conventions. Passive segments will be emitted by default when you pass --shared-memory and all you'll have to do is call __wasm_init_memory from your runtime before anything else happens.

@alexcrichton
Copy link
Contributor

Thanks for the heads up! Our LLVM 9 upgrade recently landed and I'm working on getting the threading support back up and running with this. I'll make sure to include support for --passive-segments as well!

@alexcrichton
Copy link
Contributor

@tlively on issue I've found I opened up on the tool conventions repo WebAssembly/tool-conventions#117, but otherwise looks like everything is working out great

@alexcrichton
Copy link
Contributor

@tlively it's probably also worth mentioning, if y'all have discussions for the general architecture of threaded wasm I wrote up a post awhile back about our experience along with gotchas and some problems to solve, so if it'd help I could help work through some issues as well!

alexcrichton added a commit to alexcrichton/wasm-bindgen that referenced this issue Jul 19, 2019
In LLVM 9 LLD has been updated to emit shared memory and passive
segments by default for threaded code, and `__wasm_init_memory` is a
function exported used to initialize memory. Update our
transform/runtime here to hook up all those wires correctly.

Closes rustwasm#1631
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants