Created
September 5, 2020 16:07
-
-
Save tamuhey/14a1b15a23663694e4c2281bf311e227 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Ref: https://preshing.com/20120515/memory-reordering-caught-in-the-act/ | |
// Let's change `Relaxed` to `SeqCst` and see what changed | |
use std::sync::atomic::AtomicUsize; | |
use std::sync::atomic::Ordering::*; | |
use std::thread::spawn; | |
static X: AtomicUsize = AtomicUsize::new(0); | |
static Y: AtomicUsize = AtomicUsize::new(0); | |
use rand; | |
use rand::Rng; | |
use std::sync::{mpsc, Arc}; | |
fn main() { | |
let (atx, arx) = mpsc::channel(); | |
let (btx, brx) = mpsc::channel(); | |
const n: usize = 1000000; | |
let _count = Arc::new(AtomicUsize::new(0)); | |
let count = Arc::clone(&_count); | |
let a = spawn(move || { | |
let mut rng = rand::thread_rng(); | |
for _ in 0..n { | |
atx.send(()).unwrap(); | |
while rng.gen::<usize>() % 8 != 0 {} | |
X.store(1, Relaxed); | |
let y = Y.load(Relaxed); | |
let x = brx.recv().unwrap(); | |
if (x, y) == (0, 0) { | |
count.fetch_add(1, Relaxed); | |
} | |
X.store(0, Relaxed); | |
Y.store(0, Relaxed); | |
} | |
}); | |
let b = spawn(move || { | |
let mut rng = rand::thread_rng(); | |
for _ in 0..n { | |
arx.recv().unwrap(); | |
while rng.gen::<usize>() % 8 != 0 {} | |
Y.store(1, Relaxed); | |
let x = X.load(Acquire); | |
btx.send(x).unwrap(); | |
} | |
}); | |
a.join().unwrap(); | |
b.join().unwrap(); | |
println!( | |
"{} reorders were detected after {} iterations", | |
_count.load(SeqCst), | |
n | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment