Skip to content

Commit 0eab7ff

Browse files
author
Stjepan Glavina
committed
Use a boxed slice instead of raw pointers
1 parent 0e2534b commit 0eab7ff

File tree

1 file changed

+21
-37
lines changed

1 file changed

+21
-37
lines changed

src/bounded.rs

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::cell::UnsafeCell;
22
use std::marker::PhantomData;
3-
use std::mem::{self, MaybeUninit};
3+
use std::mem::MaybeUninit;
44
use std::sync::atomic::{AtomicUsize, Ordering};
55
use std::thread;
66

@@ -38,10 +38,7 @@ pub struct Bounded<T> {
3838
tail: CachePadded<AtomicUsize>,
3939

4040
/// The buffer holding slots.
41-
buffer: *mut Slot<T>,
42-
43-
/// The queue capacity.
44-
cap: usize,
41+
buffer: Box<[Slot<T>]>,
4542

4643
/// A stamp with the value of `{ lap: 1, mark: 0, index: 0 }`.
4744
one_lap: usize,
@@ -64,29 +61,21 @@ impl<T> Bounded<T> {
6461
let tail = 0;
6562

6663
// Allocate a buffer of `cap` slots initialized with stamps.
67-
let buffer = {
68-
let mut v: Vec<Slot<T>> = (0..cap)
69-
.map(|i| {
70-
// Set the stamp to `{ lap: 0, mark: 0, index: i }`.
71-
Slot {
72-
stamp: AtomicUsize::new(i),
73-
value: UnsafeCell::new(MaybeUninit::uninit()),
74-
}
75-
})
76-
.collect();
77-
78-
let ptr = v.as_mut_ptr();
79-
mem::forget(v);
80-
ptr
81-
};
64+
let mut buffer = Vec::with_capacity(cap);
65+
for i in 0..cap {
66+
// Set the stamp to `{ lap: 0, mark: 0, index: i }`.
67+
buffer.push(Slot {
68+
stamp: AtomicUsize::new(i),
69+
value: UnsafeCell::new(MaybeUninit::uninit()),
70+
});
71+
}
8272

8373
// Compute constants `mark_bit` and `one_lap`.
8474
let mark_bit = (cap + 1).next_power_of_two();
8575
let one_lap = mark_bit * 2;
8676

8777
Bounded {
88-
buffer,
89-
cap,
78+
buffer: buffer.into(),
9079
one_lap,
9180
mark_bit,
9281
head: CachePadded::new(AtomicUsize::new(head)),
@@ -110,12 +99,12 @@ impl<T> Bounded<T> {
11099
let lap = tail & !(self.one_lap - 1);
111100

112101
// Inspect the corresponding slot.
113-
let slot = unsafe { &*self.buffer.add(index) };
102+
let slot = &self.buffer[index];
114103
let stamp = slot.stamp.load(Ordering::Acquire);
115104

116105
// If the tail and the stamp match, we may attempt to push.
117106
if tail == stamp {
118-
let new_tail = if index + 1 < self.cap {
107+
let new_tail = if index + 1 < self.buffer.len() {
119108
// Same lap, incremented index.
120109
// Set to `{ lap: lap, mark: 0, index: index + 1 }`.
121110
tail + 1
@@ -173,12 +162,12 @@ impl<T> Bounded<T> {
173162
let lap = head & !(self.one_lap - 1);
174163

175164
// Inspect the corresponding slot.
176-
let slot = unsafe { &*self.buffer.add(index) };
165+
let slot = &self.buffer[index];
177166
let stamp = slot.stamp.load(Ordering::Acquire);
178167

179168
// If the the stamp is ahead of the head by 1, we may attempt to pop.
180169
if head + 1 == stamp {
181-
let new = if index + 1 < self.cap {
170+
let new = if index + 1 < self.buffer.len() {
182171
// Same lap, incremented index.
183172
// Set to `{ lap: lap, mark: 0, index: index + 1 }`.
184173
head + 1
@@ -244,11 +233,11 @@ impl<T> Bounded<T> {
244233
return if hix < tix {
245234
tix - hix
246235
} else if hix > tix {
247-
self.cap - hix + tix
236+
self.buffer.len() - hix + tix
248237
} else if (tail & !self.mark_bit) == head {
249238
0
250239
} else {
251-
self.cap
240+
self.buffer.len()
252241
};
253242
}
254243
}
@@ -280,7 +269,7 @@ impl<T> Bounded<T> {
280269

281270
/// Returns the capacity of the queue.
282271
pub fn capacity(&self) -> usize {
283-
self.cap
272+
self.buffer.len()
284273
}
285274

286275
/// Closes the queue.
@@ -305,23 +294,18 @@ impl<T> Drop for Bounded<T> {
305294
// Loop over all slots that hold a value and drop them.
306295
for i in 0..self.len() {
307296
// Compute the index of the next slot holding a value.
308-
let index = if hix + i < self.cap {
297+
let index = if hix + i < self.buffer.len() {
309298
hix + i
310299
} else {
311-
hix + i - self.cap
300+
hix + i - self.buffer.len()
312301
};
313302

314303
// Drop the value in the slot.
304+
let slot = &self.buffer[index];
315305
unsafe {
316-
let slot = &*self.buffer.add(index);
317306
let value = slot.value.get().read().assume_init();
318307
drop(value);
319308
}
320309
}
321-
322-
// Finally, deallocate the buffer, but don't run any destructors.
323-
unsafe {
324-
Vec::from_raw_parts(self.buffer, 0, self.cap);
325-
}
326310
}
327311
}

0 commit comments

Comments
 (0)