Skip to main content

ruvix_types/
timer.rs

1//! Timer types.
2//!
3//! Timers are deadline-driven scheduling primitives. The `timer_wait` syscall
4//! allows tasks to sleep until a deadline or for a duration.
5
6/// Timer specification for `timer_wait`.
7///
8/// Timers can be absolute (wait until a specific instant) or relative
9/// (wait for a duration from now).
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum TimerSpec {
12    /// Wait until an absolute instant.
13    ///
14    /// The instant is represented as nanoseconds since kernel boot.
15    Absolute {
16        /// Nanoseconds since kernel boot.
17        nanos_since_boot: u64,
18    },
19
20    /// Wait for a relative duration.
21    ///
22    /// The duration is represented as nanoseconds.
23    Relative {
24        /// Duration in nanoseconds.
25        nanos: u64,
26    },
27}
28
29impl TimerSpec {
30    /// Creates an absolute timer specification.
31    #[inline]
32    #[must_use]
33    pub const fn absolute(nanos_since_boot: u64) -> Self {
34        Self::Absolute { nanos_since_boot }
35    }
36
37    /// Creates a relative timer specification.
38    #[inline]
39    #[must_use]
40    pub const fn relative(nanos: u64) -> Self {
41        Self::Relative { nanos }
42    }
43
44    /// Creates a relative timer from milliseconds.
45    #[inline]
46    #[must_use]
47    pub const fn from_millis(millis: u64) -> Self {
48        Self::Relative {
49            nanos: millis * 1_000_000,
50        }
51    }
52
53    /// Creates a relative timer from microseconds.
54    #[inline]
55    #[must_use]
56    pub const fn from_micros(micros: u64) -> Self {
57        Self::Relative {
58            nanos: micros * 1_000,
59        }
60    }
61
62    /// Creates a relative timer from seconds.
63    #[inline]
64    #[must_use]
65    pub const fn from_secs(secs: u64) -> Self {
66        Self::Relative {
67            nanos: secs * 1_000_000_000,
68        }
69    }
70
71    /// Returns true if this is an absolute timer.
72    #[inline]
73    #[must_use]
74    pub const fn is_absolute(&self) -> bool {
75        matches!(self, Self::Absolute { .. })
76    }
77
78    /// Returns true if this is a relative timer.
79    #[inline]
80    #[must_use]
81    pub const fn is_relative(&self) -> bool {
82        matches!(self, Self::Relative { .. })
83    }
84
85    /// Returns the nanoseconds value.
86    #[inline]
87    #[must_use]
88    pub const fn nanos(&self) -> u64 {
89        match self {
90            Self::Absolute { nanos_since_boot } => *nanos_since_boot,
91            Self::Relative { nanos } => *nanos,
92        }
93    }
94}
95
96impl Default for TimerSpec {
97    fn default() -> Self {
98        Self::Relative { nanos: 0 }
99    }
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105
106    #[test]
107    fn test_timer_absolute() {
108        let timer = TimerSpec::absolute(1_000_000_000);
109        assert!(timer.is_absolute());
110        assert!(!timer.is_relative());
111        assert_eq!(timer.nanos(), 1_000_000_000);
112    }
113
114    #[test]
115    fn test_timer_relative() {
116        let timer = TimerSpec::from_millis(100);
117        assert!(timer.is_relative());
118        assert_eq!(timer.nanos(), 100_000_000);
119    }
120
121    #[test]
122    fn test_timer_from_secs() {
123        let timer = TimerSpec::from_secs(2);
124        assert_eq!(timer.nanos(), 2_000_000_000);
125    }
126}