diff --git a/src/tools/miri/src/clock.rs b/src/tools/miri/src/clock.rs index c9bffc449f7f..34465e9cac60 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 94629964ea60..72fa918e8e51 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 { + fn next_callback_wait_time(&self, clock: &MonotonicClock) -> Option { 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 03f76cfa6524..5921ba866390 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 bd901a4ed19e..3de20f92afa4 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 64b3ce6b4e49..d7c445b47cb0 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") })?;