Skip to content

Commit 988b67e

Browse files
committed
move all time related pattern matching inside shims::time
1 parent e93c719 commit 988b67e

File tree

2 files changed

+41
-32
lines changed

2 files changed

+41
-32
lines changed

src/concurrency/thread.rs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
use std::cell::RefCell;
44
use std::collections::hash_map::Entry;
55
use std::num::TryFromIntError;
6-
use std::time::{Duration, Instant, SystemTime};
6+
use std::time::{Duration, SystemTime};
77

88
use log::trace;
99

1010
use rustc_data_structures::fx::FxHashMap;
11-
use rustc_data_structures::sync::Ordering;
1211
use rustc_hir::def_id::DefId;
1312
use rustc_index::vec::{Idx, IndexVec};
1413
use rustc_middle::mir::Mutability;
@@ -17,7 +16,7 @@ use rustc_target::spec::abi::Abi;
1716

1817
use crate::concurrency::data_race;
1918
use crate::concurrency::sync::SynchronizationState;
20-
use crate::shims::time::Clock;
19+
use crate::shims::time::{Clock, Instant};
2120
use crate::*;
2221

2322
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -186,23 +185,9 @@ impl<'mir, 'tcx> Thread<'mir, 'tcx> {
186185
#[derive(Debug)]
187186
pub enum Time {
188187
Monotonic(Instant),
189-
Virtual { nanoseconds: u64 },
190188
RealTime(SystemTime),
191189
}
192190

193-
impl Time {
194-
/// How long do we have to wait from now until the specified time?
195-
fn get_wait_time(&self, clock: &Clock) -> Duration {
196-
match self {
197-
Time::Monotonic(instant) => instant.saturating_duration_since(Instant::now()),
198-
Time::Virtual { nanoseconds } =>
199-
Duration::from_nanos(nanoseconds - clock.assert_virtual().load(Ordering::Relaxed)),
200-
Time::RealTime(time) =>
201-
time.duration_since(SystemTime::now()).unwrap_or(Duration::new(0, 0)),
202-
}
203-
}
204-
}
205-
206191
/// Callbacks are used to implement timeouts. For example, waiting on a
207192
/// conditional variable with a timeout creates a callback that is called after
208193
/// the specified time and unblocks the thread. If another thread signals on the
@@ -500,7 +485,7 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
500485
for thread in self.threads.indices() {
501486
match self.timeout_callbacks.entry(thread) {
502487
Entry::Occupied(entry) =>
503-
if entry.get().call_time.get_wait_time(clock) == Duration::new(0, 0) {
488+
if clock.get_wait_time(&entry.get().call_time) == Duration::new(0, 0) {
504489
return Some((thread, entry.remove().callback));
505490
},
506491
Entry::Vacant(_) => {}
@@ -584,7 +569,7 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
584569
// at the time of the call".
585570
// <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html>
586571
let potential_sleep_time =
587-
self.timeout_callbacks.values().map(|info| info.call_time.get_wait_time(clock)).min();
572+
self.timeout_callbacks.values().map(|info| clock.get_wait_time(&info.call_time)).min();
588573
if potential_sleep_time == Some(Duration::new(0, 0)) {
589574
return Ok(SchedulingAction::ExecuteTimeoutCallback);
590575
}

src/shims/time.rs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::sync::atomic::AtomicU64;
2-
use std::time::{Duration, Instant, SystemTime};
2+
use std::time::{Duration, Instant as StdInstant, SystemTime};
33

44
use rustc_data_structures::sync::Ordering;
55

@@ -10,12 +10,18 @@ use crate::*;
1010
/// are passing for each basic block.
1111
const NANOSECOND_PER_BASIC_BLOCK: u64 = 10;
1212

13+
#[derive(Debug)]
14+
pub enum Instant {
15+
Host(StdInstant),
16+
Virtual { nanoseconds: u64 },
17+
}
18+
1319
/// A monotone clock used for `Instant` simulation.
1420
#[derive(Debug)]
1521
pub enum Clock {
1622
Host {
1723
/// The "time anchor" for this machine's monotone clock.
18-
time_anchor: Instant,
24+
time_anchor: StdInstant,
1925
},
2026
Virtual {
2127
/// The "current virtual time".
@@ -27,7 +33,7 @@ impl Clock {
2733
/// Create a new clock based on the availability of communication with the host.
2834
pub fn new(communicate: bool) -> Self {
2935
if communicate {
30-
Self::Host { time_anchor: Instant::now() }
36+
Self::Host { time_anchor: StdInstant::now() }
3137
} else {
3238
Self::Virtual { nanoseconds: 0.into() }
3339
}
@@ -36,7 +42,7 @@ impl Clock {
3642
/// Get the current time relative to this clock.
3743
pub fn get(&self) -> Duration {
3844
match self {
39-
Self::Host { time_anchor } => Instant::now().saturating_duration_since(*time_anchor),
45+
Self::Host { time_anchor } => StdInstant::now().saturating_duration_since(*time_anchor),
4046
Self::Virtual { nanoseconds } =>
4147
Duration::from_nanos(nanoseconds.load(Ordering::Relaxed)),
4248
}
@@ -68,30 +74,48 @@ impl Clock {
6874
/// Compute `now + duration` relative to this clock.
6975
pub fn get_time_relative(&self, duration: Duration) -> Option<Time> {
7076
match self {
71-
Self::Host { .. } => Instant::now().checked_add(duration).map(Time::Monotonic),
77+
Self::Host { .. } =>
78+
StdInstant::now()
79+
.checked_add(duration)
80+
.map(|instant| Time::Monotonic(Instant::Host(instant))),
7281
Self::Virtual { nanoseconds } =>
7382
nanoseconds
7483
.load(Ordering::Relaxed)
7584
.checked_add(duration.as_nanos().try_into().unwrap())
76-
.map(|nanoseconds| Time::Virtual { nanoseconds }),
85+
.map(|nanoseconds| Time::Monotonic(Instant::Virtual { nanoseconds })),
7786
}
7887
}
7988

8089
/// Compute `start + duration` relative to this clock where `start` is the instant of time when
8190
/// this clock was created.
8291
pub fn get_time_absolute(&self, duration: Duration) -> Option<Time> {
8392
match self {
84-
Self::Host { time_anchor } => time_anchor.checked_add(duration).map(Time::Monotonic),
93+
Self::Host { time_anchor } =>
94+
time_anchor
95+
.checked_add(duration)
96+
.map(|instant| Time::Monotonic(Instant::Host(instant))),
8597
Self::Virtual { .. } =>
86-
Some(Time::Virtual { nanoseconds: duration.as_nanos().try_into().unwrap() }),
98+
Some(Time::Monotonic(Instant::Virtual {
99+
nanoseconds: duration.as_nanos().try_into().unwrap(),
100+
})),
87101
}
88102
}
89103

90-
/// Assert that this clock is a virtual one and get the current time in nanoseconds.
91-
pub(crate) fn assert_virtual(&self) -> &AtomicU64 {
92-
match self {
93-
Clock::Host { .. } => panic!(),
94-
Clock::Virtual { nanoseconds } => nanoseconds,
104+
/// How long do we have to wait from now until the specified time?
105+
pub fn get_wait_time(&self, time: &Time) -> Duration {
106+
match time {
107+
Time::Monotonic(instant) =>
108+
match (instant, self) {
109+
(Instant::Host(instant), Clock::Host { .. }) =>
110+
instant.saturating_duration_since(StdInstant::now()),
111+
(
112+
Instant::Virtual { nanoseconds },
113+
Clock::Virtual { nanoseconds: current_ns },
114+
) => Duration::from_nanos(nanoseconds - current_ns.load(Ordering::Relaxed)),
115+
_ => panic!(),
116+
},
117+
Time::RealTime(time) =>
118+
time.duration_since(SystemTime::now()).unwrap_or(Duration::new(0, 0)),
95119
}
96120
}
97121
}

0 commit comments

Comments
 (0)