ax_plat/time.rs
1//! Time-related operations.
2
3pub use core::time::Duration;
4
5/// A measurement of the system clock.
6///
7/// Currently, it reuses the [`core::time::Duration`] type. But it does not
8/// represent a duration, but a clock time.
9pub type TimeValue = Duration;
10
11/// Number of milliseconds in a second.
12pub const MILLIS_PER_SEC: u64 = 1_000;
13/// Number of microseconds in a second.
14pub const MICROS_PER_SEC: u64 = 1_000_000;
15/// Number of nanoseconds in a second.
16pub const NANOS_PER_SEC: u64 = 1_000_000_000;
17/// Number of nanoseconds in a millisecond.
18pub const NANOS_PER_MILLIS: u64 = 1_000_000;
19/// Number of nanoseconds in a microsecond.
20pub const NANOS_PER_MICROS: u64 = 1_000;
21
22/// Time-related interfaces.
23#[def_plat_interface]
24pub trait TimeIf {
25 /// Returns the current clock time in hardware ticks.
26 fn current_ticks() -> u64;
27
28 /// Converts hardware ticks to nanoseconds.
29 fn ticks_to_nanos(ticks: u64) -> u64;
30
31 /// Converts nanoseconds to hardware ticks.
32 fn nanos_to_ticks(nanos: u64) -> u64;
33
34 /// Return epoch offset in nanoseconds (wall time offset to monotonic
35 /// clock start).
36 fn epochoffset_nanos() -> u64;
37
38 /// Returns the IRQ number for the timer interrupt.
39 #[cfg(feature = "irq")]
40 fn irq_num() -> usize;
41
42 /// Set a one-shot timer.
43 ///
44 /// A timer interrupt will be triggered at the specified monotonic time
45 /// deadline (in nanoseconds).
46 #[cfg(feature = "irq")]
47 fn set_oneshot_timer(deadline_ns: u64);
48}
49
50/// Returns nanoseconds elapsed since system boot.
51pub fn monotonic_time_nanos() -> u64 {
52 ticks_to_nanos(current_ticks())
53}
54
55/// Returns the time elapsed since system boot in [`TimeValue`].
56pub fn monotonic_time() -> TimeValue {
57 TimeValue::from_nanos(monotonic_time_nanos())
58}
59
60/// Returns nanoseconds elapsed since epoch (also known as realtime).
61pub fn wall_time_nanos() -> u64 {
62 monotonic_time_nanos() + epochoffset_nanos()
63}
64
65/// Returns the time elapsed since epoch (also known as realtime) in [`TimeValue`].
66pub fn wall_time() -> TimeValue {
67 TimeValue::from_nanos(monotonic_time_nanos() + epochoffset_nanos())
68}
69
70/// Busy waiting for the given duration.
71pub fn busy_wait(dur: Duration) {
72 busy_wait_until(wall_time() + dur);
73}
74
75/// Busy waiting until reaching the given deadline.
76pub fn busy_wait_until(deadline: TimeValue) {
77 while wall_time() < deadline {
78 core::hint::spin_loop();
79 }
80}