1#![cfg_attr(not(test), no_std)]
2
3mod arch;
4
5use core::time::Duration;
6
7pub use arch::{Arch, ArchFunctionality};
8
9pub struct Instant {
22 cpu_count: u64,
23 frequency: u64,
24}
25
26impl Instant {
27 pub fn now() -> Self {
29 Self::from_cpu_count(Arch::cpu_count())
30 }
31
32 pub fn from_cpu_count(cpu_count: u64) -> Self {
34 Self { cpu_count, frequency: Arch::perf_frequency() }
35 }
36
37 pub fn beginning() -> Self {
39 Self { cpu_count: Arch::cpu_count_start(), frequency: Arch::perf_frequency() }
40 }
41
42 pub fn duration_since(&self, earlier: &Self) -> Duration {
47 if earlier.cpu_count > self.cpu_count {
48 panic!("earlier not in the past.");
49 }
50 let diff = (self.cpu_count - earlier.cpu_count) as f64;
51 Duration::from_secs_f64(diff / self.frequency as f64)
52 }
53
54 pub fn elapsed(&self) -> Duration {
56 Instant::now().duration_since(self)
57 }
58}
59
60#[cfg(test)]
61mod test {
62 use super::*;
63 use std::thread;
64
65 #[ignore = "Register / instruction return nonsense in the Azure pipeline vm."]
66 #[test]
67 fn test_instant() {
68 let ns = 1_000_000_000;
69
70 let start = Instant::now();
71 thread::sleep(Duration::from_nanos(ns));
72 let duration = start.elapsed();
73
74 let precision = (duration.as_nanos() as u64 - ns) as f64 / ns as f64 * 100_f64;
75 assert!(precision < 0.1, "precision is: {precision}");
76 }
77}