about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgeetanshjuneja <ronitjuneja2002@gmail.com>2025-04-13 14:03:22 +0530
committergeetanshjuneja <ronitjuneja2002@gmail.com>2025-04-29 19:38:58 +0530
commitef5834968e41aa6c1ef479f8acc1197dec526731 (patch)
tree691810a8a377ad25610151b76972267fcf18f5fd
parent758e99a8004cf30c35a5dc17d9f8c626fc4ae2c9 (diff)
downloadrust-ef5834968e41aa6c1ef479f8acc1197dec526731.tar.gz
rust-ef5834968e41aa6c1ef479f8acc1197dec526731.zip
Added random scheduling
-rw-r--r--src/tools/miri/src/bin/miri.rs2
-rw-r--r--src/tools/miri/src/concurrency/thread.rs52
-rw-r--r--src/tools/miri/src/eval.rs3
-rw-r--r--src/tools/miri/src/machine.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs2
-rw-r--r--src/tools/miri/tests/fail/both_borrows/retag_data_race_write.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/alloc_read_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/alloc_write_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dangling_thread_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/fence_after_load.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/local_variable_alloc_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/local_variable_read_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/local_variable_write_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/mixed_size_read_write.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/mixed_size_write_write.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/read_write_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/read_write_race_stack.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/relax_acquire_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/release_seq_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/rmw_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/stack_pop_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/write_write_race.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/write_write_race_stack.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.rs2
-rw-r--r--src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.rs2
-rw-r--r--src/tools/miri/tests/fail/tree_borrows/spurious_read.rs2
-rw-r--r--src/tools/miri/tests/fail/weak_memory/weak_uninit.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/freebsd-futex.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/windows_detach_terminated.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-pipe.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/pthread-sync.rs2
-rw-r--r--src/tools/miri/tests/pass/concurrency/data_race.rs2
-rw-r--r--src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs2
-rw-r--r--src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs2
-rw-r--r--src/tools/miri/tests/pass/concurrency/sync.rs2
-rw-r--r--src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs2
-rw-r--r--src/tools/miri/tests/pass/panic/concurrent-panic.rs2
-rw-r--r--src/tools/miri/tests/pass/shims/env/var.rs2
-rw-r--r--src/tools/miri/tests/pass/tree_borrows/read_retag_no_race.rs2
-rw-r--r--src/tools/miri/tests/pass/tree_borrows/spurious_read.rs2
-rw-r--r--src/tools/miri/tests/pass/weak_memory/weak.rs2
76 files changed, 111 insertions, 92 deletions
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 4e8fe0ca8ad..57568071d0d 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -573,6 +573,8 @@ fn main() {
             miri_config.mute_stdout_stderr = true;
         } else if arg == "-Zmiri-retag-fields" {
             miri_config.retag_fields = RetagFields::Yes;
+        } else if arg == "-Zmiri-fixed-schedule" {
+            miri_config.fixed_scheduling = true;
         } else if let Some(retag_fields) = arg.strip_prefix("-Zmiri-retag-fields=") {
             miri_config.retag_fields = match retag_fields {
                 "all" => RetagFields::Yes,
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 72fa918e8e5..d640e7777e5 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -6,6 +6,8 @@ use std::task::Poll;
 use std::time::{Duration, SystemTime};
 
 use either::Either;
+use rand::rngs::StdRng;
+use rand::seq::IteratorRandom;
 use rustc_abi::ExternAbi;
 use rustc_const_eval::CTRL_C_RECEIVED;
 use rustc_data_structures::fx::FxHashMap;
@@ -401,6 +403,8 @@ pub struct ThreadManager<'tcx> {
     thread_local_allocs: FxHashMap<(DefId, ThreadId), StrictPointer>,
     /// A flag that indicates that we should change the active thread.
     yield_active_thread: bool,
+    /// A flag that indicates that we should do round robin scheduling of threads else randomized scheduling is used.
+    fixed_scheduling: bool,
 }
 
 impl VisitProvenance for ThreadManager<'_> {
@@ -410,6 +414,7 @@ impl VisitProvenance for ThreadManager<'_> {
             thread_local_allocs,
             active_thread: _,
             yield_active_thread: _,
+            fixed_scheduling: _,
         } = self;
 
         for thread in threads {
@@ -421,8 +426,8 @@ impl VisitProvenance for ThreadManager<'_> {
     }
 }
 
