@@ -223,7 +223,7 @@ impl<T> Arc<T> {
223
223
#[ stable( feature = "arc_unique" , since = "1.4.0" ) ]
224
224
pub fn try_unwrap ( this : Self ) -> Result < T , Self > {
225
225
// 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 ( ) {
227
227
return Err ( this) ;
228
228
}
229
229
@@ -256,11 +256,11 @@ impl<T: ?Sized> Arc<T> {
256
256
/// ```
257
257
#[ stable( feature = "arc_weak" , since = "1.4.0" ) ]
258
258
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 ) ;
263
262
263
+ loop {
264
264
// check if the weak counter is currently "locked"; if so, spin.
265
265
if cur == usize:: MAX {
266
266
continue ;
@@ -273,8 +273,9 @@ impl<T: ?Sized> Arc<T> {
273
273
// Unlike with Clone(), we need this to be an Acquire read to
274
274
// synchronize with the write coming from `is_unique`, so that the
275
275
// 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,
278
279
}
279
280
}
280
281
}
@@ -416,7 +417,7 @@ impl<T: Clone> Arc<T> {
416
417
// before release writes (i.e., decrements) to `strong`. Since we hold a
417
418
// weak count, there's no chance the ArcInner itself could be
418
419
// 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 ( ) {
420
421
// Another strong pointer exists; clone
421
422
* this = Arc :: new ( ( * * this) . clone ( ) ) ;
422
423
} else if this. inner ( ) . weak . load ( Relaxed ) != 1 {
@@ -506,7 +507,7 @@ impl<T: ?Sized> Arc<T> {
506
507
// The acquire label here ensures a happens-before relationship with any
507
508
// writes to `strong` prior to decrements of the `weak` count (via drop,
508
509
// 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 ( ) {
510
511
// Due to the previous acquire read, this will observe any writes to
511
512
// `strong` that were due to upgrading weak pointers; only strong
512
513
// clones remain, which require that the strong count is > 1 anyway.
@@ -618,12 +619,14 @@ impl<T: ?Sized> Weak<T> {
618
619
// We use a CAS loop to increment the strong count instead of a
619
620
// fetch_add because once the count hits 0 it must never be above 0.
620
621
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
+
621
629
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 ) ;
627
630
if n == 0 {
628
631
return None ;
629
632
}
@@ -634,9 +637,9 @@ impl<T: ?Sized> Weak<T> {
634
637
}
635
638
636
639
// 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 ,
640
643
}
641
644
}
642
645
}
0 commit comments