#![cfg_attr(not(test), no_std)]
mod arch;
use core::time::Duration;
pub use arch::{Arch, ArchFunctionality};
pub struct Instant {
cpu_count: u64,
frequency: u64,
}
impl Instant {
pub fn now() -> Self {
Self::from_cpu_count(Arch::cpu_count())
}
pub fn from_cpu_count(cpu_count: u64) -> Self {
Self { cpu_count, frequency: Arch::perf_frequency() }
}
pub fn beginning() -> Self {
Self { cpu_count: Arch::cpu_count_start(), frequency: Arch::perf_frequency() }
}
pub fn duration_since(&self, earlier: &Self) -> Duration {
if earlier.cpu_count > self.cpu_count {
panic!("earlier not in the past.");
}
let diff = (self.cpu_count - earlier.cpu_count) as f64;
Duration::from_secs_f64(diff / self.frequency as f64)
}
pub fn elapsed(&self) -> Duration {
Instant::now().duration_since(self)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::thread;
#[ignore = "Register / instruction return nonsense in the Azure pipeline vm."]
#[test]
fn test_instant() {
let ns = 1_000_000_000;
let start = Instant::now();
thread::sleep(Duration::from_nanos(ns));
let duration = start.elapsed();
let precision = (duration.as_nanos() as u64 - ns) as f64 / ns as f64 * 100_f64;
assert!(precision < 0.1, "precision is: {precision}");
}
}