File tree 2 files changed +23
-11
lines changed
2 files changed +23
-11
lines changed Original file line number Diff line number Diff line change @@ -539,17 +539,16 @@ impl AtomicBool {
539
539
// We can't use atomic_nand here because it can result in a bool with
540
540
// an invalid value. This happens because the atomic operation is done
541
541
// with an 8-bit integer internally, which would set the upper 7 bits.
542
- // So we just use a compare-exchange loop instead, which is what the
543
- // intrinsic actually expands to anyways on many platforms.
544
- let mut old = self . load ( Relaxed ) ;
545
- loop {
546
- let new = ! ( old && val ) ;
547
- match self . compare_exchange_weak ( old , new , order , Relaxed ) {
548
- Ok ( _ ) => break ,
549
- Err ( x ) => old = x ,
550
- }
542
+ // So we just use fetch_xor or swap instead.
543
+ if val {
544
+ // !(x & true) == !x
545
+ // We must invert the bool.
546
+ self . fetch_xor ( true , order )
547
+ } else {
548
+ // !(x & false ) == true
549
+ // We must set the bool to true.
550
+ self . swap ( true , order )
551
551
}
552
- old
553
552
}
554
553
555
554
/// Logical "or" with a boolean value.
Original file line number Diff line number Diff line change @@ -24,10 +24,23 @@ fn bool_() {
24
24
#[ test]
25
25
fn bool_and ( ) {
26
26
let a = AtomicBool :: new ( true ) ;
27
- assert_eq ! ( a. fetch_and( false , SeqCst ) , true ) ;
27
+ assert_eq ! ( a. fetch_and( false , SeqCst ) , true ) ;
28
28
assert_eq ! ( a. load( SeqCst ) , false ) ;
29
29
}
30
30
31
+ #[ test]
32
+ fn bool_nand ( ) {
33
+ let a = AtomicBool :: new ( false ) ;
34
+ assert_eq ! ( a. fetch_nand( false , SeqCst ) , false ) ;
35
+ assert_eq ! ( a. load( SeqCst ) , true ) ;
36
+ assert_eq ! ( a. fetch_nand( false , SeqCst ) , true ) ;
37
+ assert_eq ! ( a. load( SeqCst ) , true ) ;
38
+ assert_eq ! ( a. fetch_nand( true , SeqCst ) , true ) ;
39
+ assert_eq ! ( a. load( SeqCst ) , false ) ;
40
+ assert_eq ! ( a. fetch_nand( true , SeqCst ) , false ) ;
41
+ assert_eq ! ( a. load( SeqCst ) , true ) ;
42
+ }
43
+
31
44
#[ test]
32
45
fn uint_and ( ) {
33
46
let x = AtomicUsize :: new ( 0xf731 ) ;
You can’t perform that action at this time.
0 commit comments