@@ -101,9 +101,14 @@ type AtomicTargetSize = atomic::AtomicUsize;
101
101
type AtomicTargetSize = atomic:: AtomicU8 ;
102
102
103
103
#[ cfg( feature = "mpmc_large" ) ]
104
- type IntSize = usize ;
104
+ type UintSize = usize ;
105
105
#[ cfg( not( feature = "mpmc_large" ) ) ]
106
- type IntSize = u8 ;
106
+ type UintSize = u8 ;
107
+
108
+ #[ cfg( feature = "mpmc_large" ) ]
109
+ type IntSize = isize ;
110
+ #[ cfg( not( feature = "mpmc_large" ) ) ]
111
+ type IntSize = i8 ;
107
112
108
113
/// MPMC queue with a capability for 2 elements.
109
114
pub type Q2 < T > = MpMcQueue < T , 2 > ;
@@ -133,7 +138,7 @@ pub struct MpMcQueue<T, const N: usize> {
133
138
}
134
139
135
140
impl < T , const N : usize > MpMcQueue < T , N > {
136
- const MASK : IntSize = ( N - 1 ) as IntSize ;
141
+ const MASK : UintSize = ( N - 1 ) as UintSize ;
137
142
const EMPTY_CELL : Cell < T > = Cell :: new ( 0 ) ;
138
143
139
144
const ASSERT : [ ( ) ; 1 ] = [ ( ) ] ;
@@ -146,7 +151,7 @@ impl<T, const N: usize> MpMcQueue<T, N> {
146
151
147
152
// Const assert on size.
148
153
#[ allow( clippy:: no_effect) ]
149
- Self :: ASSERT [ ( N >= ( IntSize :: MAX as usize ) ) as usize ] ;
154
+ Self :: ASSERT [ ( N >= ( UintSize :: MAX as usize ) ) as usize ] ;
150
155
151
156
let mut cell_count = 0 ;
152
157
@@ -200,23 +205,23 @@ impl<T> Cell<T> {
200
205
const fn new ( seq : usize ) -> Self {
201
206
Self {
202
207
data : MaybeUninit :: uninit ( ) ,
203
- sequence : AtomicTargetSize :: new ( seq as IntSize ) ,
208
+ sequence : AtomicTargetSize :: new ( seq as UintSize ) ,
204
209
}
205
210
}
206
211
}
207
212
208
213
unsafe fn dequeue < T > (
209
214
buffer : * mut Cell < T > ,
210
215
dequeue_pos : & AtomicTargetSize ,
211
- mask : IntSize ,
216
+ mask : UintSize ,
212
217
) -> Option < T > {
213
218
let mut pos = dequeue_pos. load ( Ordering :: Relaxed ) ;
214
219
215
220
let mut cell;
216
221
loop {
217
222
cell = buffer. add ( usize:: from ( pos & mask) ) ;
218
223
let seq = ( * cell) . sequence . load ( Ordering :: Acquire ) ;
219
- let dif = ( seq as i8 ) . wrapping_sub ( ( pos. wrapping_add ( 1 ) ) as i8 ) ;
224
+ let dif = ( seq as IntSize ) . wrapping_sub ( ( pos. wrapping_add ( 1 ) ) as IntSize ) ;
220
225
221
226
match dif. cmp ( & 0 ) {
222
227
core:: cmp:: Ordering :: Equal => {
@@ -251,7 +256,7 @@ unsafe fn dequeue<T>(
251
256
unsafe fn enqueue < T > (
252
257
buffer : * mut Cell < T > ,
253
258
enqueue_pos : & AtomicTargetSize ,
254
- mask : IntSize ,
259
+ mask : UintSize ,
255
260
item : T ,
256
261
) -> Result < ( ) , T > {
257
262
let mut pos = enqueue_pos. load ( Ordering :: Relaxed ) ;
@@ -260,7 +265,7 @@ unsafe fn enqueue<T>(
260
265
loop {
261
266
cell = buffer. add ( usize:: from ( pos & mask) ) ;
262
267
let seq = ( * cell) . sequence . load ( Ordering :: Acquire ) ;
263
- let dif = ( seq as i8 ) . wrapping_sub ( pos as i8 ) ;
268
+ let dif = ( seq as IntSize ) . wrapping_sub ( pos as IntSize ) ;
264
269
265
270
match dif. cmp ( & 0 ) {
266
271
core:: cmp:: Ordering :: Equal => {
@@ -320,7 +325,8 @@ mod tests {
320
325
assert ! ( q. enqueue( 0 ) . is_ok( ) ) ;
321
326
assert_eq ! ( q. dequeue( ) , Some ( 0 ) ) ;
322
327
}
323
- // this should not block forever
328
+
329
+ // Queue is empty, this should not block forever.
324
330
assert_eq ! ( q. dequeue( ) , None ) ;
325
331
}
326
332
@@ -336,4 +342,22 @@ mod tests {
336
342
// this should not block forever
337
343
assert ! ( q. enqueue( 0 ) . is_err( ) ) ;
338
344
}
345
+
346
+ #[ test]
347
+ fn enqueue_full ( ) {
348
+ #[ cfg( not( feature = "mpmc_large" ) ) ]
349
+ const CAPACITY : usize = 128 ;
350
+
351
+ #[ cfg( feature = "mpmc_large" ) ]
352
+ const CAPACITY : usize = 256 ;
353
+
354
+ let q: MpMcQueue < u8 , CAPACITY > = MpMcQueue :: new ( ) ;
355
+
356
+ for _ in 0 ..CAPACITY {
357
+ q. enqueue ( 0xAA ) . unwrap ( ) ;
358
+ }
359
+
360
+ // Queue is full, this should not block forever.
361
+ q. enqueue ( 0x55 ) . unwrap_err ( ) ;
362
+ }
339
363
}
0 commit comments