linux_api/
time.rs
1use linux_syscall::Result as LinuxSyscallResult;
2use linux_syscall::Result64;
3use linux_syscall::syscall;
4use num_enum::{IntoPrimitive, TryFromPrimitive};
5
6use crate::bindings;
7use crate::const_conversions;
8use crate::errno::Errno;
9
10pub use bindings::linux___kernel_clockid_t;
11
12#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
14#[repr(i32)]
21#[allow(non_camel_case_types)]
22pub enum ClockId {
23 CLOCK_REALTIME = const_conversions::i32_from_u32(bindings::LINUX_CLOCK_REALTIME),
24 CLOCK_MONOTONIC = const_conversions::i32_from_u32(bindings::LINUX_CLOCK_MONOTONIC),
25 CLOCK_PROCESS_CPUTIME_ID =
26 const_conversions::i32_from_u32(bindings::LINUX_CLOCK_PROCESS_CPUTIME_ID),
27 CLOCK_THREAD_CPUTIME_ID =
28 const_conversions::i32_from_u32(bindings::LINUX_CLOCK_THREAD_CPUTIME_ID),
29 CLOCK_MONOTONIC_RAW = const_conversions::i32_from_u32(bindings::LINUX_CLOCK_MONOTONIC_RAW),
30 CLOCK_REALTIME_COARSE = const_conversions::i32_from_u32(bindings::LINUX_CLOCK_REALTIME_COARSE),
31 CLOCK_MONOTONIC_COARSE =
32 const_conversions::i32_from_u32(bindings::LINUX_CLOCK_MONOTONIC_COARSE),
33 CLOCK_BOOTTIME = const_conversions::i32_from_u32(bindings::LINUX_CLOCK_BOOTTIME),
34 CLOCK_REALTIME_ALARM = const_conversions::i32_from_u32(bindings::LINUX_CLOCK_REALTIME_ALARM),
35 CLOCK_BOOTTIME_ALARM = const_conversions::i32_from_u32(bindings::LINUX_CLOCK_BOOTTIME_ALARM),
36 CLOCK_SGI_CYCLE = const_conversions::i32_from_u32(bindings::LINUX_CLOCK_SGI_CYCLE),
37 CLOCK_TAI = const_conversions::i32_from_u32(bindings::LINUX_CLOCK_TAI),
38}
39
40bitflags::bitflags! {
41 #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
43 pub struct ClockNanosleepFlags: i32 {
44 const TIMER_ABSTIME = const_conversions::i32_from_u32(bindings::LINUX_TIMER_ABSTIME);
45 }
46}
47
48#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
50#[repr(i32)]
55#[allow(non_camel_case_types)]
56pub enum ITimerId {
57 ITIMER_REAL = const_conversions::i32_from_u32(bindings::LINUX_ITIMER_REAL),
58 ITIMER_VIRTUAL = const_conversions::i32_from_u32(bindings::LINUX_ITIMER_VIRTUAL),
59 ITIMER_PROF = const_conversions::i32_from_u32(bindings::LINUX_ITIMER_PROF),
60}
61
62pub use bindings::linux_timespec;
63#[allow(non_camel_case_types)]
64pub type timespec = linux_timespec;
65unsafe impl shadow_pod::Pod for timespec {}
66unsafe impl vasi::VirtualAddressSpaceIndependent for timespec {}
67
68pub use bindings::linux___kernel_timespec;
69#[allow(non_camel_case_types)]
70pub type kernel_timespec = linux___kernel_timespec;
71unsafe impl shadow_pod::Pod for kernel_timespec {}
72unsafe impl vasi::VirtualAddressSpaceIndependent for kernel_timespec {}
73
74pub use bindings::linux_timeval;
75#[allow(non_camel_case_types)]
76pub type timeval = linux_timeval;
77unsafe impl shadow_pod::Pod for timeval {}
78unsafe impl vasi::VirtualAddressSpaceIndependent for timeval {}
79
80pub use bindings::linux___kernel_old_timeval;
81#[allow(non_camel_case_types)]
82pub type kernel_old_timeval = linux___kernel_old_timeval;
83unsafe impl shadow_pod::Pod for kernel_old_timeval {}
84unsafe impl vasi::VirtualAddressSpaceIndependent for kernel_old_timeval {}
85
86pub fn clock_gettime_raw(clockid: linux___kernel_clockid_t) -> Result<timespec, Errno> {
87 let mut t = shadow_pod::zeroed();
88 unsafe { syscall!(linux_syscall::SYS_clock_gettime, clockid, &mut t) }
89 .check()
90 .map_err(Errno::from)?;
91 Ok(t)
92}
93
94pub fn clock_gettime(clockid: ClockId) -> Result<timespec, Errno> {
95 clock_gettime_raw(clockid.into())
96}
97
98pub use bindings::linux_itimerspec;
99#[allow(non_camel_case_types)]
100pub type itimerspec = linux_itimerspec;
101unsafe impl shadow_pod::Pod for itimerspec {}
102unsafe impl vasi::VirtualAddressSpaceIndependent for itimerspec {}
103
104pub use bindings::linux_itimerval;
105#[allow(non_camel_case_types)]
106pub type itimerval = linux_itimerval;
107unsafe impl shadow_pod::Pod for itimerval {}
108unsafe impl vasi::VirtualAddressSpaceIndependent for itimerval {}
109
110pub use bindings::linux___kernel_old_itimerval;
111#[allow(non_camel_case_types)]
112pub type kernel_old_itimerval = linux___kernel_old_itimerval;
113unsafe impl shadow_pod::Pod for kernel_old_itimerval {}
114unsafe impl vasi::VirtualAddressSpaceIndependent for kernel_old_itimerval {}
115
116pub fn alarm_raw(secs: u64) -> Result<u64, Errno> {
120 unsafe { syscall!(linux_syscall::SYS_alarm, secs) }
121 .try_u64()
122 .map_err(Errno::from)
123}
124
125pub fn alarm(secs: u32) -> Result<u32, Errno> {
127 let res = alarm_raw(secs.into())?;
128 Ok(res.try_into().unwrap())
131}
132
133pub unsafe fn getitimer_raw(
144 which: core::ffi::c_int,
145 curr_value: *mut kernel_old_itimerval,
146) -> Result<(), Errno> {
147 unsafe { syscall!(linux_syscall::SYS_getitimer, which, curr_value) }
148 .check()
149 .map_err(Errno::from)
150}
151
152pub fn getitimer(which: ITimerId, curr_value: &mut kernel_old_itimerval) -> Result<(), Errno> {
154 unsafe { getitimer_raw(which.into(), curr_value) }
155}
156
157pub unsafe fn setitimer_raw(
166 which: core::ffi::c_int,
167 new_value: *const kernel_old_itimerval,
168 old_value: *mut kernel_old_itimerval,
169) -> Result<(), Errno> {
170 unsafe { syscall!(linux_syscall::SYS_setitimer, which, new_value, old_value) }
171 .check()
172 .map_err(Errno::from)
173}
174
175pub fn setitimer(
177 which: ITimerId,
178 new_value: &kernel_old_itimerval,
179 old_value: Option<&mut kernel_old_itimerval>,
180) -> Result<(), Errno> {
181 let old_value = old_value
182 .map(core::ptr::from_mut)
183 .unwrap_or(core::ptr::null_mut());
184 unsafe { setitimer_raw(which.into(), new_value, old_value) }
185}
186
187mod export {
188 use super::*;
189
190 #[unsafe(no_mangle)]
191 pub unsafe extern "C-unwind" fn linux_clock_gettime(
192 clockid: i32,
193 res: *mut linux_timespec,
194 ) -> i64 {
195 let t = match clock_gettime_raw(clockid) {
196 Ok(t) => t,
197 Err(e) => return e.to_negated_i64(),
198 };
199 assert!(!res.is_null());
200 unsafe { res.write(t) }
201 0
202 }
203}