Skip to content

Commit 99ce8fc

Browse files
authored
Merge pull request rust-lang#4242 from RalfJung/clock-names
machine clock: make 'monotonic' explicit
2 parents 7310925 + 65bf8a8 commit 99ce8fc

File tree

5 files changed

+34
-30
lines changed

5 files changed

+34
-30
lines changed

src/tools/miri/src/clock.rs

+16-14
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ impl Instant {
6262

6363
/// A monotone clock used for `Instant` simulation.
6464
#[derive(Debug)]
65-
pub struct Clock {
66-
kind: ClockKind,
65+
pub struct MonotonicClock {
66+
kind: MonotonicClockKind,
6767
}
6868

6969
#[derive(Debug)]
70-
enum ClockKind {
70+
enum MonotonicClockKind {
7171
Host {
7272
/// The "epoch" for this machine's monotone clock:
7373
/// the moment we consider to be time = 0.
@@ -79,13 +79,13 @@ enum ClockKind {
7979
},
8080
}
8181

82-
impl Clock {
82+
impl MonotonicClock {
8383
/// Create a new clock based on the availability of communication with the host.
8484
pub fn new(communicate: bool) -> Self {
8585
let kind = if communicate {
86-
ClockKind::Host { epoch: StdInstant::now() }
86+
MonotonicClockKind::Host { epoch: StdInstant::now() }
8787
} else {
88-
ClockKind::Virtual { nanoseconds: 0.into() }
88+
MonotonicClockKind::Virtual { nanoseconds: 0.into() }
8989
};
9090

9191
Self { kind }
@@ -94,10 +94,10 @@ impl Clock {
9494
/// Let the time pass for a small interval.
9595
pub fn tick(&self) {
9696
match &self.kind {
97-
ClockKind::Host { .. } => {
97+
MonotonicClockKind::Host { .. } => {
9898
// Time will pass without us doing anything.
9999
}
100-
ClockKind::Virtual { nanoseconds } => {
100+
MonotonicClockKind::Virtual { nanoseconds } => {
101101
nanoseconds.update(|x| x + NANOSECONDS_PER_BASIC_BLOCK);
102102
}
103103
}
@@ -106,8 +106,8 @@ impl Clock {
106106
/// Sleep for the desired duration.
107107
pub fn sleep(&self, duration: Duration) {
108108
match &self.kind {
109-
ClockKind::Host { .. } => std::thread::sleep(duration),
110-
ClockKind::Virtual { nanoseconds } => {
109+
MonotonicClockKind::Host { .. } => std::thread::sleep(duration),
110+
MonotonicClockKind::Virtual { nanoseconds } => {
111111
// Just pretend that we have slept for some time.
112112
let nanos: u128 = duration.as_nanos();
113113
nanoseconds.update(|x| {
@@ -121,15 +121,17 @@ impl Clock {
121121
/// Return the `epoch` instant (time = 0), to convert between monotone instants and absolute durations.
122122
pub fn epoch(&self) -> Instant {
123123
match &self.kind {
124-
ClockKind::Host { epoch } => Instant { kind: InstantKind::Host(*epoch) },
125-
ClockKind::Virtual { .. } => Instant { kind: InstantKind::Virtual { nanoseconds: 0 } },
124+
MonotonicClockKind::Host { epoch } => Instant { kind: InstantKind::Host(*epoch) },
125+
MonotonicClockKind::Virtual { .. } =>
126+
Instant { kind: InstantKind::Virtual { nanoseconds: 0 } },
126127
}
127128
}
128129

129130
pub fn now(&self) -> Instant {
130131
match &self.kind {
131-
ClockKind::Host { .. } => Instant { kind: InstantKind::Host(StdInstant::now()) },
132-
ClockKind::Virtual { nanoseconds } =>
132+
MonotonicClockKind::Host { .. } =>
133+
Instant { kind: InstantKind::Host(StdInstant::now()) },
134+
MonotonicClockKind::Virtual { nanoseconds } =>
133135
Instant { kind: InstantKind::Virtual { nanoseconds: nanoseconds.get() } },
134136
}
135137
}

src/tools/miri/src/concurrency/thread.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ enum Timeout {
347347

348348
impl Timeout {
349349
/// How long do we have to wait from now until the specified time?
350-
fn get_wait_time(&self, clock: &Clock) -> Duration {
350+
fn get_wait_time(&self, clock: &MonotonicClock) -> Duration {
351351
match self {
352352
Timeout::Monotonic(instant) => instant.duration_since(clock.now()),
353353
Timeout::RealTime(time) =>
@@ -683,7 +683,7 @@ impl<'tcx> ThreadManager<'tcx> {
683683
}
684684

685685
/// Get the wait time for the next timeout, or `None` if no timeout is pending.
686-
fn next_callback_wait_time(&self, clock: &Clock) -> Option<Duration> {
686+
fn next_callback_wait_time(&self, clock: &MonotonicClock) -> Option<Duration> {
687687
self.threads
688688
.iter()
689689
.filter_map(|t| {
@@ -702,7 +702,7 @@ impl<'tcx> ThreadManager<'tcx> {
702702
/// used in stateless model checkers such as Loom: run the active thread as
703703
/// long as we can and switch only when we have to (the active thread was
704704
/// blocked, terminated, or has explicitly asked to be preempted).
705-
fn schedule(&mut self, clock: &Clock) -> InterpResult<'tcx, SchedulingAction> {
705+
fn schedule(&mut self, clock: &MonotonicClock) -> InterpResult<'tcx, SchedulingAction> {
706706
// This thread and the program can keep going.
707707
if self.threads[self.active_thread].state.is_enabled() && !self.yield_active_thread {
708708
// The currently active thread is still enabled, just continue with it.
@@ -772,7 +772,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
772772
for (id, thread) in this.machine.threads.threads.iter_enumerated_mut() {
773773
match &thread.state {
774774
ThreadState::Blocked { timeout: Some(timeout), .. }
775-
if timeout.get_wait_time(&this.machine.clock) == Duration::ZERO =>
775+
if timeout.get_wait_time(&this.machine.monotonic_clock) == Duration::ZERO =>
776776
{
777777
let old_state = mem::replace(&mut thread.state, ThreadState::Enabled);
778778
let ThreadState::Blocked { callback, .. } = old_state else { unreachable!() };
@@ -1006,8 +1006,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10061006
}
10071007
TimeoutClock::Monotonic =>
10081008
Timeout::Monotonic(match anchor {
1009-
TimeoutAnchor::Absolute => this.machine.clock.epoch(),
1010-
TimeoutAnchor::Relative => this.machine.clock.now(),
1009+
TimeoutAnchor::Absolute => this.machine.monotonic_clock.epoch(),
1010+
TimeoutAnchor::Relative => this.machine.monotonic_clock.now(),
10111011
}),
10121012
};
10131013
anchor.add_lossy(duration)
@@ -1152,7 +1152,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11521152
this.machine.handle_abnormal_termination();
11531153
throw_machine_stop!(TerminationInfo::Interrupted);
11541154
}
1155-
match this.machine.threads.schedule(&this.machine.clock)? {
1155+
match this.machine.threads.schedule(&this.machine.monotonic_clock)? {
11561156
SchedulingAction::ExecuteStep => {
11571157
if !this.step()? {
11581158
// See if this thread can do something else.
@@ -1167,7 +1167,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11671167
this.run_timeout_callback()?;
11681168
}
11691169
SchedulingAction::Sleep(duration) => {
1170-
this.machine.clock.sleep(duration);
1170+
this.machine.monotonic_clock.sleep(duration);
11711171
}
11721172
}
11731173
}

src/tools/miri/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ pub use crate::borrow_tracker::stacked_borrows::{
121121
};
122122
pub use crate::borrow_tracker::tree_borrows::{EvalContextExt as _, Tree};
123123
pub use crate::borrow_tracker::{BorTag, BorrowTrackerMethod, EvalContextExt as _, RetagFields};
124-
pub use crate::clock::{Clock, Instant};
124+
pub use crate::clock::{Instant, MonotonicClock};
125125
pub use crate::concurrency::cpu_affinity::MAX_CPUS;
126126
pub use crate::concurrency::data_race::{
127127
AtomicFenceOrd, AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd, EvalContextExt as _,

src/tools/miri/src/machine.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ pub struct MiriMachine<'tcx> {
486486
pub(crate) epoll_interests: shims::EpollInterestTable,
487487

488488
/// This machine's monotone clock.
489-
pub(crate) clock: Clock,
489+
pub(crate) monotonic_clock: MonotonicClock,
490490

491491
/// The set of threads.
492492
pub(crate) threads: ThreadManager<'tcx>,
@@ -713,7 +713,7 @@ impl<'tcx> MiriMachine<'tcx> {
713713
preemption_rate: config.preemption_rate,
714714
report_progress: config.report_progress,
715715
basic_block_count: 0,
716-
clock: Clock::new(config.isolated_op == IsolatedOp::Allow),
716+
monotonic_clock: MonotonicClock::new(config.isolated_op == IsolatedOp::Allow),
717717
#[cfg(unix)]
718718
native_lib: config.native_lib.as_ref().map(|lib_file_path| {
719719
let host_triple = rustc_session::config::host_tuple();
@@ -896,7 +896,7 @@ impl VisitProvenance for MiriMachine<'_> {
896896
tcx: _,
897897
isolated_op: _,
898898
validation: _,
899-
clock: _,
899+
monotonic_clock: _,
900900
layouts: _,
901901
static_roots: _,
902902
profiler: _,
@@ -1568,7 +1568,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
15681568
ecx.maybe_preempt_active_thread();
15691569

15701570
// Make sure some time passes.
1571-
ecx.machine.clock.tick();
1571+
ecx.machine.monotonic_clock.tick();
15721572

15731573
interp_ok(())
15741574
}

src/tools/miri/src/shims/time.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
7979
this.check_no_isolation("`clock_gettime` with `REALTIME` clocks")?;
8080
system_time_to_duration(&SystemTime::now())?
8181
} else if relative_clocks.contains(&clk_id) {
82-
this.machine.clock.now().duration_since(this.machine.clock.epoch())
82+
this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch())
8383
} else {
8484
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
8585
};
@@ -248,7 +248,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
248248

249249
// QueryPerformanceCounter uses a hardware counter as its basis.
250250
// Miri will emulate a counter with a resolution of 1 nanosecond.
251-
let duration = this.machine.clock.now().duration_since(this.machine.clock.epoch());
251+
let duration =
252+
this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch());
252253
let qpc = i64::try_from(duration.as_nanos()).map_err(|_| {
253254
err_unsup_format!("programs running longer than 2^63 nanoseconds are not supported")
254255
})?;
@@ -287,7 +288,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
287288

288289
// This returns a u64, with time units determined dynamically by `mach_timebase_info`.
289290
// We return plain nanoseconds.
290-
let duration = this.machine.clock.now().duration_since(this.machine.clock.epoch());
291+
let duration =
292+
this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch());
291293
let res = u64::try_from(duration.as_nanos()).map_err(|_| {
292294
err_unsup_format!("programs running longer than 2^64 nanoseconds are not supported")
293295
})?;

0 commit comments

Comments
 (0)