aboutsummaryrefslogtreecommitdiff
path: root/src/seg_queue.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/seg_queue.rs')
-rw-r--r--src/seg_queue.rs24
1 files changed, 13 insertions, 11 deletions
diff --git a/src/seg_queue.rs b/src/seg_queue.rs
index 1767775..2761dc0 100644
--- a/src/seg_queue.rs
+++ b/src/seg_queue.rs
@@ -35,6 +35,11 @@ struct Slot<T> {
}
impl<T> Slot<T> {
+ const UNINIT: Self = Self {
+ value: UnsafeCell::new(MaybeUninit::uninit()),
+ state: AtomicUsize::new(0),
+ };
+
/// Waits until a value is written into the slot.
fn wait_write(&self) {
let backoff = Backoff::new();
@@ -58,13 +63,10 @@ struct Block<T> {
impl<T> Block<T> {
/// Creates an empty block that starts at `start_index`.
fn new() -> Block<T> {
- // SAFETY: This is safe because:
- // [1] `Block::next` (AtomicPtr) may be safely zero initialized.
- // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4].
- // [3] `Slot::value` (UnsafeCell) may be safely zero initialized because it
- // holds a MaybeUninit.
- // [4] `Slot::state` (AtomicUsize) may be safely zero initialized.
- unsafe { MaybeUninit::zeroed().assume_init() }
+ Self {
+ next: AtomicPtr::new(ptr::null_mut()),
+ slots: [Slot::UNINIT; BLOCK_CAP],
+ }
}
/// Waits until the next pointer is set.
@@ -437,9 +439,9 @@ impl<T> SegQueue<T> {
impl<T> Drop for SegQueue<T> {
fn drop(&mut self) {
- let mut head = self.head.index.load(Ordering::Relaxed);
- let mut tail = self.tail.index.load(Ordering::Relaxed);
- let mut block = self.head.block.load(Ordering::Relaxed);
+ let mut head = *self.head.index.get_mut();
+ let mut tail = *self.tail.index.get_mut();
+ let mut block = *self.head.block.get_mut();
// Erase the lower bits.
head &= !((1 << SHIFT) - 1);
@@ -457,7 +459,7 @@ impl<T> Drop for SegQueue<T> {
p.as_mut_ptr().drop_in_place();
} else {
// Deallocate the block and move to the next one.
- let next = (*block).next.load(Ordering::Relaxed);
+ let next = *(*block).next.get_mut();
drop(Box::from_raw(block));
block = next;
}