okkotsu
1
use loom::sync::Arc;
use loom::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
loom::model(|| {
let ptr = Box::into_raw(Box::new(0));
let flag = Arc::new(AtomicBool::new(false));
let flag2 = flag.clone();
loom::thread::spawn(move || {
unsafe { *ptr = 1 };
flag.store(true, Ordering::Relaxed);
});
loom::thread::spawn(move || {
if flag2.load(Ordering::Relaxed) {
assert!(unsafe { *ptr == 1 });
}
});
});
this passes, could someone please explain why? thanks!
edit: oh, UB?
Yeah, UB.
How about using: UnsafeCell in loom::cell - Rust
Also looks like MutPtr would be useful.
farnz
3
If I rewrite it so that Loom can track the raw pointer use, I get:
use loom::sync::Arc;
use loom::sync::atomic::{AtomicBool, Ordering};
fn main() {
loom::model(|| {
let cell = loom::cell::UnsafeCell::new(0);
let flag = Arc::new(AtomicBool::new(false));
loom::thread::spawn({
let ptr = cell.get_mut();
let flag = flag.clone();
move || {
unsafe { *ptr.deref() = 1 };
flag.store(true, Ordering::Relaxed);
}
});
loom::thread::spawn({
let ptr = cell.get_mut();
let flag = flag.clone();
move || {
if flag.load(Ordering::Relaxed) {
assert!(unsafe { *ptr.deref() == 1 });
}
}
});
});
}
(which does fail)