Centralize locking primitives in wgpu-types#9780
Conversation
6c357f7 to
bc3ccdd
Compare
bushrat011899
left a comment
There was a problem hiding this comment.
Some comments to assist review.
| futures-lite.workspace = true | ||
| libtest-mimic.workspace = true | ||
| log.workspace = true | ||
| parking_lot = { workspace = true, features = ["deadlock_detection"] } |
There was a problem hiding this comment.
This dependency was previously included in triplicate for wasm, not wasm, and for tests. Moved for the sake of clarity.
| #[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()); |
There was a problem hiding this comment.
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.
| 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", |
There was a problem hiding this comment.
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.
| # FIXME: This can probably be removed as a feature and directly controlled by `std` | ||
| parking_lot = ["wgpu-types/std"] |
There was a problem hiding this comment.
Would need a version bump to remove this feature, but I think it should be, since it's entirely redundant.
| mod device; | ||
| mod encoder; | ||
| mod init; | ||
| mod mutex; |
There was a problem hiding this comment.
The implementation here can just be entirely removed, wgpu-types provides an API compatible alternative so no need to duplicate effort.
| type RawMutexInner = core::sync::atomic::AtomicBool; | ||
| type RawRwLockInner = core::sync::atomic::AtomicUsize; | ||
| } else { | ||
| compile_error!("wgpu-types does not support platforms without atomics"); |
There was a problem hiding this comment.
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.
f5e73b4 to
ebf9a47
Compare
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.
ebf9a47 to
9c84405
Compare
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
Connections
MutexandRwLock#7830Description
Across wgpu's various crates there is a need for locking primitives, such as
MutexandRwLock. Currently, each crate independently imports from eitherstd,parking_lot, or potentially uses aRefCell-based fallback forno_stdcompatibility. This leads to duplicated implementations of the fallback logic. This PR centralizes theseMutexandRwLockdefinitions intowgpu-types, allowing them to be re-used across Wgpu.parking_lotis not available as ano_stddependency and likely never will be. Based on this feedback,wgpu-typeswill includeparking_lotwhenstdis enabled, so the primitives instd::syncare never used. This is done to avoid adding more features unnecessarily, sinceparking_lotis supported on all platforms that providestdanyway.To allow for potentially better performance and platform compatibility in
no_stdconfigurations,spinhas been added towgpu-typesas an optional dependency, and it is used as the backing implementation for locking primitives whenparking_lotis unavailable.The fallback uses atomics. This allows for
Syncsupport inno_stdeven whenspinis not enabled for modern platforms (e.g.,x86_64-unknown-none). Currently,wgpu-typesdoes not support no-atomic platforms such asthumbv4t-none-eabidue to several existing dependencies. I've explicitly leftcompile_errormessages inwgpu-typesto give an informed error to end users if that situation ever changes.Note that while
lock_apiandspinare added as dependencies towgpu-types, they were already present in the lockfile.lock_apiis unconditionally included asparking_lotalready unconditionally included it inwgpu-core, and it isno_stdcompatible.Testing
CI
Squash or Rebase?
Rebase, all commits are atomic.
Checklist
wgpumay be affected behaviorally.CHANGELOG.mdentries for the user-facing effects of this change are present.wgpu_types::syncis intended to be used.