Update the virtual clock in isolation mode to step forward with around the same speed as the host system.

This commit is contained in:
Oli Scherer 2023-03-15 11:23:50 +00:00
parent 3831a25490
commit abc824fd25
5 changed files with 27 additions and 6 deletions

View file

@ -3,7 +3,10 @@ use std::time::{Duration, Instant as StdInstant};
/// When using a virtual clock, this defines how many nanoseconds we pretend are passing for each
/// basic block.
const NANOSECONDS_PER_BASIC_BLOCK: u64 = 10;
/// This number is pretty random, but it has been shown to approximately cause
/// some sample programs to run within an order of magnitude of real time on desktop CPUs.
/// (See `tests/pass/shims/time-with-isolation*.rs`.)
const NANOSECONDS_PER_BASIC_BLOCK: u64 = 5000;
#[derive(Debug)]
pub struct Instant {

View file

@ -7,6 +7,6 @@ fn main() {
thread::park_timeout(Duration::from_millis(200));
// Thanks to deterministic execution, this will wiat *exactly* 200ms (rounded to 1ms).
assert!((200..201).contains(&start.elapsed().as_millis()));
// Thanks to deterministic execution, this will wait *exactly* 200ms, plus the time for the surrounding code.
assert!((200..210).contains(&start.elapsed().as_millis()), "{}", start.elapsed().as_millis());
}

View file

@ -22,14 +22,23 @@ fn test_time_passes() {
let diff = now2.duration_since(now1);
assert_eq!(now1 + diff, now2);
assert_eq!(now2 - diff, now1);
// The virtual clock is deterministic and I got 29us on a 64-bit Linux machine. However, this
// The virtual clock is deterministic and I got 15ms on a 64-bit Linux machine. However, this
// changes according to the platform so we use an interval to be safe. This should be updated
// if `NANOSECONDS_PER_BASIC_BLOCK` changes.
assert!(diff.as_micros() > 10);
assert!(diff.as_micros() < 40);
assert!(diff.as_millis() > 5);
assert!(diff.as_millis() < 20);
}
fn test_block_for_one_second() {
let end = Instant::now() + Duration::from_secs(1);
// This takes a long time, as we only increment when statements are executed.
// When we sleep on all threads, we fast forward to the sleep duration, which we can't
// do with busy waiting.
while Instant::now() < end {}
}
fn main() {
test_time_passes();
test_block_for_one_second();
test_sleep();
}

View file

@ -0,0 +1,8 @@
use std::time::Instant;
fn main() {
let begin = Instant::now();
for _ in 0..100_000 {}
let time = begin.elapsed();
println!("The loop took around {}s", time.as_secs());
}

View file

@ -0,0 +1 @@
The loop took around 13s