//@ revisions: non_genmc genmc //@[genmc] compile-flags: -Zmiri-genmc -Zmiri-disable-stacked-borrows // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (c) 2019 Carl Lerche // This is the test `store_buffering` from `loom/test/litmus.rs`, adapted for Miri-GenMC. // https://github.com/tokio-rs/loom/blob/dbf32b04bae821c64be44405a0bb72ca08741558/tests/litmus.rs // This test shows the comparison between running Miri with or without GenMC. // Without GenMC, Miri requires multiple iterations of the loop to detect the error. #![no_main] #[path = "../../../utils/genmc.rs"] mod genmc; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::*; use crate::genmc::*; #[unsafe(no_mangle)] fn miri_start(_argc: isize, _argv: *const *const u8) -> isize { // For normal Miri, we need multiple repetitions, but GenMC should find the bug with only 1. const REPS: usize = if cfg!(non_genmc) { 128 } else { 1 }; for _ in 0..REPS { // New atomics every iterations, so they don't influence each other. let x = AtomicUsize::new(0); let y = AtomicUsize::new(0); // FIXME(genmc,HACK): remove these initializing writes once Miri-GenMC supports mixed atomic-non-atomic accesses. x.store(0, Relaxed); y.store(0, Relaxed); let mut a: usize = 1234; let mut b: usize = 1234; unsafe { let ids = [ spawn_pthread_closure(|| { x.store(1, Relaxed); a = y.load(Relaxed) }), spawn_pthread_closure(|| { y.store(1, Relaxed); b = x.load(Relaxed) }), ]; join_pthreads(ids); } if (a, b) == (0, 0) { std::process::abort(); //~ ERROR: abnormal termination } } 0 }