/// A guard that provides read access to snatchable data. pubstruct SnatchGuard<'a>(RwLockReadGuard<'a, ()>); /// A guard that allows snatching the snatchable data. pubstruct ExclusiveSnatchGuard<'a>(RwLockWriteGuard<'a, ()>);
/// A value that is mostly immutable but can be "snatched" if we need to destroy /// it early. /// /// In order to safely access the underlying data, the device's global snatchable /// lock must be taken. To guarantee it, methods take a read or write guard of that /// special lock. pubstruct Snatchable<T> {
value: UnsafeCell<Option<T>>,
}
/// Get read access to the value. Requires a the snatchable lock's read guard. pubfn get<'a>(&'a self, _guard: &'a SnatchGuard) -> Option<&'>a T> { unsafe { (*self.value.get()).as_ref() }
}
/// Take the value. Requires a the snatchable lock's write guard. pubfn snatch(&self, _guard: &mut ExclusiveSnatchGuard) -> Option<T> { unsafe { (*self.value.get()).take() }
}
/// Take the value without a guard. This can only be used with exclusive access /// to self, so it does not require locking. /// /// Typically useful in a drop implementation. pubfn take(&mutself) -> Option<T> { self.value.get_mut().take()
}
}
// Can't safely print the contents of a snatchable object without holding // the lock. impl<T> std::fmt::Debug for Snatchable<T> { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "<snatchable>")
}
}
iflet Some(prev) = SNATCH_LOCK_TRACE.take() { let current = thread::current(); let name = current.name().unwrap_or("<unnamed>");
panic!( "thread '{name}' attempted to acquire a snatch lock recursively.\n\
- Currently trying to acquire {new}\n\
- Previously acquired {prev}",
);
} else {
SNATCH_LOCK_TRACE.set(Some(new));
}
}
/// A Device-global lock for all snatchable data. pubstruct SnatchLock {
lock: RwLock<()>,
}
impl SnatchLock { /// The safety of `Snatchable::get` and `Snatchable::snatch` rely on their using of the /// right SnatchLock (the one associated to the same device). This method is unsafe /// to force force sers to think twice about creating a SnatchLock. The only place this /// method should be called is when creating the device. pubunsafefn new(rank: rank::LockRank) -> Self {
SnatchLock {
lock: RwLock::new(rank, ()),
}
}
/// Request write access to snatchable resources. /// /// This should only be called when a resource needs to be snatched. This has /// a high risk of causing lock contention if called concurrently with other /// wgpu work. #[track_caller] pubfn write(&self) -> ExclusiveSnatchGuard {
LockTrace::enter("write");
ExclusiveSnatchGuard(self.lock.write())
}
}
impl Drop for SnatchGuard<'_> { fn drop(&mutself) {
LockTrace::exit();
}
}
impl Drop for ExclusiveSnatchGuard<'_> { fn drop(&mutself) {
LockTrace::exit();
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.