os/uapi/
time.rs

1//! 定义与时间相关的结构和常量。
2//!
3//! 这些定义用于系统调用如 `clock_gettime`, `nanosleep`, `timer_create` 等。
4
5#![allow(non_camel_case_types)]
6#![allow(dead_code)]
7
8use core::{
9    ffi::{c_int, c_long},
10    ops::{Add, Sub},
11};
12
13use crate::{
14    arch::timer::{clock_freq, get_time},
15    kernel::time::REALTIME,
16};
17
18/// 用于指定秒和纳秒精度的时间
19#[repr(C)]
20#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
21pub struct TimeSpec {
22    /// 秒 (seconds)
23    pub tv_sec: c_long,
24    /// 纳秒 (nanoseconds)
25    pub tv_nsec: c_long,
26}
27
28impl TimeSpec {
29    /// 特殊值:设置为当前时间(UTIME_NOW,用于 utimensat)
30    pub const UTIME_NOW: c_long = (1i64 << 30) - 1; // 1073741823
31
32    /// 特殊值:不改变此时间(UTIME_OMIT,用于 utimensat)
33    pub const UTIME_OMIT: c_long = (1i64 << 30) - 2; // 1073741822
34
35    /// 创建一个新的 TimeSpec 结构体
36    /// # 参数:
37    /// - `sec`: 秒数
38    /// - `nsec`: 纳秒数
39    /// # 返回值:
40    /// - 对应的 TimeSpec 结构体
41    pub fn new(sec: c_long, nsec: c_long) -> Self {
42        Self {
43            tv_sec: sec,
44            tv_nsec: nsec,
45        }
46    }
47
48    /// 将 TimeSpec 转换为指定频率的刻度数。
49    /// # 参数:
50    /// - `freq`: 频率(每秒刻度数)
51    /// # 返回值:
52    /// - 刻度数
53    pub fn into_freq(&self, freq: usize) -> usize {
54        let sec_ticks = (self.tv_sec as u128) * (freq as u128);
55        let nsec_ticks = (self.tv_nsec as u128) * (freq as u128) / 1_000_000_000;
56        (sec_ticks + nsec_ticks) as usize
57    }
58
59    /// 通过指定频率的刻度数创建 TimeSpec。
60    /// # 参数:
61    /// - `ticks`: 刻度数
62    /// - `freq`: 频率(每秒刻度数)
63    /// # 返回值:
64    /// - 对应的 TimeSpec 结构体
65    pub fn from_freq(ticks: usize, freq: usize) -> Self {
66        let sec = ticks / freq;
67        let nsec = (ticks % freq) * 1_000_000_000 / freq;
68        Self {
69            tv_sec: sec as c_long,
70            tv_nsec: nsec as c_long,
71        }
72    }
73
74    /// 获取当前墙上时钟时间的 TimeSpec。
75    /// # 返回值:
76    /// - 当前时间的 TimeSpec 结构体
77    pub fn now() -> Self {
78        let time = REALTIME.read();
79        let mtime = Self::monotonic_now();
80        mtime + *time
81    }
82
83    /// 获取当前单调时钟时间的 TimeSpec。
84    /// # 返回值:
85    /// - 当前单调时间的 TimeSpec 结构体
86    pub fn monotonic_now() -> Self {
87        let time = get_time();
88        Self::from_freq(time, clock_freq())
89    }
90
91    /// 创建零时间的 TimeSpec。
92    /// # 返回值:
93    /// - 零时间的 TimeSpec 结构体
94    pub fn zero() -> Self {
95        Self {
96            tv_sec: 0,
97            tv_nsec: 0,
98        }
99    }
100
101    /// 验证 TimeSpec 的有效性(用于 utimensat)
102    ///
103    /// # 返回值
104    /// - `Ok(())`: 有效
105    /// - `Err(EINVAL)`: 无效
106    pub fn validate(&self) -> Result<(), i32> {
107        use crate::uapi::errno::EINVAL;
108
109        // 检查特殊值
110        if self.tv_nsec == Self::UTIME_NOW || self.tv_nsec == Self::UTIME_OMIT {
111            return Ok(());
112        }
113
114        // 检查纳秒范围
115        if self.tv_nsec < 0 || self.tv_nsec >= 1_000_000_000 {
116            return Err(EINVAL);
117        }
118
119        Ok(())
120    }
121
122    /// 将 TimeSpec 转换为 timeval 结构体。
123    /// # 返回值:
124    /// - 对应的 timeval 结构体
125    pub fn to_timeval(&self) -> timeval {
126        timeval {
127            tv_sec: self.tv_sec,
128            tv_usec: self.tv_nsec / 1000,
129        }
130    }
131
132    /// 检查是否为零时间
133    #[inline]
134    pub fn is_zero(&self) -> bool {
135        self.tv_sec == 0 && self.tv_nsec == 0
136    }
137
138    /// 检查是否为 UTIME_NOW(用于 utimensat)
139    #[inline]
140    pub fn is_now(&self) -> bool {
141        self.tv_nsec == Self::UTIME_NOW
142    }
143
144    /// 检查是否为 UTIME_OMIT(用于 utimensat)
145    #[inline]
146    pub fn is_omit(&self) -> bool {
147        self.tv_nsec == Self::UTIME_OMIT
148    }
149}
150
151impl Sub for TimeSpec {
152    type Output = TimeSpec;
153
154    fn sub(self, other: TimeSpec) -> TimeSpec {
155        let sec = self.tv_sec - other.tv_sec;
156        let nsec = self.tv_nsec - other.tv_nsec;
157        if nsec < 0 {
158            TimeSpec {
159                tv_sec: sec - 1,
160                tv_nsec: nsec + 1_000_000_000,
161            }
162        } else {
163            TimeSpec {
164                tv_sec: sec,
165                tv_nsec: nsec,
166            }
167        }
168    }
169}
170
171impl Add for TimeSpec {
172    type Output = TimeSpec;
173
174    fn add(self, other: TimeSpec) -> TimeSpec {
175        let sec = self.tv_sec + other.tv_sec;
176        let nsec = self.tv_nsec + other.tv_nsec;
177        if nsec >= 1_000_000_000 {
178            TimeSpec {
179                tv_sec: sec + 1,
180                tv_nsec: nsec - 1_000_000_000,
181            }
182        } else {
183            TimeSpec {
184                tv_sec: sec,
185                tv_nsec: nsec,
186            }
187        }
188    }
189}
190
191/// 用于指定秒和微秒精度的时间。
192#[repr(C)]
193#[derive(Debug, Clone, Copy, PartialEq, Eq)]
194pub struct timeval {
195    /// 秒 (seconds)
196    pub tv_sec: c_long,
197    /// 微秒 (microseconds)
198    pub tv_usec: c_long,
199}
200
201impl timeval {
202    /// 将 timeval 转换为 TimeSpec 结构体。
203    /// # 返回值:
204    /// - 对应的 TimeSpec 结构体
205    pub fn to_timespec(&self) -> TimeSpec {
206        TimeSpec {
207            tv_sec: self.tv_sec,
208            tv_nsec: self.tv_usec * 1000,
209        }
210    }
211
212    /// 将 timeval 转换为指定频率的刻度数。
213    /// # 参数:
214    /// - `freq`: 频率(每秒刻度数)
215    /// # 返回值:
216    /// - 刻度数
217    pub fn into_freq(&self, freq: usize) -> usize {
218        let sec_ticks = (self.tv_sec as u128) * (freq as u128);
219        let usec_ticks = (self.tv_usec as u128) * (freq as u128) / 1_000_000;
220        (sec_ticks + usec_ticks) as usize
221    }
222
223    /// 创建一个新的 timeval 结构体
224    /// # 参数:
225    /// - `sec`: 秒数
226    /// - `usec`: 微秒数
227    /// # 返回值:
228    /// - 对应的 timeval 结构体
229    pub fn new(sec: c_long, usec: c_long) -> Self {
230        Self {
231            tv_sec: sec,
232            tv_usec: usec,
233        }
234    }
235
236    /// 创建零时间的 timeval 结构体
237    /// # 返回值:
238    /// - 零时间的 timeval 结构体
239    pub fn zero() -> Self {
240        Self {
241            tv_sec: 0,
242            tv_usec: 0,
243        }
244    }
245
246    /// 检查是否为零时间
247    #[inline]
248    pub fn is_zero(&self) -> bool {
249        self.tv_sec == 0 && self.tv_usec == 0
250    }
251}
252
253/// 用于设置 POSIX 间隔定时器 (timer_create) 的结构。
254#[repr(C)]
255#[derive(Debug, Clone, Copy, PartialEq, Eq)]
256pub struct Itimerspec {
257    /// 定时器周期 (timer period)
258    pub it_interval: TimeSpec,
259    /// 定时器初始值/到期时间 (timer expiration)
260    pub it_value: TimeSpec,
261}
262
263/// 用于设置传统 BSD 间隔定时器 (setitimer) 的结构。
264#[repr(C)]
265#[derive(Debug, Clone, Copy, PartialEq, Eq)]
266pub struct Itimerval {
267    /// 定时器周期 (timer interval)
268    pub it_interval: timeval,
269    /// 定时器当前值 (current value)
270    pub it_value: timeval,
271}
272
273impl Itimerval {
274    /// 将 Itimerval 转换为 Itimerspec。
275    /// # 返回值:
276    /// - 对应的 Itimerspec 结构体
277    pub fn zero() -> Self {
278        Self {
279            it_interval: timeval {
280                tv_sec: 0,
281                tv_usec: 0,
282            },
283            it_value: timeval {
284                tv_sec: 0,
285                tv_usec: 0,
286            },
287        }
288    }
289}
290
291/// 时区结构体,用于 gettimeofday/settimeofday(现在已不推荐使用)。
292#[repr(C)]
293#[derive(Debug, Clone, Copy, PartialEq, Eq)]
294pub struct timezone {
295    /// 格林威治以西的分钟数 (minutes west of Greenwich)
296    pub tz_minuteswest: c_int,
297    /// DST 校正类型 (type of dst correction)
298    pub tz_dsttime: c_int,
299}
300
301/// 传统 BSD 风格间隔定时器 ID。
302pub mod itimer_id {
303    use super::c_int;
304    /// 实时计时器。当计时器到期时发送 SIGALRM。
305    pub const ITIMER_REAL: c_int = 0;
306    /// 虚拟计时器。当进程处于用户态执行时计时,到期时发送 SIGVTALRM。
307    pub const ITIMER_VIRTUAL: c_int = 1;
308    /// 性能计时器。当进程处于用户态和内核态执行时计时,到期时发送 SIGPROF。
309    pub const ITIMER_PROF: c_int = 2;
310}
311
312/// 用于 `clock_gettime`, `nanosleep` 等系统调用的时钟 ID。
313pub mod clock_id {
314    use super::c_int;
315
316    /// 实时时钟,可被修改,非单调。
317    pub const CLOCK_REALTIME: c_int = 0;
318    /// 单调时钟,从系统启动开始计数,不计入休眠时间。
319    pub const CLOCK_MONOTONIC: c_int = 1;
320    /// 当前进程消耗的 CPU 时间。
321    pub const CLOCK_PROCESS_CPUTIME_ID: c_int = 2;
322    /// 当前线程消耗的 CPU 时间。
323    pub const CLOCK_THREAD_CPUTIME_ID: c_int = 3;
324    /// 原始单调时钟,未经 NTP 或频率调整。
325    pub const CLOCK_MONOTONIC_RAW: c_int = 4;
326    /// 粗粒度实时时钟,访问速度快。
327    pub const CLOCK_REALTIME_COARSE: c_int = 5;
328    /// 粗粒度单调时钟,访问速度快。
329    pub const CLOCK_MONOTONIC_COARSE: c_int = 6;
330    /// 启动时间时钟,包含系统休眠时间。
331    pub const CLOCK_BOOTTIME: c_int = 7;
332    /// 实时闹钟,即使系统休眠也会唤醒。
333    pub const CLOCK_REALTIME_ALARM: c_int = 8;
334    /// 启动时间闹钟,即使系统休眠也会唤醒。
335    pub const CLOCK_BOOTTIME_ALARM: c_int = 9;
336    /// SGI 循环时钟 (已移除,仅占位)。
337    pub const CLOCK_SGI_CYCLE: c_int = 10;
338    /// 国际原子时 (TAI)。
339    pub const CLOCK_TAI: c_int = 11;
340
341    // 最大时钟 ID 数量(用于数组或边界检查)
342    pub const MAX_CLOCKS: c_int = 16;
343}
344
345/// 辅助时钟和标志
346pub mod clock_flags {
347    use crate::uapi::time::clock_id::{CLOCK_MONOTONIC, CLOCK_REALTIME};
348
349    use super::c_int;
350
351    // 辅助时钟的基数和范围
352    pub const CLOCK_AUX: c_int = super::clock_id::MAX_CLOCKS;
353    pub const MAX_AUX_CLOCKS: c_int = 8;
354    pub const CLOCK_AUX_LAST: c_int = CLOCK_AUX + MAX_AUX_CLOCKS - 1;
355
356    // 掩码,用于组合时钟 ID
357    pub const CLOCKS_MASK: c_int = CLOCK_REALTIME | CLOCK_MONOTONIC;
358    pub const CLOCKS_MONO: c_int = CLOCK_MONOTONIC;
359
360    // POSIX.1b 定时器标志
361    /// TIMER_ABSTIME: 将时间解释为绝对时间而非相对时间。
362    pub const TIMER_ABSTIME: c_int = 0x01;
363}