Skip to content

Instantly share code, notes, and snippets.

@tamuhey
Created September 5, 2020 16:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tamuhey/14a1b15a23663694e4c2281bf311e227 to your computer and use it in GitHub Desktop.
Save tamuhey/14a1b15a23663694e4c2281bf311e227 to your computer and use it in GitHub Desktop.
// 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