Need help understanding atomic ordering

⚓ Rust    📅 2025-12-11    👤 surdeus    👁️ 3      

surdeus

Hello,

I do have a question regarding atomics. I am reading the book by marabos and I am looking at the following example of Mutex.

pub struct Mutex<T> {
    /// 0: unlocked
    /// 1: locked
    state: AtomicU32,
    value: UnsafeCell<T>,
}

impl<T> Mutex<T> {
    pub const fn new(value: T) -> Self {
        Self {
            state: AtomicU32::new(0), // unlocked state
            value: UnsafeCell::new(value),
        }
    }

    pub fn lock(&self) -> MutexGuard<T> {
        // Set the state to 1: locked.
        while self.state.swap(1, Acquire) == 1 {
            // If it was already locked..
            // .. wait, unless the state is no longer 1.
            wait(&self.state, 1);
        }
        MutexGuard { mutex: self }
    }
}

My issue is with the following Drop impl.

impl<T> Drop for MutexGuard<'_, T> {
    fn drop(&mut self) {
        // Set the state back to 0: unlocked.
        self.mutex.state.store(0, Release);
        // Wake up one of the waiting threads, if any.
        wake_one(&self.mutex.state);
    }
}

I do not understand what prevents the wake_one to be re-ordered before the self.mutex.state.store(0, Release);, since the Release ordering prevents things that happens "before" to be re-ordered "after", but not the opposite.

Then, the thread waiting with wait would view the wake_one, would actually not wake up since the value has not changed yet.

Could somebody help me to understand what I am missing ?

Thank you very much.

4 posts - 2 participants

Read full topic

🏷️ Rust_feed