From 669d159cef8584a077440779584e84d07e92894e Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Tue, 17 Oct 2023 17:59:38 -0700 Subject: [PATCH] Let the `"strict_asserts"` feature enable `Token::root` assertions. Perform run-time checks that only one root `Token` exists per thread when the `"strict_asserts"` feature is enabled, not only in debug builds. --- CHANGELOG.md | 2 +- wgpu-core/src/hub.rs | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e16759d4ee..75afd3d29d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -101,7 +101,6 @@ By @teoxoy in [#4185](https://github.com/gfx-rs/wgpu/pull/4185) - Add WinUI 3 SwapChainPanel support. By @ddrboxman in [#4191](https://github.com/gfx-rs/wgpu/pull/4191) ### Changes - #### General - Omit texture store bound checks since they are no-ops if out of bounds on all APIs. By @teoxoy in [#3975](https://github.com/gfx-rs/wgpu/pull/3975) @@ -117,6 +116,7 @@ By @teoxoy in [#4185](https://github.com/gfx-rs/wgpu/pull/4185) - Expose instance flags. By @nical in [4230](https://github.com/gfx-rs/wgpu/pull/4230) - Add support for the bgra8unorm-storage feature. By @jinleili and @nical in [#4228](https://github.com/gfx-rs/wgpu/pull/4228) - Calls to lost devices now return `DeviceError::Lost` instead of `DeviceError::Invalid`. By @bradwerth in [#4238]([https://github.com/gfx-rs/wgpu/pull/4238]) +- Let the `"strict_asserts"` feature enable check that wgpu-core's lock-ordering tokens are unique per thread. By @jimblandy in [#4258]([https://github.com/gfx-rs/wgpu/pull/4258]) #### Vulkan diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 0435a28607..6445a328ed 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -169,7 +169,9 @@ use crate::{ storage::{Element, Storage, StorageReport}, }; -#[cfg(debug_assertions)] +use wgt::{strict_assert_eq, strict_assert_ne}; + +#[cfg(any(debug_assertions, feature = "strict_asserts"))] use std::cell::Cell; use std::{fmt::Debug, marker::PhantomData}; @@ -281,7 +283,7 @@ impl Access> for RenderPipeline {} impl Access> for ComputePipeline {} impl Access> for Sampler {} -#[cfg(debug_assertions)] +#[cfg(any(debug_assertions, feature = "strict_asserts"))] thread_local! { /// Per-thread state checking `Token` creation in debug builds. /// @@ -320,10 +322,10 @@ impl<'a, T> Token<'a, T> { /// /// This should only be used by `Registry` locking methods. pub(crate) fn new() -> Self { - #[cfg(debug_assertions)] + #[cfg(any(debug_assertions, feature = "strict_asserts"))] ACTIVE_TOKEN.with(|active| { let old = active.get(); - assert_ne!(old, 0, "Root token was dropped"); + strict_assert_ne!(old, 0, "Root token was dropped"); active.set(old + 1); }); Self { level: PhantomData } @@ -336,9 +338,9 @@ impl Token<'static, Root> { /// Debug builds check dynamically that each thread has at most /// one root token at a time. pub fn root() -> Self { - #[cfg(debug_assertions)] + #[cfg(any(debug_assertions, feature = "strict_asserts"))] ACTIVE_TOKEN.with(|active| { - assert_eq!(0, active.replace(1), "Root token is already active"); + strict_assert_eq!(0, active.replace(1), "Root token is already active"); }); Self { level: PhantomData } @@ -347,7 +349,7 @@ impl Token<'static, Root> { impl<'a, T> Drop for Token<'a, T> { fn drop(&mut self) { - #[cfg(debug_assertions)] + #[cfg(any(debug_assertions, feature = "strict_asserts"))] ACTIVE_TOKEN.with(|active| { let old = active.get(); active.set(old - 1);