-impl<'tcx> Default for ThreadManager<'tcx> {
-    fn default() -> Self {
+impl<'tcx> ThreadManager<'tcx> {
+    pub(crate) fn new(config: &MiriConfig) -> Self {
         let mut threads = IndexVec::new();
         // Create the main thread and add it to the list of threads.
         threads.push(Thread::new(Some("main"), None));
@@ -431,11 +436,10 @@ impl<'tcx> Default for ThreadManager<'tcx> {
             threads,
             thread_local_allocs: Default::default(),
             yield_active_thread: false,
+            fixed_scheduling: config.fixed_scheduling,
         }
     }
-}
 
-impl<'tcx> ThreadManager<'tcx> {
     pub(crate) fn init(
         ecx: &mut MiriInterpCx<'tcx>,
         on_main_stack_empty: StackEmptyCallback<'tcx>,
@@ -702,7 +706,11 @@ impl<'tcx> ThreadManager<'tcx> {
     /// used in stateless model checkers such as Loom: run the active thread as
     /// long as we can and switch only when we have to (the active thread was
     /// blocked, terminated, or has explicitly asked to be preempted).
-    fn schedule(&mut self, clock: &MonotonicClock) -> InterpResult<'tcx, SchedulingAction> {
+    fn schedule(
+        &mut self,
+        clock: &MonotonicClock,
+        rng: &mut StdRng,
+    ) -> InterpResult<'tcx, SchedulingAction> {
         // This thread and the program can keep going.
         if self.threads[self.active_thread].state.is_enabled() && !self.yield_active_thread {
             // The currently active thread is still enabled, just continue with it.
@@ -720,30 +728,33 @@ impl<'tcx> ThreadManager<'tcx> {
         }
         // No callbacks immediately scheduled, pick a regular thread to execute.
         // The active thread blocked or yielded. So we go search for another enabled thread.
-        // Crucially, we start searching at the current active thread ID, rather than at 0, since we
-        // want to avoid always scheduling threads 0 and 1 without ever making progress in thread 2.
-        //
-        // `skip(N)` means we start iterating at thread N, so we skip 1 more to start just *after*
-        // the active thread. Then after that we look at `take(N)`, i.e., the threads *before* the
-        // active thread.
-        let threads = self
+        // We build the list of threads by starting with the thread after the current one, followed by
+        // the threads before the current one and then the current thread itself (i.e., this iterator acts
+        // like `threads.rotate_left(self.active_thread.index() + 1)`. This ensures that if we pick the first
+        // eligible thread, we do regular round-robin scheduling, and all threads get a chance to take a step.
+        let mut threads_iter = self
             .threads
             .iter_enumerated()
             .skip(self.active_thread.index() + 1)
-            .chain(self.threads.iter_enumerated().take(self.active_thread.index()));
-        for (id, thread) in threads {
-            debug_assert_ne!(self.active_thread, id);
-            if thread.state.is_enabled() {
+            .chain(self.threads.iter_enumerated().take(self.active_thread.index() + 1))
+            .filter(|(_id, thread)| thread.state.is_enabled());
+        // Pick a new thread, and switch to it.
+        let new_thread =
+            if self.fixed_scheduling { threads_iter.next() } else { threads_iter.choose(rng) };
+
+        if let Some((id, _thread)) = new_thread {
+            if self.active_thread != id {
                 info!(
                     "---------- Now executing on thread `{}` (previous: `{}`) ----------------------------------------",
                     self.get_thread_display_name(id),
                     self.get_thread_display_name(self.active_thread)
                 );
                 self.active_thread = id;
-                break;
             }
         }
+        //This completes the `yield`, if any was requested.
         self.yield_active_thread = false;
+
         if self.threads[self.active_thread].state.is_enabled() {
             return interp_ok(SchedulingAction::ExecuteStep);
         }
@@ -1138,7 +1149,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         use rand::Rng as _;
 
         let this = self.eval_context_mut();
-        if this.machine.rng.get_mut().random_bool(this.machine.preemption_rate) {
+        if !this.machine.threads.fixed_scheduling
+            && this.machine.rng.get_mut().random_bool(this.machine.preemption_rate)
+        {
             this.yield_active_thread();
         }
     }
@@ -1152,7 +1165,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.machine.handle_abnormal_termination();
                 throw_machine_stop!(TerminationInfo::Interrupted);
             }
-            match this.machine.threads.schedule(&this.machine.monotonic_clock)? {
+            let rng = this.machine.rng.get_mut();
+            match this.machine.threads.schedule(&this.machine.monotonic_clock, rng)? {
                 SchedulingAction::ExecuteStep => {
                     if !this.step()? {
                         // See if this thread can do something else.
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 7586b5efd4b..3349d2df0d5 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -163,6 +163,8 @@ pub struct MiriConfig {
     pub address_reuse_rate: f64,
     /// Probability for address reuse across threads.
     pub address_reuse_cross_thread_rate: f64,
+    /// Round Robin scheduling with no preemption.
+    pub fixed_scheduling: bool,
 }
 
 impl Default for MiriConfig {
@@ -200,6 +202,7 @@ impl Default for MiriConfig {
             collect_leak_backtraces: true,
             address_reuse_rate: 0.5,
             address_reuse_cross_thread_rate: 0.1,
+            fixed_scheduling: false,
         }
     }
 }
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index ea59d327be8..bbd170a8b27 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -669,7 +669,7 @@ impl<'tcx> MiriMachine<'tcx> {
             cpu_affinity::MAX_CPUS,
             config.num_cpus
         );
-        let threads = ThreadManager::default();
+        let threads = ThreadManager::new(config);
         let mut thread_cpu_affinity = FxHashMap::default();
         if matches!(&*tcx.sess.target.os, "linux" | "freebsd" | "android") {
             thread_cpu_affinity
diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs
index 53760b05a31..a3db0fd25dc 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs
@@ -1,6 +1,6 @@
 //@ignore-target: windows # No pthreads on Windows
 // We are making scheduler assumptions here.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 // Joining itself is undefined behavior.
 
diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs
index 3ee2bf14f9f..044d9a88ddc 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs
@@ -1,6 +1,6 @@
 //@only-target: windows # Uses win32 api functions
 // We are making scheduler assumptions here.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 //@error-in-other-file: deadlock
 
 // On windows, joining main is not UB, but it will block a thread forever.
diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs
index eee2979f3cf..812fab445d1 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs
@@ -1,6 +1,6 @@
 //@only-target: windows # Uses win32 api functions
 // We are making scheduler assumptions here.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 //@error-in-other-file: deadlock
 
 // On windows, a thread joining itself is not UB, but it will deadlock.
diff --git a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs
index 3a832bb0ce0..16706fd4744 100644
--- a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs
+++ b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-isolation -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-disable-isolation -Zmiri-fixed-schedule
 //@ignore-target: windows # No libc env support on Windows
 
 use std::{env, thread};
diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.rs b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.rs
index 0d893663fd6..168711d4d34 100644
--- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.rs
+++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.rs
@@ -1,7 +1,7 @@
 //@only-target: linux android illumos
 //~^ERROR: deadlocked
 //~^^ERROR: deadlocked
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 //@error-in-other-file: deadlock
 
 use std::thread;
diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.rs b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.rs
index 9fed47c17d4..cc71aaf1a14 100644
--- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.rs
+++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.rs
@@ -1,7 +1,7 @@
 //@only-target: linux android illumos
 //~^ERROR: deadlocked
 //~^^ERROR: deadlocked
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 //@error-in-other-file: deadlock
 
 use std::thread;
diff --git a/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs b/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs
index 45f6bf6da09..f9a4a4e5b2b 100644
--- a/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs
+++ b/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs
@@ -4,7 +4,7 @@
 //! to be considered synchronized.
 //@only-target: linux android illumos
 // ensure deterministic schedule
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 use std::convert::TryInto;
 use std::thread;
diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs
index 059b24cb8c0..c5c1db64037 100644
--- a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs
+++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 //~^ERROR: deadlocked
 //~^^ERROR: deadlocked
 //@only-target: linux android illumos
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.rs b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.rs
index 8413e118819..1f6bb430ab2 100644
--- a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.rs
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.rs
@@ -2,7 +2,7 @@
 //! faulty logic around `release_clock` that led to this code not reporting a data race.
 //~^^ERROR: deadlock
 //@ignore-target: windows # no libc socketpair on Windows
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-address-reuse-rate=0
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-address-reuse-rate=0
 //@error-in-other-file: deadlock
 use std::thread;
 
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs b/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs
index 55491da9f60..b864347e234 100644
--- a/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs
@@ -1,7 +1,7 @@
 //! This is a regression test for <https://github.com/rust-lang/miri/issues/3947>: we had some
 //! faulty logic around `release_clock` that led to this code not reporting a data race.
 //@ignore-target: windows # no libc socketpair on Windows
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-address-reuse-rate=0
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-address-reuse-rate=0
 use std::thread;
 
 fn main() {
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs
index d3e4c43f2b7..c7bcdd54ec7 100644
--- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs
@@ -2,7 +2,7 @@
 //~^ERROR: deadlocked
 //~^^ERROR: deadlocked
 // test_race depends on a deterministic schedule.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 //@error-in-other-file: deadlock
 
 use std::thread;
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs
index 4f951acb2c3..aaf9ead2000 100644
--- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs
@@ -2,7 +2,7 @@
 //~^ERROR: deadlocked
 //~^^ERROR: deadlocked
 // test_race depends on a deterministic schedule.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 //@error-in-other-file: deadlock
 
 use std::thread;
diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.rs b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.rs
index 0061679eaa4..09924cd61ac 100644
--- a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.rs
+++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.rs
@@ -1,6 +1,6 @@
 //! Make sure that a retag acts like a write for the data race model.
 //@revisions: stack tree
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 //@[tree]compile-flags: -Zmiri-tree-borrows
diff --git a/src/tools/miri/tests/fail/data_race/alloc_read_race.rs b/src/tools/miri/tests/fail/data_race/alloc_read_race.rs
index 312b7ba05d3..e3f60251121 100644
--- a/src/tools/miri/tests/fail/data_race/alloc_read_race.rs
+++ b/src/tools/miri/tests/fail/data_race/alloc_read_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/alloc_write_race.rs b/src/tools/miri/tests/fail/data_race/alloc_write_race.rs
index f1f308b37e7..0a010f68abb 100644
--- a/src/tools/miri/tests/fail/data_race/alloc_write_race.rs
+++ b/src/tools/miri/tests/fail/data_race/alloc_write_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs
index 4003892f0a6..de3bac474db 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs
index c67ce65eb34..123050331cd 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs
index 5e328740e85..88ce531a694 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs
index e0876a93fdd..963ce28065f 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs
index 1010216a497..cfbcec9cc2b 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs
index fdc0f9e20f0..1e76f0faa2a 100644
--- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs
index dffafe3cfaa..c9fa6a86443 100644
--- a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs
+++ b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs b/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs
index 8dc35c7ea72..d4bcc9abca3 100644
--- a/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs
+++ b/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs
index d0a28482054..f1458131c48 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
index f56c44cabc2..8a8595b97a0 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs
index c67e03d362b..de79076f59d 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs
index a16ea25e11c..d42a89eae3c 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
index f3855e33c98..a3d7770c2ce 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs
index 8e63bc1dc7b..770283a7be2 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs
index 53050608d27..6820ec46058 100644
--- a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs
+++ b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/fence_after_load.rs b/src/tools/miri/tests/fail/data_race/fence_after_load.rs
index 5dfb260c20b..df5730ae1bb 100644
--- a/src/tools/miri/tests/fail/data_race/fence_after_load.rs
+++ b/src/tools/miri/tests/fail/data_race/fence_after_load.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.rs b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.rs
index 751a308a399..208b974cc7b 100644
--- a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.rs
+++ b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-preemption-rate=0.0 -Zmiri-disable-weak-memory-emulation
+//@compile-flags:-Zmiri-fixed-schedule -Zmiri-disable-weak-memory-emulation
 #![feature(core_intrinsics)]
 #![feature(custom_mir)]
 
diff --git a/src/tools/miri/tests/fail/data_race/local_variable_read_race.rs b/src/tools/miri/tests/fail/data_race/local_variable_read_race.rs
index 16a23f595ee..4a622e5d1b9 100644
--- a/src/tools/miri/tests/fail/data_race/local_variable_read_race.rs
+++ b/src/tools/miri/tests/fail/data_race/local_variable_read_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-preemption-rate=0.0 -Zmiri-disable-weak-memory-emulation
+//@compile-flags:-Zmiri-fixed-schedule -Zmiri-disable-weak-memory-emulation
 use std::sync::atomic::Ordering::*;
 use std::sync::atomic::*;
 
diff --git a/src/tools/miri/tests/fail/data_race/local_variable_write_race.rs b/src/tools/miri/tests/fail/data_race/local_variable_write_race.rs
index 7e00573146c..e80f2a0c037 100644
--- a/src/tools/miri/tests/fail/data_race/local_variable_write_race.rs
+++ b/src/tools/miri/tests/fail/data_race/local_variable_write_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-preemption-rate=0.0 -Zmiri-disable-weak-memory-emulation
+//@compile-flags:-Zmiri-fixed-schedule -Zmiri-disable-weak-memory-emulation
 use std::sync::atomic::Ordering::*;
 use std::sync::atomic::*;
 
diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.rs b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.rs
index e76654806bb..6496fb30b76 100644
--- a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.rs
+++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-preemption-rate=0.0 -Zmiri-disable-weak-memory-emulation
+//@compile-flags:-Zmiri-fixed-schedule -Zmiri-disable-weak-memory-emulation
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 // Two variants: the atomic store matches the size of the first or second atomic load.
diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.rs b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.rs
index 53016bab780..08fe0965aef 100644
--- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.rs
+++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-preemption-rate=0.0 -Zmiri-disable-weak-memory-emulation
+//@compile-flags:-Zmiri-fixed-schedule -Zmiri-disable-weak-memory-emulation
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 // Two revisions, depending on which access goes first.
diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.rs b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.rs
index 545e354a037..dd3db5a11d8 100644
--- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.rs
+++ b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-preemption-rate=0.0 -Zmiri-disable-weak-memory-emulation
+//@compile-flags:-Zmiri-fixed-schedule -Zmiri-disable-weak-memory-emulation
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 //@revisions: fst snd
diff --git a/src/tools/miri/tests/fail/data_race/read_write_race.rs b/src/tools/miri/tests/fail/data_race/read_write_race.rs
index adf19dda9d3..dfe9de155ec 100644
--- a/src/tools/miri/tests/fail/data_race/read_write_race.rs
+++ b/src/tools/miri/tests/fail/data_race/read_write_race.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here. Stacked borrows interferes by having its own accesses.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs
index f411767f7b5..f02c0b23e52 100644
--- a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs
+++ b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs b/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs
index c4f94380822..1d9cebb6c74 100644
--- a/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs
+++ b/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race.rs b/src/tools/miri/tests/fail/data_race/release_seq_race.rs
index f03ab3efa06..36716050635 100644
--- a/src/tools/miri/tests/fail/data_race/release_seq_race.rs
+++ b/src/tools/miri/tests/fail/data_race/release_seq_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs
index 88ae01b3ca1..8c223ee4ac1 100644
--- a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs
+++ b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/rmw_race.rs b/src/tools/miri/tests/fail/data_race/rmw_race.rs
index d738caa1058..d06c13a8f7f 100644
--- a/src/tools/miri/tests/fail/data_race/rmw_race.rs
+++ b/src/tools/miri/tests/fail/data_race/rmw_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/stack_pop_race.rs b/src/tools/miri/tests/fail/data_race/stack_pop_race.rs
index 762a8e51f69..95d4145e5e7 100644
--- a/src/tools/miri/tests/fail/data_race/stack_pop_race.rs
+++ b/src/tools/miri/tests/fail/data_race/stack_pop_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/write_write_race.rs b/src/tools/miri/tests/fail/data_race/write_write_race.rs
index 993d8d25b4c..7d7516449c3 100644
--- a/src/tools/miri/tests/fail/data_race/write_write_race.rs
+++ b/src/tools/miri/tests/fail/data_race/write_write_race.rs
@@ -1,5 +1,5 @@
 // We want to control preemption here.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs
index 8070a7f4fc2..6707de52e3f 100644
--- a/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs
+++ b/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule -Zmiri-disable-stacked-borrows
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.rs b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.rs
index a6ee7b40c34..9fb910a3de4 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.rs
@@ -1,5 +1,5 @@
 // Avoid accidental synchronization via address reuse.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-address-reuse-cross-thread-rate=0
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-address-reuse-cross-thread-rate=0
 use std::thread;
 
 #[derive(Copy, Clone)]
diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.rs b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.rs
index 949f659e7e8..a91931312bc 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.rs
@@ -1,6 +1,6 @@
 //! Make sure that a retag acts like a read for the data race model.
 // Avoid accidental synchronization via address reuse.
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-address-reuse-cross-thread-rate=0
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-address-reuse-cross-thread-rate=0
 #[derive(Copy, Clone)]
 struct SendPtr(*mut u8);
 
diff --git a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.rs b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.rs
index 73f227fee2f..19c6e1bfcc1 100644
--- a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.rs
+++ b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.rs
@@ -1,7 +1,7 @@
 // Illustrating a problematic interaction between Reserved, interior mutability,
 // and protectors, that makes spurious writes fail in the previous model of Tree Borrows.
 // As for all similar tests, we disable preemption so that the error message is deterministic.
-//@compile-flags: -Zmiri-tree-borrows -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-tree-borrows -Zmiri-fixed-schedule
 //
 // One revision without spurious read (default source code) and one with spurious read.
 // Both are expected to be UB. Both revisions are expected to have the *same* error
diff --git a/src/tools/miri/tests/fail/tree_borrows/spurious_read.rs b/src/tools/miri/tests/fail/tree_borrows/spurious_read.rs
index 50ef0ceef91..19f56730f36 100644
--- a/src/tools/miri/tests/fail/tree_borrows/spurious_read.rs
+++ b/src/tools/miri/tests/fail/tree_borrows/spurious_read.rs
@@ -2,7 +2,7 @@
 // Note that we are *also* using barriers: the barriers enforce the
 // specific interleaving of operations that we want, but only the preemption
 // rate guarantees that the error message is also deterministic.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 //@compile-flags: -Zmiri-tree-borrows
 
 use std::sync::{Arc, Barrier};
diff --git a/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs b/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs
index 79c97a5b752..b4b4b084987 100644
--- a/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs
+++ b/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-ignore-leaks -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-ignore-leaks -Zmiri-fixed-schedule
 
 // Tests showing weak memory behaviours are exhibited. All tests
 // return true when the desired behaviour is seen.
diff --git a/src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs b/src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs
index becb90eb923..d7110466762 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs
@@ -1,5 +1,5 @@
 //@only-target: darwin
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 use std::time::{Duration, Instant};
 use std::{io, ptr, thread};
diff --git a/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs b/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs
index c9c9dc5dfd2..4c42e97b66c 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-isolation -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-disable-isolation -Zmiri-fixed-schedule
 //@ignore-target: windows # No libc env support on Windows
 
 use std::ffi::CStr;
diff --git a/src/tools/miri/tests/pass-dep/concurrency/freebsd-futex.rs b/src/tools/miri/tests/pass-dep/concurrency/freebsd-futex.rs
index 38a0bf58148..36dbb1bb4fd 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/freebsd-futex.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/freebsd-futex.rs
@@ -1,5 +1,5 @@
 //@only-target: freebsd
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-disable-isolation
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-disable-isolation
 
 use std::mem::{self, MaybeUninit};
 use std::ptr::{self, addr_of};
diff --git a/src/tools/miri/tests/pass-dep/concurrency/windows_detach_terminated.rs b/src/tools/miri/tests/pass-dep/concurrency/windows_detach_terminated.rs
index fe2d20bb76f..aabd542f7c7 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/windows_detach_terminated.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/windows_detach_terminated.rs
@@ -1,6 +1,6 @@
 //@only-target: windows # Uses win32 api functions
 // We are making scheduler assumptions here.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 use std::os::windows::io::IntoRawHandle;
 use std::thread;
diff --git a/src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs b/src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs
index 6853395686a..f02ad3d4edd 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs
@@ -1,6 +1,6 @@
 //@only-target: windows # Uses win32 api functions
 // We are making scheduler assumptions here.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 use std::ptr::null_mut;
 use std::thread;
diff --git a/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs b/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs
index 2796541a3d7..5a62c41927a 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs
@@ -1,6 +1,6 @@
 //@only-target: windows # Uses win32 api functions
 // We are making scheduler assumptions here.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 use std::os::windows::io::IntoRawHandle;
 use std::sync::atomic::{AtomicBool, Ordering};
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs
index 825e1355848..ae9bf6995e6 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs
@@ -1,6 +1,6 @@
 //@only-target: linux android illumos
 // test_epoll_block_then_unblock and test_epoll_race depend on a deterministic schedule.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 use std::convert::TryInto;
 use std::thread;
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs b/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs
index 30e1bbb8fa1..12e12aa7138 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs
@@ -1,6 +1,6 @@
 //@only-target: linux android illumos
 // test_race, test_blocking_read and test_blocking_write depend on a deterministic schedule.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
 #![allow(static_mut_refs)]
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
index d6072c2569e..71e0467b3eb 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
@@ -1,6 +1,6 @@
 //@ignore-target: windows # No libc pipe on Windows
 // test_race depends on a deterministic schedule.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 use std::thread;
 fn main() {
     test_pipe();
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs
index 9163fd3d06f..f4277791aeb 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs
@@ -1,6 +1,6 @@
 //@ignore-target: windows # No libc socketpair on Windows
 // test_race depends on a deterministic schedule.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
 #![allow(static_mut_refs)]
diff --git a/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs b/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs
index fa11b5b1299..fae517f8e19 100644
--- a/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs
+++ b/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs
@@ -1,6 +1,6 @@
 //@ignore-target: windows # No pthreads on Windows
 // We use `yield` to test specific interleavings, so disable automatic preemption.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 #![feature(sync_unsafe_cell)]
 
 use std::cell::SyncUnsafeCell;
diff --git a/src/tools/miri/tests/pass/concurrency/data_race.rs b/src/tools/miri/tests/pass/concurrency/data_race.rs
index d16de0ae8e2..76b31a76ccf 100644
--- a/src/tools/miri/tests/pass/concurrency/data_race.rs
+++ b/src/tools/miri/tests/pass/concurrency/data_race.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-fixed-schedule
 
 use std::sync::atomic::*;
 use std::thread::{self, spawn};
diff --git a/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs b/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs
index 354a4bef932..968d5237ead 100644
--- a/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs
+++ b/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs
@@ -1,6 +1,6 @@
 //@compile-flags: -Zmiri-disable-data-race-detector
 // Avoid non-determinism
-//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-address-reuse-cross-thread-rate=0
+//@compile-flags: -Zmiri-fixed-schedule -Zmiri-address-reuse-cross-thread-rate=0
 
 use std::thread::spawn;
 
diff --git a/src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs b/src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs
index 44b16e1ac74..55d6e0660c9 100644
--- a/src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs
+++ b/src/tools/miri/tests/pass/concurrency/spin_loops_nopreempt.rs
@@ -1,5 +1,5 @@
 // This specifically tests behavior *without* preemption.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 use std::cell::Cell;
 use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
diff --git a/src/tools/miri/tests/pass/concurrency/sync.rs b/src/tools/miri/tests/pass/concurrency/sync.rs
index 91c67b215a1..6e726ee0e09 100644
--- a/src/tools/miri/tests/pass/concurrency/sync.rs
+++ b/src/tools/miri/tests/pass/concurrency/sync.rs
@@ -1,7 +1,7 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
 // We use `yield` to test specific interleavings, so disable automatic preemption.
-//@compile-flags: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-fixed-schedule
 
 use std::sync::{Arc, Barrier, Condvar, Mutex, Once, RwLock};
 use std::thread;
diff --git a/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs b/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs
index c6cff038f81..7c465d7ad56 100644
--- a/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs
+++ b/src/tools/miri/tests/pass/concurrency/sync_nopreempt.rs
@@ -1,5 +1,5 @@
 // We are making scheduler assumptions here.
-//@compile-flags: -Zmiri-strict-provenance -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-strict-provenance -Zmiri-fixed-schedule
 
 use std::sync::{Arc, Condvar, Mutex, RwLock};
 use std::thread;
diff --git a/src/tools/miri/tests/pass/panic/concurrent-panic.rs b/src/tools/miri/tests/pass/panic/concurrent-panic.rs
index e804df90977..d4d5eecd912 100644
--- a/src/tools/miri/tests/pass/panic/concurrent-panic.rs
+++ b/src/tools/miri/tests/pass/panic/concurrent-panic.rs
@@ -1,5 +1,5 @@
 // We are making scheduler assumptions here.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 
 //! Cause a panic in one thread while another thread is unwinding. This checks
 //! that separate threads have their own panicking state.
diff --git a/src/tools/miri/tests/pass/shims/env/var.rs b/src/tools/miri/tests/pass/shims/env/var.rs
index 655b29674e3..44eb69cc684 100644
--- a/src/tools/miri/tests/pass/shims/env/var.rs
+++ b/src/tools/miri/tests/pass/shims/env/var.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 use std::{env, thread};
 
 fn main() {
diff --git a/src/tools/miri/tests/pass/tree_borrows/read_retag_no_race.rs b/src/tools/miri/tests/pass/tree_borrows/read_retag_no_race.rs
index d9897a1033f..19f90e5ee12 100644
--- a/src/tools/miri/tests/pass/tree_borrows/read_retag_no_race.rs
+++ b/src/tools/miri/tests/pass/tree_borrows/read_retag_no_race.rs
@@ -2,7 +2,7 @@
 // This test relies on a specific interleaving that cannot be enforced
 // with just barriers. We must remove preemption so that the execution and the
 // error messages are deterministic.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 use std::ptr::addr_of_mut;
 use std::sync::{Arc, Barrier};
 use std::thread;
diff --git a/src/tools/miri/tests/pass/tree_borrows/spurious_read.rs b/src/tools/miri/tests/pass/tree_borrows/spurious_read.rs
index 71e93d2f84f..061a5dd9e8e 100644
--- a/src/tools/miri/tests/pass/tree_borrows/spurious_read.rs
+++ b/src/tools/miri/tests/pass/tree_borrows/spurious_read.rs
@@ -2,7 +2,7 @@
 // Note that we are *also* using barriers: the barriers enforce the
 // specific interleaving of operations that we want, but only the preemption
 // rate guarantees that the error message is also deterministic.
-//@compile-flags: -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-fixed-schedule
 //@compile-flags: -Zmiri-tree-borrows
 
 use std::sync::{Arc, Barrier};
diff --git a/src/tools/miri/tests/pass/weak_memory/weak.rs b/src/tools/miri/tests/pass/weak_memory/weak.rs
index 5d636431d86..eeab4ebf129 100644
--- a/src/tools/miri/tests/pass/weak_memory/weak.rs
+++ b/src/tools/miri/tests/pass/weak_memory/weak.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmiri-ignore-leaks -Zmiri-preemption-rate=0
+//@compile-flags: -Zmiri-ignore-leaks -Zmiri-fixed-schedule
 
 // Tests showing weak memory behaviours are exhibited. All tests
 // return true when the desired behaviour is seen.