Skip to content

Centralize locking primitives in wgpu-types#9780

Open
bushrat011899 wants to merge 5 commits into
gfx-rs:trunkfrom
bushrat011899:wgpu_types_lock_api
Open

Centralize locking primitives in wgpu-types#9780
bushrat011899 wants to merge 5 commits into
gfx-rs:trunkfrom
bushrat011899:wgpu_types_lock_api

Conversation

@bushrat011899

@bushrat011899 bushrat011899 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Connections

Description

Across wgpu's various crates there is a need for locking primitives, such as Mutex and RwLock. Currently, each crate independently imports from either std, parking_lot, or potentially uses a RefCell-based fallback for no_std compatibility. This leads to duplicated implementations of the fallback logic. This PR centralizes these Mutex and RwLock definitions into wgpu-types, allowing them to be re-used across Wgpu.

parking_lot is not available as a no_std dependency and likely never will be. Based on this feedback, wgpu-types will include parking_lot when std is enabled, so the primitives in std::sync are never used. This is done to avoid adding more features unnecessarily, since parking_lot is supported on all platforms that provide std anyway.

To allow for potentially better performance and platform compatibility in no_std configurations, spin has been added to wgpu-types as an optional dependency, and it is used as the backing implementation for locking primitives when parking_lot is unavailable.

The fallback uses atomics. This allows for Sync support in no_std even when spin is not enabled for modern platforms (e.g., x86_64-unknown-none). Currently, wgpu-types does not support no-atomic platforms such as thumbv4t-none-eabi due to several existing dependencies. I've explicitly left compile_error messages in wgpu-types to give an informed error to end users if that situation ever changes.

Note that while lock_api and spin are added as dependencies to wgpu-types, they were already present in the lockfile. lock_api is unconditionally included as parking_lot already unconditionally included it in wgpu-core, and it is no_std compatible.

Testing

CI

Squash or Rebase?

Rebase, all commits are atomic.

Checklist

  • I self-reviewed and fully understand this PR.
    • No AI tooling of any kind was used during the creation of this PR.
  • WebGPU implementations built with wgpu may be affected behaviorally.
  • Validation and feature gates are in place to confine behavioral changes.
  • Tests demonstrate the validation and altered logic works.
  • CHANGELOG.md entries for the user-facing effects of this change are present.
  • The PR is minimal, and doesn't make sense to land as multiple PRs.
    • Each commit could be its own PR, and I'm happy to split it up. I've opened it as one large PR to give the best context for where and how wgpu_types::sync is intended to be used.
  • Commits are logically scoped and individually reviewable.
  • The PR description has enough context to understand the motivation and solution implemented.

@bushrat011899 bushrat011899 force-pushed the wgpu_types_lock_api branch 2 times, most recently from 6c357f7 to bc3ccdd Compare July 1, 2026 08:30

@bushrat011899 bushrat011899 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments to assist review.

Comment thread tests/Cargo.toml
futures-lite.workspace = true
libtest-mimic.workspace = true
log.workspace = true
parking_lot = { workspace = true, features = ["deadlock_detection"] }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency was previously included in triplicate for wasm, not wasm, and for tests. Moved for the sake of clarity.

Comment thread tests/src/native.rs
#[doc(hidden)]
pub static TEST_LIST: Mutex<Vec<crate::GpuTestConfiguration>> = Mutex::new(Vec::new());
pub static TEST_LIST: Mutex<Vec<crate::GpuTestConfiguration>> =
Mutex::const_new(wgpu_types::sync::RawMutex::new(), Vec::new());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lock_api only made Mutex::new const in the current version, but it seems unnecessary to mandate a higher version when we only need to use this API in a couple of locations.

Comment thread wgpu-hal/Cargo.toml
metal = [
# Metal is only available on Apple platforms, therefore request MSL output also only if we target an Apple platform.
"naga/msl-out",
"wgpu-types/std",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metal requires the use of Condvar, which is only available with exactly the lock types in parking_lot. Since Metal is only available on Apple platforms which already have std I don't think this is worth litigating too heavily.

Comment thread wgpu/Cargo.toml
Comment on lines +196 to +197
# FIXME: This can probably be removed as a feature and directly controlled by `std`
parking_lot = ["wgpu-types/std"]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would need a version bump to remove this feature, but I think it should be, since it's entirely redundant.

Comment thread wgpu/src/util/mod.rs
mod device;
mod encoder;
mod init;
mod mutex;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation here can just be entirely removed, wgpu-types provides an API compatible alternative so no need to duplicate effort.

Comment thread wgpu-types/src/sync.rs
type RawMutexInner = core::sync::atomic::AtomicBool;
type RawRwLockInner = core::sync::atomic::AtomicUsize;
} else {
compile_error!("wgpu-types does not support platforms without atomics");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

foldhash and lock_api are both incompatible with no-atomic targets, so there's no way to test a no-atomic implementation here anyway, so might as well leave an informative compiler error.

@bushrat011899 bushrat011899 force-pushed the wgpu_types_lock_api branch 2 times, most recently from f5e73b4 to ebf9a47 Compare July 1, 2026 09:59
Exposes `Mutex` and `RwLock` types which either use `parking_lot`, `spin`, or `RefCell` based on the `std` and `spin` features. This uses `lock_api` to provide a consistent interface regardless of the enabled features.
Comment thread wgpu-types/Cargo.toml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wgpu-types is a library whose purposes include being usable as a dependency by other packages to be able to use wgpu vocabulary without depending on building the actual wgpu implementation. Adding dependencies on parking_lot | spin means that those libraries will need to be compiled before wgpu-types is, possibly putting them on the critical path. It also means that they will be compiled even if the current build might not even need wgpu locking at all.

Therefore, it seems desirable to split this out to a separate package from wgpu-types.

On the other hand, perhaps this concern is insignificant. I just took a look at my CI timings and wgpu-types v29 currently takes about 4× as long to compile as parking_lot + parking_lot_core.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think the impact to compile times should be overall pretty minimal. A new wgpu-sync (bikeshed name) could make sense, but if a locking primitive is ever used in the public interface of a type then wgpu-types would need to depend on wgpu-sync anyway.

I'm also wagering that by using lock_api to provide high level abstractions like mapped guards, the actual usage of parking_lot can be entirely optional, so even though it's required earlier in the graph, it's more able to be pruned out entirely. So far, only Metal really needs it, and even then, only for Condvar in one place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants