First attempt
This commit is contained in:
parent
773415d28f
commit
844450ae3a
@ -6,7 +6,7 @@
|
|||||||
/// This number is pretty random, but it has been shown to approximately cause
|
/// 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.
|
/// some sample programs to run within an order of magnitude of real time on desktop CPUs.
|
||||||
/// (See `tests/pass/shims/time-with-isolation*.rs`.)
|
/// (See `tests/pass/shims/time-with-isolation*.rs`.)
|
||||||
const NANOSECONDS_PER_BASIC_BLOCK: u64 = 5000;
|
const NANOSECONDS_PER_BASIC_BLOCK: u128 = 5000;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Instant {
|
pub struct Instant {
|
||||||
@ -16,7 +16,7 @@ pub struct Instant {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum InstantKind {
|
enum InstantKind {
|
||||||
Host(StdInstant),
|
Host(StdInstant),
|
||||||
Virtual { nanoseconds: u64 },
|
Virtual { nanoseconds: u128 },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instant {
|
impl Instant {
|
||||||
@ -25,9 +25,8 @@ pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
|
|||||||
InstantKind::Host(instant) =>
|
InstantKind::Host(instant) =>
|
||||||
instant.checked_add(duration).map(|i| Instant { kind: InstantKind::Host(i) }),
|
instant.checked_add(duration).map(|i| Instant { kind: InstantKind::Host(i) }),
|
||||||
InstantKind::Virtual { nanoseconds } =>
|
InstantKind::Virtual { nanoseconds } =>
|
||||||
u128::from(nanoseconds)
|
nanoseconds
|
||||||
.checked_add(duration.as_nanos())
|
.checked_add(duration.as_nanos())
|
||||||
.and_then(|n| u64::try_from(n).ok())
|
|
||||||
.map(|nanoseconds| Instant { kind: InstantKind::Virtual { nanoseconds } }),
|
.map(|nanoseconds| Instant { kind: InstantKind::Virtual { nanoseconds } }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,7 +38,19 @@ pub fn duration_since(&self, earlier: Instant) -> Duration {
|
|||||||
(
|
(
|
||||||
InstantKind::Virtual { nanoseconds },
|
InstantKind::Virtual { nanoseconds },
|
||||||
InstantKind::Virtual { nanoseconds: earlier },
|
InstantKind::Virtual { nanoseconds: earlier },
|
||||||
) => Duration::from_nanos(nanoseconds.saturating_sub(earlier)),
|
) => {
|
||||||
|
// Trade some nanosecond precision to prevent as much overflow as possible.
|
||||||
|
let duration = match u64::try_from(
|
||||||
|
// Manually convert from nanosecond to millisecond.
|
||||||
|
// If it exceeded u64::MAX millisecond, we will just use u64::MAX millisecond,
|
||||||
|
// Duration can't take in more than u64::MAX millisecond.
|
||||||
|
nanoseconds.saturating_sub(earlier).saturating_div(1_000_000),
|
||||||
|
) {
|
||||||
|
Ok(millisecond) => Duration::from_millis(millisecond),
|
||||||
|
_ => Duration::from_millis(u64::MAX),
|
||||||
|
};
|
||||||
|
Duration::new(duration.as_secs(), duration.subsec_nanos())
|
||||||
|
}
|
||||||
_ => panic!("all `Instant` must be of the same kind"),
|
_ => panic!("all `Instant` must be of the same kind"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,7 +70,7 @@ enum ClockKind {
|
|||||||
},
|
},
|
||||||
Virtual {
|
Virtual {
|
||||||
/// The "current virtual time".
|
/// The "current virtual time".
|
||||||
nanoseconds: Cell<u64>,
|
nanoseconds: Cell<u128>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +104,7 @@ pub fn sleep(&self, duration: Duration) {
|
|||||||
ClockKind::Host { .. } => std::thread::sleep(duration),
|
ClockKind::Host { .. } => std::thread::sleep(duration),
|
||||||
ClockKind::Virtual { nanoseconds } => {
|
ClockKind::Virtual { nanoseconds } => {
|
||||||
// Just pretend that we have slept for some time.
|
// Just pretend that we have slept for some time.
|
||||||
let nanos: u64 = duration.as_nanos().try_into().unwrap();
|
let nanos: u128 = duration.as_nanos().try_into().unwrap();
|
||||||
nanoseconds.update(|x| x + nanos);
|
nanoseconds.update(|x| x + nanos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,23 @@ fn concurrent_wait_wake() {
|
|||||||
assert!(woken > 0 && woken < rounds);
|
assert!(woken > 0 && woken < rounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reproduce of https://github.com/rust-lang/miri/issues/3647.
|
||||||
|
fn large_timeout() {
|
||||||
|
let futex: i32 = 123;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
libc::syscall(
|
||||||
|
libc::SYS_futex,
|
||||||
|
addr_of!(futex),
|
||||||
|
libc::FUTEX_WAIT,
|
||||||
|
123,
|
||||||
|
&libc::timespec { tv_sec: 184467440839020, tv_nsec: 117558982 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
large_timeout();
|
||||||
wake_nobody();
|
wake_nobody();
|
||||||
wake_dangling();
|
wake_dangling();
|
||||||
wait_wrong_val();
|
wait_wrong_val();
|
||||||
|
Loading…
Reference in New Issue
Block a user