From dd324027af0bd6c030e9ad7cbd2c45ffc0bd8dd0 Mon Sep 17 00:00:00 2001 From: Kai Ninomiya Date: Fri, 20 Dec 2024 18:32:16 -0800 Subject: [PATCH 1/5] Docs: multithreading support in wasm Starts the Multithreading article but doesn't add anything about thread safety yet. Issue: 248 --- doc/articles/Asynchronous Operations.md | 4 ++++ doc/articles/Multithreading.md | 30 +++++++++++++++++++++++++ doc/articles/index.md | 1 + 3 files changed, 35 insertions(+) create mode 100644 doc/articles/Multithreading.md diff --git a/doc/articles/Asynchronous Operations.md b/doc/articles/Asynchronous Operations.md index 570caf31..823397e5 100644 --- a/doc/articles/Asynchronous Operations.md +++ b/doc/articles/Asynchronous Operations.md @@ -69,3 +69,7 @@ Device events are slightly different in that their callback info (`WGPUDeviceLos The `WGPUUncapturedErrorCallbackInfo` _does not_ have a callback mode member. It is always as-if it were @ref WGPUCallbackMode_AllowSpontaneous. Note also that the uncaptured error callback is a _repeating_ callback that fires multiple times, unlike other callbacks in webgpu.h. The uncaptured error callback is guaranteed not to fire after the device becomes lost. When the device is lost, it is an appropriate time for the application to free userdata variables for the uncaptured error callback. Note that the device becomes lost _before_ the actual device lost callback fires. First the device state transitions to lost, then the device lost callback fires. The timing of the callback depends on the device lost callback mode. + +## Callback Reentrancy {#CallbackReentrancy} + +TODO diff --git a/doc/articles/Multithreading.md b/doc/articles/Multithreading.md new file mode 100644 index 00000000..ff6244e3 --- /dev/null +++ b/doc/articles/Multithreading.md @@ -0,0 +1,30 @@ +# Multithreading {#Multithreading} + +`webgpu.h` implementations are allowed to require that all returned objects, except for `WGPUInstance`, can only be used from the thread they were created on, causing undefined behavior otherwise. + +Where multithreading is supported: + +- The implementation must provide the documented @ref ThreadSafety guarantees. +- All objects must be freely usable on any thread at any time. +- State must be thread-global, except where otherwise defined. + - For example, buffer map state is thread-global, and mapped memory ranges may be used from any thread. + - Note: Error scope state is thread-local. See @ref ErrorScopes. + +Native (non-Wasm) implementations **should** support multithreading. + +## In WebAssembly + +At the time of this writing, the JS WebGPU API is not multithreading-capable. +Initial `webgpu.h` implementations will not be multithreading-capable. + +Wasm-on-JS implementations *may* implement multithreading by proxying calls to a single JS "thread", as long as the C API behavior is conformant. + +Once the JS API is multithreading-capable, there are still expected to be some thread-local behaviors (such as buffer mapping state being thread-local). These limitations may still be exposed, but multithreading-capable Wasm-on-JS implementations may also avoid exposing them where feasible (e.g. by proxying all mapping calls to a single JS thread). + +## Thread Safety {#ThreadSafety} + +TODO + +### Callback Reentrancy + +See @ref CallbackReentrancy. diff --git a/doc/articles/index.md b/doc/articles/index.md index d15af669..2e646d5d 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -7,3 +7,4 @@ - \subpage SentinelValues - \subpage Strings - \subpage StructChaining +- \subpage Multithreading From 466f223485c0c9a1f9719c9cca0dc03c3f60fe09 Mon Sep 17 00:00:00 2001 From: Kai Ninomiya Date: Fri, 20 Dec 2024 21:22:22 -0800 Subject: [PATCH 2/5] oh also say things about encoders --- doc/articles/Multithreading.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/articles/Multithreading.md b/doc/articles/Multithreading.md index ff6244e3..7aebb48e 100644 --- a/doc/articles/Multithreading.md +++ b/doc/articles/Multithreading.md @@ -5,7 +5,9 @@ Where multithreading is supported: - The implementation must provide the documented @ref ThreadSafety guarantees. -- All objects must be freely usable on any thread at any time. +- All objects must be freely usable on any thread at any time, except: + - Where APIs are specified as being non-thread-safe, they must mutexed. + - The exceptions for Wasm, below. - State must be thread-global, except where otherwise defined. - For example, buffer map state is thread-global, and mapped memory ranges may be used from any thread. - Note: Error scope state is thread-local. See @ref ErrorScopes. @@ -19,7 +21,12 @@ Initial `webgpu.h` implementations will not be multithreading-capable. Wasm-on-JS implementations *may* implement multithreading by proxying calls to a single JS "thread", as long as the C API behavior is conformant. -Once the JS API is multithreading-capable, there are still expected to be some thread-local behaviors (such as buffer mapping state being thread-local). These limitations may still be exposed, but multithreading-capable Wasm-on-JS implementations may also avoid exposing them where feasible (e.g. by proxying all mapping calls to a single JS thread). +Once the JS API is multithreading-capable, there are still expected to be some thread-local behaviors: + +- Buffer mapping state may be thread-local. + - Implementations *should* make this state thread-global if feasible (e.g. by proxying all mapping calls to a single JS thread). +- Any object which is not thread-shareable in JS may not be thread-shareable in Wasm (e.g. encoder objects may not be thread-shareable, similar to how they are not thread safe in `webgpu.h` in general). + - Implementations *may* make them thread-global but this is not expected to be performant. ## Thread Safety {#ThreadSafety} From 9b7ec5417e8c87ab780218c6382b536cd4ee33bc Mon Sep 17 00:00:00 2001 From: Kai Ninomiya Date: Fri, 20 Dec 2024 22:27:22 -0800 Subject: [PATCH 3/5] more stuff about encoders --- doc/articles/Multithreading.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/articles/Multithreading.md b/doc/articles/Multithreading.md index 7aebb48e..1ece2343 100644 --- a/doc/articles/Multithreading.md +++ b/doc/articles/Multithreading.md @@ -25,8 +25,8 @@ Once the JS API is multithreading-capable, there are still expected to be some t - Buffer mapping state may be thread-local. - Implementations *should* make this state thread-global if feasible (e.g. by proxying all mapping calls to a single JS thread). -- Any object which is not thread-shareable in JS may not be thread-shareable in Wasm (e.g. encoder objects may not be thread-shareable, similar to how they are not thread safe in `webgpu.h` in general). - - Implementations *may* make them thread-global but this is not expected to be performant. +- Any object which is non-shareable or non-transferable in JS may also be fully or partially non-shareable or non-transferable in Wasm (e.g. encoder objects may be thread-locked, similar to how they are not thread safe in `webgpu.h` in general). (In Rust terms, shareable = `Send`+`Sync`, transferable = `Send`.) + - Implementations *may* make them shareable. (For example, proxying all encoder methods to a single thread would make them fully shareable but be inefficient; alternatively, encoder commands can be buffered, which might enable some multithreaded use-cases even if `Finish()` still must happen on the thread that created the encoder.) ## Thread Safety {#ThreadSafety} From 3d75059052082047cf4adc453a3bf4261c1dca07 Mon Sep 17 00:00:00 2001 From: Kai Ninomiya Date: Fri, 20 Dec 2024 22:30:43 -0800 Subject: [PATCH 4/5] Add thread safety docs --- doc/articles/Multithreading.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/articles/Multithreading.md b/doc/articles/Multithreading.md index 1ece2343..b342a29e 100644 --- a/doc/articles/Multithreading.md +++ b/doc/articles/Multithreading.md @@ -30,8 +30,14 @@ Once the JS API is multithreading-capable, there are still expected to be some t ## Thread Safety {#ThreadSafety} -TODO +The `webgpu.h` API is thread-safe (when multithreading is supported). That is, its functions are reentrant and may be called during the execution of other functions, with the following exceptions: -### Callback Reentrancy +- Encoder objects (@ref WGPUCommandEncoder, @ref WGPUComputePassEncoder, @ref WGPURenderPassEncoder, and @ref WGPURenderBundleEncoder) are not thread-safe. Note these objects appear only in their own methods. + - Additionally, in Wasm, note these objects may be thread-locked as discussed above. +- API calls may not be made during @ref WGPUCallbackMode_AllowSpontaneous callbacks. See @ref CallbackReentrancy. -See @ref CallbackReentrancy. +The following _are_ thread safe: + +- @ref wgpuInstanceWaitAny() and @ref wgpuInstanceProcessEvents +- @ref wgpuDeviceDestroy() +- @ref wgpuBufferDestroy(), @ref wgpuTextureDestroy(), and @ref wgpuQuerySetDestroy() From f1b2a5cb0f8c1e5ebb650aaf9e00ee24a39296f7 Mon Sep 17 00:00:00 2001 From: Kai Ninomiya Date: Fri, 3 Jan 2025 22:40:24 -0800 Subject: [PATCH 5/5] address comments --- doc/articles/Multithreading.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/articles/Multithreading.md b/doc/articles/Multithreading.md index b342a29e..cedd297f 100644 --- a/doc/articles/Multithreading.md +++ b/doc/articles/Multithreading.md @@ -7,14 +7,14 @@ Where multithreading is supported: - The implementation must provide the documented @ref ThreadSafety guarantees. - All objects must be freely usable on any thread at any time, except: - Where APIs are specified as being non-thread-safe, they must mutexed. - - The exceptions for Wasm, below. + - The exceptions for Wasm, below: @ref MultithreadingInWasm. - State must be thread-global, except where otherwise defined. - For example, buffer map state is thread-global, and mapped memory ranges may be used from any thread. - Note: Error scope state is thread-local. See @ref ErrorScopes. Native (non-Wasm) implementations **should** support multithreading. -## In WebAssembly +## Multithreading In WebAssembly {#MultithreadingInWasm} At the time of this writing, the JS WebGPU API is not multithreading-capable. Initial `webgpu.h` implementations will not be multithreading-capable. @@ -33,7 +33,7 @@ Once the JS API is multithreading-capable, there are still expected to be some t The `webgpu.h` API is thread-safe (when multithreading is supported). That is, its functions are reentrant and may be called during the execution of other functions, with the following exceptions: - Encoder objects (@ref WGPUCommandEncoder, @ref WGPUComputePassEncoder, @ref WGPURenderPassEncoder, and @ref WGPURenderBundleEncoder) are not thread-safe. Note these objects appear only in their own methods. - - Additionally, in Wasm, note these objects may be thread-locked as discussed above. + - Additionally, in Wasm, these objects may be thread-locked, as discussed above. - API calls may not be made during @ref WGPUCallbackMode_AllowSpontaneous callbacks. See @ref CallbackReentrancy. The following _are_ thread safe: