@@ -223,7 +223,7 @@ impl<T> Arc<T> {
223223 #[ stable( feature = "arc_unique" , since = "1.4.0" ) ]
224224 pub fn try_unwrap ( this : Self ) -> Result < T , Self > {
225225 // See `drop` for why all these atomics are like this
226- if this. inner ( ) . strong . compare_and_swap ( 1 , 0 , Release ) != 1 {
226+ if this. inner ( ) . strong . compare_exchange ( 1 , 0 , Release , Relaxed ) . is_err ( ) {
227227 return Err ( this) ;
228228 }
229229
@@ -256,11 +256,11 @@ impl<T: ?Sized> Arc<T> {
256256 /// ```
257257 #[ stable( feature = "arc_weak" , since = "1.4.0" ) ]
258258 pub fn downgrade ( this : & Self ) -> Weak < T > {
259- loop {
260- // This Relaxed is OK because we're checking the value in the CAS
261- // below.
262- let cur = this. inner ( ) . weak . load ( Relaxed ) ;
259+ // This Relaxed is OK because we're checking the value in the CAS
260+ // below.
261+ let mut cur = this. inner ( ) . weak . load ( Relaxed ) ;
263262
263+ loop {
264264 // check if the weak counter is currently "locked"; if so, spin.
265265 if cur == usize:: MAX {
266266 continue ;
@@ -273,8 +273,9 @@ impl<T: ?Sized> Arc<T> {
273273 // Unlike with Clone(), we need this to be an Acquire read to
274274 // synchronize with the write coming from `is_unique`, so that the
275275 // events prior to that write happen before this read.
276- if this. inner ( ) . weak . compare_and_swap ( cur, cur + 1 , Acquire ) == cur {
277- return Weak { _ptr : this. _ptr } ;
276+ match this. inner ( ) . weak . compare_exchange_weak ( cur, cur + 1 , Acquire , Relaxed ) {
277+ Ok ( _) => return Weak { _ptr : this. _ptr } ,
278+ Err ( old) => cur = old,
278279 }
279280 }
280281 }
@@ -416,7 +417,7 @@ impl<T: Clone> Arc<T> {
416417 // before release writes (i.e., decrements) to `strong`. Since we hold a
417418 // weak count, there's no chance the ArcInner itself could be
418419 // deallocated.
419- if this. inner ( ) . strong . compare_and_swap ( 1 , 0 , Acquire ) != 1 {
420+ if this. inner ( ) . strong . compare_exchange ( 1 , 0 , Acquire , Relaxed ) . is_err ( ) {
420421 // Another strong pointer exists; clone
421422 * this = Arc :: new ( ( * * this) . clone ( ) ) ;
422423 } else if this. inner ( ) . weak . load ( Relaxed ) != 1 {
@@ -506,7 +507,7 @@ impl<T: ?Sized> Arc<T> {
506507 // The acquire label here ensures a happens-before relationship with any
507508 // writes to `strong` prior to decrements of the `weak` count (via drop,
508509 // which uses Release).
509- if self . inner ( ) . weak . compare_and_swap ( 1 , usize:: MAX , Acquire ) == 1 {
510+ if self . inner ( ) . weak . compare_exchange ( 1 , usize:: MAX , Acquire , Relaxed ) . is_ok ( ) {
510511 // Due to the previous acquire read, this will observe any writes to
511512 // `strong` that were due to upgrading weak pointers; only strong
512513 // clones remain, which require that the strong count is > 1 anyway.
@@ -618,12 +619,14 @@ impl<T: ?Sized> Weak<T> {
618619 // We use a CAS loop to increment the strong count instead of a
619620 // fetch_add because once the count hits 0 it must never be above 0.
620621 let inner = self . inner ( ) ;
622+
623+ // Relaxed load because any write of 0 that we can observe
624+ // leaves the field in a permanently zero state (so a
625+ // "stale" read of 0 is fine), and any other value is
626+ // confirmed via the CAS below.
627+ let mut n = inner. strong . load ( Relaxed ) ;
628+
621629 loop {
622- // Relaxed load because any write of 0 that we can observe
623- // leaves the field in a permanently zero state (so a
624- // "stale" read of 0 is fine), and any other value is
625- // confirmed via the CAS below.
626- let n = inner. strong . load ( Relaxed ) ;
627630 if n == 0 {
628631 return None ;
629632 }
@@ -634,9 +637,9 @@ impl<T: ?Sized> Weak<T> {
634637 }
635638
636639 // Relaxed is valid for the same reason it is on Arc's Clone impl
637- let old = inner. strong . compare_and_swap ( n, n + 1 , Relaxed ) ;
638- if old == n {
639- return Some ( Arc { _ptr : self . _ptr } ) ;
640+ match inner. strong . compare_exchange_weak ( n, n + 1 , Relaxed , Relaxed ) {
641+ Ok ( _ ) => return Some ( Arc { _ptr : self . _ptr } ) ,
642+ Err ( old ) => n = old ,
640643 }
641644 }
642645 }
0 commit comments