about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-03-28 14:48:13 +0100
committerRalf Jung <post@ralfj.de>2025-03-28 14:51:15 +0100
commit65bf8a8866557408b9e23ce3a99ec44c29dcb625 (patch)
treee2d8a0cad7199505c11bf7083fbe2fbbd3f231ab
parentab8836f548b3833ec985e46c48409870c0a5cbfd (diff)
downloadrust-65bf8a8866557408b9e23ce3a99ec44c29dcb625.tar.gz
rust-65bf8a8866557408b9e23ce3a99ec44c29dcb625.zip
machine clock: make 'monotonic' explicit
-rw-r--r--src/tools/miri/src/clock.rs30
-rw-r--r--src/tools/miri/src/concurrency/thread.rs16
-rw-r--r--src/tools/miri/src/lib.rs2
-rw-r--r--src/tools/miri/src/machine.rs8
-rw-r--r--src/tools/miri/src/shims/time.rs8
5 files changed, 34 insertions, 30 deletions
diff --git a/src/tools/miri/src/clock.rs b/src/tools/miri/src/clock.rs
index c9bffc449f7..34465e9cac6 100644
--- a/src/tools/miri/src/clock.rs
+++ b/src/tools/miri/src/clock.rs
@@ -62,12 +62,12 @@ impl Instant {
 
 /// A monotone clock used for `Instant` simulation.
 #[derive(Debug)]
-pub struct Clock {
-    kind: ClockKind,
+pub struct MonotonicClock {
+    kind: MonotonicClockKind,
 }
 
 #[derive(Debug)]
-enum ClockKind {
+enum MonotonicClockKind {
     Host {
         /// The "epoch" for this machine's monotone clock:
         /// the moment we consider to be time = 0.
@@ -79,13 +79,13 @@ enum ClockKind {
     },
 }
 
-impl Clock {
+impl MonotonicClock {
     /// Create a new clock based on the availability of communication with the host.
     pub fn new(communicate: bool) -> Self {
         let kind = if communicate {
-            ClockKind::Host { epoch: StdInstant::now() }
+            MonotonicClockKind::Host { epoch: StdInstant::now() }
         } else {
-            ClockKind::Virtual { nanoseconds: 0.into() }
+            MonotonicClockKind::Virtual { nanoseconds: 0.into() }
         };
 
         Self { kind }
@@ -94,10 +94,10 @@ impl Clock {
     /// Let the time pass for a small interval.
     pub fn tick(&self) {
         match &self.kind {
-            ClockKind::Host { .. } => {
+            MonotonicClockKind::Host { .. } => {
                 // Time will pass without us doing anything.
             }
-            ClockKind::Virtual { nanoseconds } => {
+            MonotonicClockKind::Virtual { nanoseconds } => {
                 nanoseconds.update(|x| x + NANOSECONDS_PER_BASIC_BLOCK);
             }
         }
@@ -106,8 +106,8 @@ impl Clock {
     /// Sleep for the desired duration.
     pub fn sleep(&self, duration: Duration) {
         match &self.kind {
-            ClockKind::Host { .. } => std::thread::sleep(duration),
-            ClockKind::Virtual { nanoseconds } => {
+            MonotonicClockKind::Host { .. } => std::thread::sleep(duration),
+            MonotonicClockKind::Virtual { nanoseconds } => {
                 // Just pretend that we have slept for some time.
                 let nanos: u128 = duration.as_nanos();
                 nanoseconds.update(|x| {
@@ -121,15 +121,17 @@ impl Clock {
     /// Return the `epoch` instant (time = 0), to convert between monotone instants and absolute durations.
     pub fn epoch(&self) -> Instant {
         match &self.kind {
-            ClockKind::Host { epoch } => Instant { kind: InstantKind::Host(*epoch) },
-            ClockKind::Virtual { .. } => Instant { kind: InstantKind::Virtual { nanoseconds: 0 } },
+            MonotonicClockKind::Host { epoch } => Instant { kind: InstantKind::Host(*epoch) },
+            MonotonicClockKind::Virtual { .. } =>
+                Instant { kind: InstantKind::Virtual { nanoseconds: 0 } },
         }
     }
 
     pub fn now(&self) -> Instant {
         match &self.kind {
-            ClockKind::Host { .. } => Instant { kind: InstantKind::Host(StdInstant::now()) },
-            ClockKind::Virtual { nanoseconds } =>
+            MonotonicClockKind::Host { .. } =>
+                Instant { kind: InstantKind::Host(StdInstant::now()) },
+            MonotonicClockKind::Virtual { nanoseconds } =>
                 Instant { kind: InstantKind::Virtual { nanoseconds: nanoseconds.get() } },
         }
     }
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 94629964ea6..72fa918e8e5 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -347,7 +347,7 @@ enum Timeout {
 
 impl Timeout {
     /// How long do we have to wait from now until the specified time?
-    fn get_wait_time(&self, clock: &Clock) -> Duration {
+    fn get_wait_time(&self, clock: &MonotonicClock) -> Duration {
         match self {
             Timeout::Monotonic(instant) => instant.duration_since(clock.now()),
             Timeout::RealTime(time) =>
@@ -683,7 +683,7 @@ impl<'tcx> ThreadManager<'tcx> {
     }
 
     /// Get the wait time for the next timeout, or `None` if no timeout is pending.
-    fn next_callback_wait_time(&self, clock: &Clock) -> Option<Duration> {
+    fn next_callback_wait_time(&self, clock: &MonotonicClock) -> Option<Duration> {
         self.threads
             .iter()
             .filter_map(|t| {
@@ -702,7 +702,7 @@ 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: &Clock) -> InterpResult<'tcx, SchedulingAction> {
+    fn schedule(&mut self, clock: &MonotonicClock) -> 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.
@@ -772,7 +772,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
         for (id, thread) in this.machine.threads.threads.iter_enumerated_mut() {
             match &thread.state {
                 ThreadState::Blocked { timeout: Some(timeout), .. }
-                    if timeout.get_wait_time(&this.machine.clock) == Duration::ZERO =>
+                    if timeout.get_wait_time(&this.machine.monotonic_clock) == Duration::ZERO =>
                 {
                     let old_state = mem::replace(&mut thread.state, ThreadState::Enabled);
                     let ThreadState::Blocked { callback, .. } = old_state else { unreachable!() };
@@ -1006,8 +1006,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
                 TimeoutClock::Monotonic =>
                     Timeout::Monotonic(match anchor {
-                        TimeoutAnchor::Absolute => this.machine.clock.epoch(),
-                        TimeoutAnchor::Relative => this.machine.clock.now(),
+                        TimeoutAnchor::Absolute => this.machine.monotonic_clock.epoch(),
+                        TimeoutAnchor::Relative => this.machine.monotonic_clock.now(),
                     }),
             };
             anchor.add_lossy(duration)
@@ -1152,7 +1152,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.machine.handle_abnormal_termination();
                 throw_machine_stop!(TerminationInfo::Interrupted);
             }
-            match this.machine.threads.schedule(&this.machine.clock)? {
+            match this.machine.threads.schedule(&this.machine.monotonic_clock)? {
                 SchedulingAction::ExecuteStep => {
                     if !this.step()? {
                         // See if this thread can do something else.
@@ -1167,7 +1167,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     this.run_timeout_callback()?;
                 }
                 SchedulingAction::Sleep(duration) => {
-                    this.machine.clock.sleep(duration);
+                    this.machine.monotonic_clock.sleep(duration);
                 }
             }
         }
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 03f76cfa652..5921ba86639 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -121,7 +121,7 @@ pub use crate::borrow_tracker::stacked_borrows::{
 };
 pub use crate::borrow_tracker::tree_borrows::{EvalContextExt as _, Tree};
 pub use crate::borrow_tracker::{BorTag, BorrowTrackerMethod, EvalContextExt as _, RetagFields};
-pub use crate::clock::{Clock, Instant};
+pub use crate::clock::{Instant, MonotonicClock};
 pub use crate::concurrency::cpu_affinity::MAX_CPUS;
 pub use crate::concurrency::data_race::{
     AtomicFenceOrd, AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd, EvalContextExt as _,
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index bd901a4ed19..3de20f92afa 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -486,7 +486,7 @@ pub struct MiriMachine<'tcx> {
     pub(crate) epoll_interests: shims::EpollInterestTable,
 
     /// This machine's monotone clock.
-    pub(crate) clock: Clock,
+    pub(crate) monotonic_clock: MonotonicClock,
 
     /// The set of threads.
     pub(crate) threads: ThreadManager<'tcx>,
@@ -710,7 +710,7 @@ impl<'tcx> MiriMachine<'tcx> {
             preemption_rate: config.preemption_rate,
             report_progress: config.report_progress,
             basic_block_count: 0,
-            clock: Clock::new(config.isolated_op == IsolatedOp::Allow),
+            monotonic_clock: MonotonicClock::new(config.isolated_op == IsolatedOp::Allow),
             #[cfg(unix)]
             native_lib: config.native_lib.as_ref().map(|lib_file_path| {
                 let host_triple = rustc_session::config::host_tuple();
@@ -892,7 +892,7 @@ impl VisitProvenance for MiriMachine<'_> {
             tcx: _,
             isolated_op: _,
             validation: _,
-            clock: _,
+            monotonic_clock: _,
             layouts: _,
             static_roots: _,
             profiler: _,
@@ -1563,7 +1563,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         ecx.maybe_preempt_active_thread();
 
         // Make sure some time passes.
-        ecx.machine.clock.tick();
+        ecx.machine.monotonic_clock.tick();
 
         interp_ok(())
     }
diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs
index 64b3ce6b4e4..d7c445b47cb 100644
--- a/src/tools/miri/src/shims/time.rs
+++ b/src/tools/miri/src/shims/time.rs
@@ -79,7 +79,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             this.check_no_isolation("`clock_gettime` with `REALTIME` clocks")?;
             system_time_to_duration(&SystemTime::now())?
         } else if relative_clocks.contains(&clk_id) {
-            this.machine.clock.now().duration_since(this.machine.clock.epoch())
+            this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch())
         } else {
             return this.set_last_error_and_return_i32(LibcError("EINVAL"));
         };
@@ -248,7 +248,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         // QueryPerformanceCounter uses a hardware counter as its basis.
         // Miri will emulate a counter with a resolution of 1 nanosecond.
-        let duration = this.machine.clock.now().duration_since(this.machine.clock.epoch());
+        let duration =
+            this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch());
         let qpc = i64::try_from(duration.as_nanos()).map_err(|_| {
             err_unsup_format!("programs running longer than 2^63 nanoseconds are not supported")
         })?;
@@ -287,7 +288,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         // This returns a u64, with time units determined dynamically by `mach_timebase_info`.
         // We return plain nanoseconds.
-        let duration = this.machine.clock.now().duration_since(this.machine.clock.epoch());
+        let duration =
+            this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch());
         let res = u64::try_from(duration.as_nanos()).map_err(|_| {
             err_unsup_format!("programs running longer than 2^64 nanoseconds are not supported")
         })?;