diff options
Diffstat (limited to 'vendor/elsa/src')
-rw-r--r-- | vendor/elsa/src/sync.rs | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/vendor/elsa/src/sync.rs b/vendor/elsa/src/sync.rs index afa4bb7c7..5746989d1 100644 --- a/vendor/elsa/src/sync.rs +++ b/vendor/elsa/src/sync.rs @@ -13,7 +13,6 @@ use std::collections::BTreeMap; use std::collections::HashMap; use std::hash::Hash; use std::iter::{FromIterator, IntoIterator}; -use std::mem::MaybeUninit; use std::ops::Index; use std::sync::atomic::AtomicPtr; @@ -301,9 +300,11 @@ pub struct LockFreeFrozenVec<T: Copy> { impl<T: Copy> Drop for LockFreeFrozenVec<T> { fn drop(&mut self) { let cap = *self.cap.get_mut(); - let layout = self.layout(cap); - unsafe { - std::alloc::dealloc((*self.data.get_mut()).cast(), layout); + let layout = Self::layout(cap); + if cap != 0 { + unsafe { + std::alloc::dealloc((*self.data.get_mut()).cast(), layout); + } } } } @@ -326,9 +327,7 @@ impl<T: Copy> LockFreeFrozenVec<T> { pub fn with_capacity(cap: usize) -> Self { Self { - data: AtomicPtr::new( - Box::into_raw(vec![MaybeUninit::<T>::uninit(); cap].into_boxed_slice()).cast(), - ), + data: AtomicPtr::new(unsafe { std::alloc::alloc(Self::layout(cap)) }.cast()), len: AtomicUsize::new(0), cap: AtomicUsize::new(cap), } @@ -349,7 +348,7 @@ impl<T: Copy> LockFreeFrozenVec<T> { ret } - fn layout(&self, cap: usize) -> Layout { + fn layout(cap: usize) -> Layout { let num_bytes = std::mem::size_of::<T>() * cap; let align = std::mem::align_of::<T>(); Layout::from_size_align(num_bytes, align).unwrap() @@ -375,7 +374,7 @@ impl<T: Copy> LockFreeFrozenVec<T> { if len >= cap { if cap == 0 { // No memory allocated yet - let layout = self.layout(128); + let layout = Self::layout(128); // SAFETY: `LockFreeFrozenVec` statically rejects zsts unsafe { *ptr = std::alloc::alloc(layout).cast::<T>(); @@ -385,7 +384,7 @@ impl<T: Copy> LockFreeFrozenVec<T> { self.cap.store(128, Ordering::Release); } else { // Out of memory, realloc with double the capacity - let layout = self.layout(cap); + let layout = Self::layout(cap); let new_size = layout.size() * 2; // SAFETY: `LockFreeFrozenVec` statically rejects zsts and the input `ptr` has always been // allocated at the size stated in `cap`. @@ -459,6 +458,13 @@ fn test_non_lockfree() { } }); } + // Test dropping empty vecs + for _ in [ + LockFreeFrozenVec::<()>::new(), + LockFreeFrozenVec::with_capacity(1), + LockFreeFrozenVec::with_capacity(2), + LockFreeFrozenVec::with_capacity(1000), + ] {} } /// Append-only threadsafe version of `std::collections::BTreeMap` where |