Open
Description
This is a tracking issue for adding experimental support for WebAssembly multi-threading to the browser-wasm runtime pack.
High Level Goals
The threading runtime should be distributed in the same browser-wasm runtime packThe threading runtime is in a separate.multithread.
runtime pack variant. The WASM SDK chooses the correct runtime pack variant based on project properties.- Threading should be opt-in only
- The wasm bindings and runtime are thread-safe and co-op GC aware
Completed in .NET 7 RC2
The wasm-experimental
workload supports threading using <WasmEnableThreads>true</WasmEnableThreads>
in interp and AOT configurations when using the wasmbrowser
workload. Blazor does not support threading in .NET 7
Tracking
SDK:
- Support wasm variants in NuGet packages #76959
- The browser-wasm SDK should automatically reference the threading/perf-tracing ref assemblies #72872
- Properties/targets to generate and consume AOT profiles
- Properties/targets to create and run EP instrumented apps with
dotnet-counters
/dotnet-trace
(viadotnet-dsrouter
)
CI testing:
- Need a way to skip tests on single threaded / multi-threaded wasm configs.
- Add tests. (src/libraries). Maybe add some convenient way to add
ProjectReference
s to the multi-threaded ref assemblies (the roll-upMicrosoft.NET.WebAssembly.Threading.proj
doesn't seem to work) and run the normal runtime tests.
Libraries and Interop:
- JS interop should support threading #76956
- [browser][MT] Multithreading and JavaScript async interop in .NET 9 #85592
- [browser][mt] Propagate unhandled JS errors in JSWebWorker to the top level Task #76957
- [browser][mt] Do not allow blocking on the thread with JS interop: UI, JSWebWorker #76958
- Consider making System.Threading.Thread.IsThreadStartSupported public #77541
- Blazor needs to provide
dotnet.worker.js
as ajs-module-threads
asset (fixed by [browser] Enable threads in Wasm SDK #85109)
Runtime and codegen:
- [browser][MT] JS Interop should respect GC pauses #76963
- AOT: tell LLVM that it's ok to use atomics if threading is enabled
Issues:
- [wasm-mt] Improved experience when SharedArrayBuffer is not available #76961
- Real multithreading in Blazor WebAssembly aspnetcore#17730
- No platform compatability analyzer warnings in Razor @code sections razor#7250
- The
Microsoft.AspNetCore.Components.WebAssembly.DevServer
(used by blazorwasm fordotnet run
) should serve CORS headers - Blazor should use the GC-safe API for accessing the render tree from JS
- cleanup the Node polyfill in
dotnet.worker.js
that useseval
andrequire
[wasm] proper startup sequence indotnet.worker.js
#70891 - [browser][MT] Switch to multi-threaded Emscripten VFS when it is available #76964
- [wasm-mt] Option to package threaded runtime as CommonJS #76962
- [browser][mt] Upgrade emscripten #75625
- [browser][mt] Provide API to start the web workers later #75629
-
Kind of resolved - we use Emscripten's ability to pre-allocate some workers before the app starts creating threads.Thread.Start().Wait
pattern on the browser threads will deadlock. Emscripten relies on the browser thread's eventloop to start threads (unless we use a dedicated "main" thread when building). After a thread start, the browser thread's eventloop must run in order for new threads to start.
Done
On the branch:
- put all modifications under conditionals
- The runtime build should be under
/p:WasmEnableThreads=true
- ref assemblies should use
FeatureWasmThreads
in project files andFEATURE_WASM_THREADS
in C# code to conditionally include[UnsupportedOSPlatform("browser")]
guards around multi-threading APIs, and include the ref assembly inMicrosoft.NET.WebAssembly.Threading
- CoreLib uses
FeatureWasmThreads
andFEATURE_WASM_THREADS
to defineSystem.Thread.IsThreadStartSupported
. All other code should checkSystem.Thread.IsThreadStartSupported
to throw a PNSE. There should not be[UnsupportedOSPlatform("browser")]
guards in CoreLib - EventPipe and diagnostics should use
FeatureWasmPerfTracing
andFEATURE_WASM_PERFTRACING
(and a constant?).
- The runtime build should be under
- Add separate
browser-mt
andbrowser-mt-eventpipe
samples. - Land the branch changes in
main
In .NET 7 RC2
-
Build and package:
- [wasm-mt] place multi-threaded wasm build into separate artifacts folders #68506 Completed as part of Add support for building WASM variants alongside single-threaded to the build system #71054
- [wasm-mt] The
browser-wasm
runtime pack should pack both single- and multi-threaded builds. #68508 completed as part of Add support for building WASM variants alongside single-threaded to the build system #71054 - The
Microsoft.NET.WebAssembly.Threading.nupkg
ref assemblies package should be published to the dotnet7 feed
-
Libraries and interop:
- [wasm-mt] Add a System.Runtime.InteropServices.JavaScript.BrowserSynchronizationContext #69409
-
Need a hook for frameworks to identify the location ofWe set up an asset loading framework that handles these use cases [wasm] asset loading for workers #73484dotnet.js
. Emscripten relies onmainScriptUrlOrBlob
property on the module on the main threads to be set to the URL ofdotnet.js
so that it can locatedotnet.worker.js
. Frameworks like Blazor sometimes renamedotnet.js
and/or move the wasm artifacts into subdirectories. Provide a hook for them to tell the runtime where to find the files.
-
AOT
- [Wasm] AOT support for threading-enabled runtime #70489
- AOT compiler task: add an option to control safepoint generation (wrap
MONO_THREADS_SUSPEND=coop
mono-aot-cross environment setting) [mono][wasm] Add a 'wasm-gc-safepoints' option to enable the generati… #70520 - emit safepoints if threading is enabled. (we want one
mono-aot-cross
that doesn't emit safepoints for single-threaded wasm, but does emit safepoints for mt) [mono][wasm] Add a 'wasm-gc-safepoints' option to enable the generati… #70520
-
CI testing:
In .NET 8
...