diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
commit | 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch) | |
tree | 3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /vendor/elsa/src | |
parent | Releasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip |
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
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 |