Skip to content

Commit

Permalink
Simplify implementation of RefCount and MultiRefCount. (#2548)
Browse files Browse the repository at this point in the history
`RefCount::rich_drop_inner` is no longer used by anything other than `RefCount::drop`. It's simpler to just handle it directly in `drop`.

`MultiRefCount` has no need to heap-allocate the count, since it's
never cloned.
  • Loading branch information
jimblandy authored Mar 21, 2022
1 parent b0da1a2 commit e821e18
Showing 1 changed file with 7 additions and 28 deletions.
35 changes: 7 additions & 28 deletions wgpu-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,6 @@ impl RefCount {
fn load(&self) -> usize {
unsafe { self.0.as_ref() }.load(Ordering::Acquire)
}

/// This function exists to allow `Self::rich_drop_outer` and `Drop::drop` to share the same
/// logic. To use this safely from outside of `Drop::drop`, the calling function must move
/// `Self` into a `ManuallyDrop`.
unsafe fn rich_drop_inner(&mut self) -> bool {
if self.0.as_ref().fetch_sub(1, Ordering::AcqRel) == 1 {
let _ = Box::from_raw(self.0.as_ptr());
true
} else {
false
}
}
}

impl Clone for RefCount {
Expand All @@ -108,38 +96,29 @@ impl Clone for RefCount {
impl Drop for RefCount {
fn drop(&mut self) {
unsafe {
self.rich_drop_inner();
if self.0.as_ref().fetch_sub(1, Ordering::AcqRel) == 1 {
drop(Box::from_raw(self.0.as_ptr()));
}
}
}
}

/// Reference count object that tracks multiple references.
/// Unlike `RefCount`, it's manually inc()/dec() called.
#[derive(Debug)]
struct MultiRefCount(ptr::NonNull<AtomicUsize>);

unsafe impl Send for MultiRefCount {}
unsafe impl Sync for MultiRefCount {}
struct MultiRefCount(AtomicUsize);

impl MultiRefCount {
fn new() -> Self {
let bx = Box::new(AtomicUsize::new(1));
let ptr = Box::into_raw(bx);
Self(unsafe { ptr::NonNull::new_unchecked(ptr) })
Self(AtomicUsize::new(1))
}

fn inc(&self) {
unsafe { self.0.as_ref() }.fetch_add(1, Ordering::AcqRel);
self.0.fetch_add(1, Ordering::AcqRel);
}

fn dec_and_check_empty(&self) -> bool {
unsafe { self.0.as_ref() }.fetch_sub(1, Ordering::AcqRel) == 1
}
}

impl Drop for MultiRefCount {
fn drop(&mut self) {
let _ = unsafe { Box::from_raw(self.0.as_ptr()) };
self.0.fetch_sub(1, Ordering::AcqRel) == 1
}
}

Expand Down

0 comments on commit e821e18

Please sign in to comment.