1use crate::errno::Errno;
9use crate::{syscall_1, syscall_2};
10pub use irox_enums::{EnumIterItem, EnumName};
11
12pub const SYSCALL_TIMES: u64 = 100;
13pub const SYSCALL_CLOCK_GETTIME: u64 = 228;
14pub const SYSCALL_CLOCK_GETRES: u64 = 229;
15
16pub type ClockT = u64;
19
20#[derive(Debug, Copy, Clone, Eq, PartialEq, EnumName, EnumIterItem)]
23#[repr(u32)]
24pub enum ClockType {
25 Realtime = 0,
29
30 Monotonic = 1,
37
38 ProcessCPUTime = 2,
41
42 ThreadCPUTime = 3,
44
45 MonotonicRaw = 4,
46
47 RealtimeCoarse = 5,
50
51 MonotonicCoarse = 6,
54 BootTime = 7,
55 RealTimeAlarm = 8,
56 BootTimeAlarm = 9,
57 TAI = 11,
58}
59
60#[repr(C)]
63#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
64pub struct Timespec {
65 pub tv_sec: u64,
67 pub tv_nsec: u64,
69}
70
71#[derive(Debug, Copy, Clone, Eq, PartialEq)]
74pub struct ClockTimespec {
75 pub timespec: Timespec,
76 pub clock: ClockType,
77}
78
79#[repr(C)]
82#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
83pub struct Times {
84 pub tms_utime: ClockT,
86 pub tms_stime: ClockT,
88 pub tms_cutime: ClockT,
90 pub tms_cstime: ClockT,
92}
93
94pub fn clock_gettime(clock_type: ClockType) -> Result<ClockTimespec, Errno> {
97 let mut ts: Timespec = Default::default();
98
99 let ret = unsafe {
100 let ptr = core::ptr::from_mut(&mut ts);
101 syscall_2!(SYSCALL_CLOCK_GETTIME, clock_type as u64, ptr)
102 };
103
104 if ret != 0 {
105 return Err(ret.into());
106 }
107 Ok(ClockTimespec {
108 clock: clock_type,
109 timespec: ts,
110 })
111}
112
113#[derive(Debug, Copy, Clone, Eq, PartialEq)]
114pub struct ClockResolution {
115 pub clock: ClockType,
116 pub resolution_ns: u64,
117}
118
119pub fn clock_getres(clock_type: ClockType) -> Result<ClockResolution, Errno> {
122 let mut ts: Timespec = Default::default();
123
124 let ret = unsafe {
125 let ptr = core::ptr::from_mut(&mut ts);
126 syscall_2!(SYSCALL_CLOCK_GETRES, clock_type as u64, ptr)
127 };
128
129 if ret != 0 {
130 return Err(ret.into());
131 }
132 Ok(ClockResolution {
133 clock: clock_type,
134 resolution_ns: ts.tv_nsec,
135 })
136}
137
138#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
139pub struct TimesTicks {
140 pub times: Times,
141 pub ticks: u64,
143}
144
145pub fn times() -> Result<TimesTicks, Errno> {
147 let mut ts: Times = Default::default();
148
149 let ret = unsafe {
150 let ptr = core::ptr::from_mut(&mut ts);
151 syscall_1!(SYSCALL_TIMES, ptr)
152 };
153
154 if ret < 0 {
155 return Err(ret.into());
156 }
157 Ok(TimesTicks {
158 times: ts,
159 ticks: ret as u64,
160 })
161}
162
163#[cfg(test)]
164mod tests {
165 use crate::errno::Errno;
166 use crate::time::*;
167
168 #[test]
169 pub fn test_clock_gettime() -> Result<(), Errno> {
170 let out = clock_gettime(ClockType::Realtime)?;
171
172 println!("{out:#?}");
173
174 for clock in ClockType::iter_items() {
175 let out = clock_gettime(clock);
176 println!("{clock:?}: {out:#?}");
177 }
178
179 Ok(())
180 }
181
182 #[test]
183 pub fn test_clock_getres() -> Result<(), Errno> {
184 let out = clock_getres(ClockType::Realtime)?;
185
186 println!("{out:#?}");
187
188 for clock in ClockType::iter_items() {
189 let out = clock_getres(clock);
190 println!("{clock:?}: {out:#?}");
191 }
192
193 Ok(())
194 }
195
196 #[test]
197 pub fn test_times() -> Result<(), Errno> {
198 let out = times()?;
199 println!("{out:#?}");
200 Ok(())
201 }
202}