dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.28k stars 4.73k forks source link

[wasm][post-MVP] shared everything threads #96629

Open lambdageek opened 10 months ago

lambdageek commented 10 months ago

This issue tracks support for the WebAssembly post-MVP "shared everything threads" (aka thread spawn) proposal in .NET

See #94351 for a summary of other WebAssembly proposals and their status.

Proposal

Repo: https://github.com/WebAssembly/shared-everything-threads

Explainer or overview: https://github.com/WebAssembly/shared-everything-threads/blob/main/proposals/shared-everything-threads/Overview.md

.NET Scenarios and User Stories

Support multi-threaded .NET programs in web browsers

See https://github.com/dotnet/runtime/issues/85592

Support multi-threaded .NET programs on WASI hosts

As a C# developer targeting a WASI host, I would like to compile and run multi-threaded .NET programs.

Upstream dependencies: engines and toolchains

Required WebAssembly engine support

Expected .NET targets or supported configurations: Desktop browsers + Mobile browsers + Node + WASI

Engine Status
Chrome ?
Firefox ?
Safari ?
Node ?
wasmtime ?

Required WebAssembly toolchain support

We need LLVM to support this for AOT.


Opportunities and challenges

Shared-non-shared validation

Previously WebAssembly had a shared flag on linear memories, the proposal adds a shared flag on globals, functions, tables, etc. It also introduces a new restriction: shared functions (globals, tables) cannot access non-shared function (globals, tables, memories). As noted in the Overview, one approach that C toolchains may take is to mark everything as shared: https://github.com/WebAssembly/shared-everything-threads/blob/main/proposals/shared-everything-threads/Overview.md#how-will-toolchains-need-to-change

The jiterpreter will have to emit shared functions, too. It should be possible to take advantage of the new atomic table grow/get/set opcodes to populate the tables with jiterpreter-generated code.

Realm local shared globals and functions in JS

The proposal adds thread local shared globals (that can also be exported to JS as "realm local" shared globals. Additionally JS hosts will have a way to construct a shared function object that can be initialized differently in each realm.

We will likely need to take advantage of this for JS interop.

non-shared globals/functions/tables

Need to further investigate whether non-shared wasm constructs make sense for .NET (perhaps as an optimization for JS interop avoiding realm-local shared functions)

acquire-release memory model operations

The proposal adds relaxed memory model annotations to some atomic memory access operations. We should be able to take advantage of these in .NET intrinsics

thread spawn opcode

The proposal adds a thread spawn opcode. We will likely not use it directly (the spawned threads do not intrinsically have POSIX thread semantics), but together with the rest of the proposal there should be enough here for a WASI libc to implement something like POSIX thread semantics that .NET could use to bootstrap our own threads with the expected semantics.

Compatibility with WASI preview1+threads

WASI hosts implement WASI preview1 and the wasi-threads proposal as another mechanism for spawning threads. Depending on engine uptake (and user scenarios) we might have to support both options. That probably means compiling against a different libc and with different toolchain compiler flags. Likewise our own tools would need to take flags to specify if we want "shared everything" or "preview1+threads"

WasmGC

In some sense the point of this proposal is to add threading for WasmGC. Heap types also get a shared annotation. If we end up working on #94420 we would need to mark our heap types as shared.

ghost commented 10 months ago

Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.

Issue Details
This issue tracks support for the WebAssembly post-MVP "shared everything threads" (aka thread spawn) proposal in .NET See #94351 for a summary of other WebAssembly proposals and their status. ## Proposal Repo: https://github.com/WebAssembly/shared-everything-threads Explainer or overview: https://github.com/WebAssembly/shared-everything-threads/blob/main/proposals/shared-everything-threads/Overview.md ### .NET Scenarios and User Stories #### Support multi-threaded .NET programs in web browsers See https://github.com/dotnet/runtime/issues/85592 #### Support multi-threaded .NET programs on WASI hosts As a C# developer targeting a WASI host, I would like to compile and run multi-threaded .NET programs. ### Upstream dependencies: engines and toolchains #### Required WebAssembly engine support Expected .NET targets or supported configurations: Desktop browsers + Mobile browsers + Node + WASI | Engine | Status | |---------|--------| | Chrome | ? | | Firefox | ? | | Safari | ? | | Node | ? | | wasmtime| ? | #### Required WebAssembly toolchain support We need LLVM to support this for AOT. --- ### Opportunities and challenges #### Shared-non-shared validation Previously WebAssembly had a `shared` flag on linear memories, the proposal adds a `shared` flag on globals, functions, tables, etc. It also introduces a new restriction: shared functions (globals, tables) cannot access non-shared function (globals, tables, memories). As noted in the Overview, one approach that C toolchains may take is to mark everything as shared: https://github.com/WebAssembly/shared-everything-threads/blob/main/proposals/shared-everything-threads/Overview.md#how-will-toolchains-need-to-change The jiterpreter will have to emit shared functions, too. It should be possible to take advantage of the new atomic table grow/get/set opcodes to populate the tables with jiterpreter-generated code. #### Realm local shared globals and functions in JS The proposal adds thread local shared globals (that can also be exported to JS as "realm local" shared globals. Additionally JS hosts will have a way to construct a shared function object that can be initialized differently in each realm. We will likely need to take advantage of this for JS interop. #### non-shared globals/functions/tables Need to further investigate whether non-`shared` wasm constructs make sense for .NET (perhaps as an optimization for JS interop avoiding realm-local shared functions) #### acquire-release memory model operations The proposal adds relaxed memory model annotations to some atomic memory access operations. We should be able to take advantage of these in .NET intrinsics #### thread spawn opcode The proposal adds a thread spawn opcode. We will likely not use it directly (the spawned threads do not intrinsically have POSIX thread semantics), but together with the rest of the proposal there should be enough here for a WASI libc to implement something like POSIX thread semantics that .NET could use to bootstrap our own threads with the expected semantics.
Author: lambdageek
Assignees: -
Labels: `arch-wasm`, `needs-area-label`
Milestone: -
lambdageek commented 10 months ago

/cc @pavelsavara @kg