Skip to content

Commit 4608b94

Browse files
committed
implement CLOCK_MONOTONIC on Linux
1 parent 0ff05c4 commit 4608b94

File tree

4 files changed

+35
-26
lines changed

4 files changed

+35
-26
lines changed

src/machine.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::borrow::Cow;
55
use std::cell::RefCell;
66
use std::num::NonZeroU64;
77
use std::rc::Rc;
8+
use std::time::Instant;
89

910
use rand::rngs::StdRng;
1011

@@ -164,6 +165,9 @@ pub struct Evaluator<'tcx> {
164165
/// the call to `miri_start_panic` (the panic payload) when unwinding.
165166
/// This is pointer-sized, and matches the `Payload` type in `src/libpanic_unwind/miri.rs`.
166167
pub(crate) panic_payload: Option<Scalar<Tag>>,
168+
169+
/// The "time anchor" for this machine's monotone clock (for `Instant` simulation).
170+
pub(crate) time_anchor: Instant,
167171
}
168172

169173
impl<'tcx> Evaluator<'tcx> {
@@ -182,6 +186,7 @@ impl<'tcx> Evaluator<'tcx> {
182186
file_handler: Default::default(),
183187
dir_handler: Default::default(),
184188
panic_payload: None,
189+
time_anchor: Instant::now(),
185190
}
186191
}
187192
}

src/shims/time.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
use std::time::{Duration, SystemTime};
1+
use std::time::{Duration, SystemTime, Instant};
22

33
use crate::stacked_borrows::Tag;
44
use crate::*;
55
use helpers::immty_from_int_checked;
66

7-
// Returns the time elapsed between now and the unix epoch as a `Duration`.
8-
fn get_time<'tcx>() -> InterpResult<'tcx, Duration> {
9-
system_time_to_duration(&SystemTime::now())
10-
}
11-
127
/// Returns the time elapsed between the provided time and the unix epoch as a `Duration`.
138
pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Duration> {
149
time.duration_since(SystemTime::UNIX_EPOCH)
@@ -28,15 +23,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2823
this.check_no_isolation("clock_gettime")?;
2924

3025
let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
31-
if clk_id != this.eval_libc_i32("CLOCK_REALTIME")? {
26+
let tp = this.deref_operand(tp_op)?;
27+
28+
let duration = if clk_id == this.eval_libc_i32("CLOCK_REALTIME")? {
29+
system_time_to_duration(&SystemTime::now())?
30+
} else if clk_id == this.eval_libc_i32("CLOCK_MONOTONIC")? {
31+
// Absolute time does not matter, only relative time does, so we can just
32+
// use our own time anchor here.
33+
Instant::now().duration_since(this.machine.time_anchor)
34+
} else {
3235
let einval = this.eval_libc("EINVAL")?;
3336
this.set_last_error(einval)?;
3437
return Ok(-1);
35-
}
36-
37-
let tp = this.deref_operand(tp_op)?;
38+
};
3839

39-
let duration = get_time()?;
4040
let tv_sec = duration.as_secs();
4141
let tv_nsec = duration.subsec_nanos();
4242

@@ -68,7 +68,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6868

6969
let tv = this.deref_operand(tv_op)?;
7070

71-
let duration = get_time()?;
71+
let duration = system_time_to_duration(&SystemTime::now())?;
7272
let tv_sec = duration.as_secs();
7373
let tv_usec = duration.subsec_micros();
7474

tests/run-pass/clock.rs

Lines changed: 0 additions & 14 deletions
This file was deleted.

tests/run-pass/time.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// ignore-windows: TODO clock shims are not implemented on Windows
2+
// compile-flags: -Zmiri-disable-isolation
3+
4+
use std::time::{SystemTime, Instant};
5+
6+
fn main() {
7+
let now1 = SystemTime::now();
8+
// Do some work to make time pass.
9+
for _ in 0..10 { drop(vec![42]); }
10+
let now2 = SystemTime::now();
11+
assert!(now2 > now1);
12+
13+
let now1 = Instant::now();
14+
// Do some work to make time pass.
15+
for _ in 0..10 { drop(vec![42]); }
16+
let now2 = Instant::now();
17+
assert!(now2 > now1);
18+
}

0 commit comments

Comments
 (0)