aarch64_std/
time.rs

1use aarch64_cpu::registers;
2use tock_registers::interfaces::Readable;
3
4pub use core::time::*;
5
6/// A measurement of a monotonically nondecreasing clock. Opaque and useful only with Duration.
7///
8/// Instants are always guaranteed, barring platform bugs, to be no less than any previously
9/// measured instant when created, and are often useful for tasks such as measuring benchmarks or
10/// timing how long an operation takes.
11///
12/// Note, however, that instants are not guaranteed to be steady. In other words, each tick of the
13/// underlying clock might not be the same length (e.g. some seconds may be longer than others). An
14/// instant may jump forwards or experience time dilation (slow down or speed up), but it will
15/// never go backwards.
16///
17/// Instants are opaque types that can only be compared to one another. There is no method to get
18/// “the number of seconds” from an instant. Instead, it only allows measuring the duration between
19/// two instants (or comparing two instants).
20#[derive(Clone, Copy, Debug, Hash)]
21pub struct Instant {
22    ticks: u64,
23}
24
25impl Instant {
26    /// Returns an instant corresponding to “now”.
27    pub fn now() -> Self {
28        Self {
29            ticks: registers::CNTVCT_EL0.get(),
30        }
31    }
32
33    /// Returns the amount of time elapsed from another instant to this one, or zero duration if
34    /// that instant is later than this one.
35    pub fn duration_since(&self, earlier: Self) -> Duration {
36        let freq = registers::CNTFRQ_EL0.get();
37        let ticks = self.ticks - earlier.ticks;
38        Duration::from_secs_f64(ticks as f64 / freq as f64)
39    }
40
41    /// Returns the amount of time elapsed since this instant was created.
42    pub fn elapsed(&self) -> Duration {
43        Self::now().duration_since(*self)
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50    use crate::thread::sleep;
51
52    #[test]
53    fn test_instant() {
54        let start = Instant::now();
55        const SLEEP_DURATION: Duration = Duration::from_millis(500);
56        sleep(SLEEP_DURATION);
57        assert!(start.elapsed() >= SLEEP_DURATION);
58    }
59}