use crate::{Clock, Signal, paused};
use std::sync::Mutex;
use std::sync::atomic::Ordering;
use std::sync::mpsc::{self, Receiver, SyncSender};
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
pub(crate) fn blocked(clock: &Clock) -> usize {
clock.paused.as_ref().unwrap().state.lock().unwrap().blocked
}
pub(crate) fn wakes(signal: &Signal) -> usize {
signal.wakes.load(Ordering::SeqCst)
}
pub(crate) fn pause_before_park(clock: &Clock) -> (Receiver<Option<Instant>>, SyncSender<()>) {
pause(&clock.paused.as_ref().unwrap().before_park)
}
pub(crate) fn pause_before_rewait(clock: &Clock) -> (Receiver<Option<Instant>>, SyncSender<()>) {
pause(&clock.paused.as_ref().unwrap().before_rewait)
}
fn pause(hook: &Mutex<Option<paused::BeforePark>>) -> (Receiver<Option<Instant>>, SyncSender<()>) {
let (checked, checks) = mpsc::sync_channel(0);
let (resume, resumed) = mpsc::sync_channel(0);
*hook.lock().unwrap() = Some(Box::new(move |timer| {
checked.send(timer).unwrap();
resumed.recv().unwrap();
}));
(checks, resume)
}
pub(crate) fn last_system_time() -> SystemTime {
let mut time = UNIX_EPOCH;
for bit in (0..64).rev() {
if let Some(next) = time.checked_add(Duration::from_secs(1 << bit)) {
time = next;
}
}
time
}