1 //@compile-flags: -Zmiri-disable-isolation -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0
3 use std::ptr::null_mut;
4 use std::sync::atomic::{AtomicPtr, Ordering};
5 use std::thread::{sleep, spawn};
6 use std::time::Duration;
9 struct EvilSend<T>(pub T);
11 unsafe impl<T> Send for EvilSend<T> {}
12 unsafe impl<T> Sync for EvilSend<T> {}
15 // Shared atomic pointer
16 let pointer = AtomicPtr::new(null_mut::<usize>());
17 let ptr = EvilSend(&pointer as *const AtomicPtr<usize>);
19 // Note: this is scheduler-dependent
20 // the operations need to occur in
21 // order, otherwise the allocation is
22 // not visible to the other-thread to
30 let j1 = spawn(move || {
31 // Concurrent allocate the memory.
32 // Uses relaxed semantics to not generate
33 // a release sequence.
34 let pointer = &*ptr.0;
36 let mut stack_var = 0usize;
38 pointer.store(&mut stack_var as *mut _, Ordering::Release);
40 sleep(Duration::from_millis(200));
42 stack_var = 1usize; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>`
44 // read to silence errors
48 let j2 = spawn(move || {
49 let pointer = &*ptr.0;
50 *pointer.load(Ordering::Acquire) = 3;