browser_wasi_shim icon indicating copy to clipboard operation
browser_wasi_shim copied to clipboard

Does this support threads?

Open temeddix opened this issue 1 year ago • 6 comments

Hi, thanks for this wonderful effort :)

I'm very interested in running thread code from WASI .wasm file on the browser. Is it possible right now? If not, can I make a PR for that using web workers?

temeddix avatar Oct 25 '23 12:10 temeddix

Threads are not yet supported. I do want to support them, but I don't think it will be a trivial change. webworkers don't allow sharing javascript objects, so directly sharing the Fd list between all threads is not possible. Instead some way of keeping them on a single thread and then doing message passing whenever another thread wants to call a method on it will be necessary. The standard message passing way for webworkers is asynchronous and webassembly is fully synchronous, so using that method won't be possible afaik. Instead I think it will be necessary to manually implement a message queue on top of SharedArrayBuffer which can block threads using Atomics.wait/Atomics.notify. See also https://github.com/bjorn3/browser_wasi_shim/issues/14.

bjorn3 avatar Oct 25 '23 12:10 bjorn3

Yeah, I am aware that message passing is crucial between web workers to send messages in JS. However in native languages like Rust, you can simply share native channels inside WebAssembly.Memory and communicate using them. IMO, All we have to do is to ensure that all the new web workers share the same WebAssembly.Memory and provide some spawn mechanism for native functions with SharedArrayBuffer.

I think we should guide the users about only two things:

  1. Provide the WebAssembly.Memory that this shim library will use, when instantiating wasm with this shim(Perhaps this can be automatically done).
  2. Be sure to set the proper cross-origin related headers when using the thread feature.

I have experience with web workers and SharedArrayBuffer from Rinf and async_wasm_task (I'm the maintainer). I'm also very familiar with typescript. May I work on this idea and create a PR, if acceptable?

temeddix avatar Oct 25 '23 13:10 temeddix

I'll leave the relevant links

  • https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Memory
  • https://github.com/wasm-rs/shared-channel/blob/master/src/lib.rs

temeddix avatar Oct 25 '23 13:10 temeddix

Provide the WebAssembly.Memory that this shim library will use, when instantiating wasm with this shim(Perhaps this can be automatically done).

There are two shared memories that are necessary. One shared between the wasm instances for each thread and one for the message passing. browser_wasi_shim can't use the shared memory used by wasm for message passing as that would likely cause corruption for the wasm module if it thinks it can write to memory while at the same time browser_wasi_shim is using it for the message passing.

I think it would be possible to have a method on WASI (Or maybe we should have a separate SharedWASI) which returns an Object containing all necessary SharedArrayBuffer and Webassembly.Memory instances which can be passed to postMessage and on the other side can be turned back into a WASI (or SharedWASI) instance. Or alternatively we could have browser_wasi_shim ship with a webworker which is used for all thread spawning attempts and handles all this passing behind the scenes. This would be less flexible though.

May I work on this idea and create a PR, if acceptable?

Absolutely!

bjorn3 avatar Oct 25 '23 14:10 bjorn3