blob: 4955dfd8a77ad3597a6c1745fc6fc82ea90528c6 [file] [log] [blame]
//@ 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
}