gpu_alloc/
util.rs

1use alloc::sync::Arc;
2
3/// Guarantees uniqueness only if `Weak` pointers are never created
4/// from this `Arc` or clones.
5pub(crate) fn is_arc_unique<M>(arc: &mut Arc<M>) -> bool {
6    let strong_count = Arc::strong_count(&*arc);
7    debug_assert_ne!(strong_count, 0, "This Arc should exist");
8
9    debug_assert!(
10        strong_count > 1 || Arc::get_mut(arc).is_some(),
11        "`Weak` pointer exists"
12    );
13
14    strong_count == 1
15}
16
17/// Can be used instead of `Arc::try_unwrap(arc).unwrap()`
18/// when it is guaranteed to succeed.
19pub(crate) unsafe fn arc_unwrap<M>(mut arc: Arc<M>) -> M {
20    use core::{mem::ManuallyDrop, ptr::read};
21    debug_assert!(is_arc_unique(&mut arc));
22
23    // Get raw pointer to inner value.
24    let raw = Arc::into_raw(arc);
25
26    // As `Arc` is unique and no Weak pointers exist
27    // it won't be dereferenced elsewhere.
28    let inner = read(raw);
29
30    // Cast to `ManuallyDrop` which guarantees to have same layout
31    // and will skip dropping.
32    drop(Arc::from_raw(raw as *const ManuallyDrop<M>));
33    inner
34}
35
36/// Can be used instead of `Arc::try_unwrap`
37/// only if `Weak` pointers are never created from this `Arc` or clones.
38pub(crate) unsafe fn try_arc_unwrap<M>(mut arc: Arc<M>) -> Option<M> {
39    if is_arc_unique(&mut arc) {
40        Some(arc_unwrap(arc))
41    } else {
42        None
43    }
44}