Is RMW operation less prone to reading stale values than a pure load?

⚓ Rust    📅 2026-04-17    👤 surdeus    👁️ 2      

surdeus

use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
use std::thread;

fn main() {
    let v = AtomicI32::new(0);
    let flag = AtomicBool::new(false);

    thread::scope(|s| {
        s.spawn(|| {
            while !flag.load(Ordering::Relaxed) { // #1
                std::hint::spin_loop();
            }
            assert_eq!(v.swap(2, Ordering::Relaxed), 1); // #2
            // assert_eq!(v.load(Ordering::Relaxed),1); // #5
        });


        s.spawn(|| {
            if v.swap(1, Ordering::Relaxed) == 0 { // #3
                flag.store(true, Ordering::Relaxed); // #4
            }
        });
    });
}

In this example, the assert at #2 never fails. However, if you comment out #2 and uncomment #5, the assert at #5 can fail because #5 can either read 0 or 1.

Does it mean that an RMW is less prone to reading stale values than a pure load? So, for flag checking, we should use RMW operations rather than a pure load? If not that, what's the plausible reason here?

2 posts - 2 participants

Read full topic

🏷️ Rust_feed