m-ou-se / rust-atomics-and-locks

Code examples, data structures, and links from my book, Rust Atomics and Locks.
Other
1.33k stars 120 forks source link

Ch.6 - Cryptic/Challenging explanation regarding 'special "locked" state' #43

Closed 0x32c2cac3info closed 1 year ago

0x32c2cac3info commented 1 year ago

The content that the question is about

Regarding this section roughly around:

A way out of this dilemma is to briefly block the downgrade() operation

it's not readily clear to me how the facade of a mutex over usize::MAX is used to guarantee the correctness of get_mut for the given snippet:

use std::sync::atomic::{
    Ordering::{Acquire, Relaxed, Release},
    fence,
};
struct Weak<T> { ... }
impl<T> Weak<T> {
    // ...
    pub fn get_mut(arc: &mut Self) -> Option<&mut T> {
        if arc.data().alloc_ref_count.compare_exchange(1, usize::MAX, Relaxed).is_err() { return None; }
        let is_unique = arc.data().data_ref_count.load(Relaxed) == 1;
        arc.data().alloc_ref_count.store(1, Release);
        if !is_unique { return None; }
        fence(Acquire);
        unsafe { Some(&mut *arc.data().data.get()) }
    }
}

is there an unspoken behaviour that the count cannot be exceeded (without overflow), thus allowing the implementation to leverage a stop condition elsewhere (like in downgrade)?

The question

Can there be a simpler explanation for the Ch.6 Arc optimization?