11use std:: cell:: UnsafeCell ;
22use std:: marker:: PhantomData ;
3- use std:: mem:: { self , MaybeUninit } ;
3+ use std:: mem:: MaybeUninit ;
44use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
55use 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