File tree 3 files changed +12
-8
lines changed
3 files changed +12
-8
lines changed Original file line number Diff line number Diff line change @@ -129,8 +129,7 @@ impl<T> Bounded<T> {
129
129
}
130
130
}
131
131
} else if stamp. wrapping_add ( self . one_lap ) == tail + 1 {
132
- crate :: full_fence ( ) ;
133
- let head = self . head . load ( Ordering :: Relaxed ) ;
132
+ let head = crate :: full_fence_for_load ( || self . head . load ( Ordering :: Relaxed ) ) ;
134
133
135
134
// If the head lags one lap behind the tail as well...
136
135
if head. wrapping_add ( self . one_lap ) == tail {
@@ -191,8 +190,7 @@ impl<T> Bounded<T> {
191
190
}
192
191
}
193
192
} else if stamp == head {
194
- crate :: full_fence ( ) ;
195
- let tail = self . tail . load ( Ordering :: Relaxed ) ;
193
+ let tail = crate :: full_fence_for_load ( || self . tail . load ( Ordering :: Relaxed ) ) ;
196
194
197
195
// If the tail equals the head, that means the queue is empty.
198
196
if ( tail & !self . mark_bit ) == head {
Original file line number Diff line number Diff line change @@ -445,8 +445,11 @@ impl<T> fmt::Display for PushError<T> {
445
445
446
446
/// Equivalent to `atomic::fence(Ordering::SeqCst)`, but in some cases faster.
447
447
#[ inline]
448
- fn full_fence ( ) {
449
- if cfg ! ( any( target_arch = "x86" , target_arch = "x86_64" ) ) {
448
+ fn full_fence_for_load < T > ( load_op : impl FnOnce ( ) -> T ) -> T {
449
+ if cfg ! ( all(
450
+ any( target_arch = "x86" , target_arch = "x86_64" ) ,
451
+ not( miri)
452
+ ) ) {
450
453
// HACK(stjepang): On x86 architectures there are two different ways of executing
451
454
// a `SeqCst` fence.
452
455
//
@@ -461,7 +464,11 @@ fn full_fence() {
461
464
// x86 platforms is going to optimize this away.
462
465
let a = AtomicUsize :: new ( 0 ) ;
463
466
let _ = a. compare_exchange ( 0 , 1 , Ordering :: SeqCst , Ordering :: SeqCst ) ;
467
+ // On x86, `lock cmpxchg; mov` is fine. See also https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html.
468
+ load_op ( )
464
469
} else {
470
+ let res = load_op ( ) ;
465
471
atomic:: fence ( Ordering :: SeqCst ) ;
472
+ res
466
473
}
467
474
}
Original file line number Diff line number Diff line change @@ -237,8 +237,7 @@ impl<T> Unbounded<T> {
237
237
let mut new_head = head + ( 1 << SHIFT ) ;
238
238
239
239
if new_head & MARK_BIT == 0 {
240
- crate :: full_fence ( ) ;
241
- let tail = self . tail . index . load ( Ordering :: Relaxed ) ;
240
+ let tail = crate :: full_fence_for_load ( || self . tail . index . load ( Ordering :: Relaxed ) ) ;
242
241
243
242
// If the tail equals the head, that means the queue is empty.
244
243
if head >> SHIFT == tail >> SHIFT {
You can’t perform that action at this time.
0 commit comments