File tree Expand file tree Collapse file tree 2 files changed +23
-11
lines changed Expand file tree Collapse file tree 2 files changed +23
-11
lines changed Original file line number Diff line number Diff line change @@ -539,17 +539,16 @@ impl AtomicBool {
539539 // We can't use atomic_nand here because it can result in a bool with
540540 // an invalid value. This happens because the atomic operation is done
541541 // 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 )
551551 }
552- old
553552 }
554553
555554 /// Logical "or" with a boolean value.
Original file line number Diff line number Diff line change @@ -24,10 +24,23 @@ fn bool_() {
2424#[ test]
2525fn bool_and ( ) {
2626 let a = AtomicBool :: new ( true ) ;
27- assert_eq ! ( a. fetch_and( false , SeqCst ) , true ) ;
27+ assert_eq ! ( a. fetch_and( false , SeqCst ) , true ) ;
2828 assert_eq ! ( a. load( SeqCst ) , false ) ;
2929}
3030
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+
3144#[ test]
3245fn uint_and ( ) {
3346 let x = AtomicUsize :: new ( 0xf731 ) ;
You can’t perform that action at this time.
0 commit comments