]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/fail/data_race/write_write_race_stack.rs
Rollup merge of #101717 - Pointerbender:unsafecell-memory-layout, r=Amanieu
[rust.git] / src / tools / miri / tests / fail / data_race / write_write_race_stack.rs
1 //@compile-flags: -Zmiri-disable-isolation -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0
2
3 use std::ptr::null_mut;
4 use std::sync::atomic::{AtomicPtr, Ordering};
5 use std::thread::{sleep, spawn};
6 use std::time::Duration;
7
8 #[derive(Copy, Clone)]
9 struct EvilSend<T>(pub T);
10
11 unsafe impl<T> Send for EvilSend<T> {}
12 unsafe impl<T> Sync for EvilSend<T> {}
13
14 pub fn main() {
15     // Shared atomic pointer
16     let pointer = AtomicPtr::new(null_mut::<usize>());
17     let ptr = EvilSend(&pointer as *const AtomicPtr<usize>);
18
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
23     // detect the race:
24     //  1. stack-allocate
25     //  2. atomic_store
26     //  3. atomic_load
27     //  4. write-value
28     //  5. write-value
29     unsafe {
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;
35
36             let mut stack_var = 0usize;
37
38             pointer.store(&mut stack_var as *mut _, Ordering::Release);
39
40             sleep(Duration::from_millis(200));
41
42             stack_var = 1usize; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>`
43
44             // read to silence errors
45             stack_var
46         });
47
48         let j2 = spawn(move || {
49             let pointer = &*ptr.0;
50             *pointer.load(Ordering::Acquire) = 3;
51         });
52
53         j1.join().unwrap();
54         j2.join().unwrap();
55     }
56 }