Skip to main content

tg_rcore_tutorial_syscall/
time.rs

1//! 时间相关共享类型定义。
2//!
3//! 参考 Linux UAPI:
4//! <https://github.com/torvalds/linux/blob/master/include/uapi/linux/time.h>.
5
6#[derive(Clone, Copy, PartialEq, Eq, Debug)]
7#[repr(transparent)]
8/// 时钟类型标识(与 `clock_gettime` 等接口配合使用)。
9pub struct ClockId(pub usize);
10
11impl ClockId {
12    /// 实时时钟(受系统时间校正影响)。
13    pub const CLOCK_REALTIME: Self = Self(0);
14    /// 单调时钟(不受 wall-clock 调整影响,常用于计时)。
15    pub const CLOCK_MONOTONIC: Self = Self(1);
16    pub const CLOCK_PROCESS_CPUTIME_ID: Self = Self(2);
17    pub const CLOCK_THREAD_CPUTIME_ID: Self = Self(3);
18    pub const CLOCK_MONOTONIC_RAW: Self = Self(4);
19    pub const CLOCK_REALTIME_COARSE: Self = Self(5);
20    pub const CLOCK_MONOTONIC_COARSE: Self = Self(6);
21    pub const CLOCK_BOOTTIME: Self = Self(7);
22    pub const CLOCK_REALTIME_ALARM: Self = Self(8);
23    pub const CLOCK_BOOTTIME_ALARM: Self = Self(9);
24    pub const CLOCK_SGI_CYCLE: Self = Self(10);
25    pub const CLOCK_TAI: Self = Self(11);
26}
27
28#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug)]
29#[repr(C)]
30/// 秒 + 纳秒表示的时间结构。
31pub struct TimeSpec {
32    /// 秒
33    pub tv_sec: usize,
34    /// 纳秒
35    pub tv_nsec: usize,
36}
37
38impl TimeSpec {
39    /// 0 秒。
40    pub const ZERO: Self = Self {
41        tv_sec: 0,
42        tv_nsec: 0,
43    };
44    /// 1 秒。
45    pub const SECOND: Self = Self {
46        tv_sec: 1,
47        tv_nsec: 0,
48    };
49    /// 1 毫秒。
50    pub const MILLSECOND: Self = Self {
51        tv_sec: 0,
52        tv_nsec: 1_000_000,
53    };
54    /// 1 微秒。
55    pub const MICROSECOND: Self = Self {
56        tv_sec: 0,
57        tv_nsec: 1_000,
58    };
59    /// 1 纳秒。
60    pub const NANOSECOND: Self = Self {
61        tv_sec: 0,
62        tv_nsec: 1,
63    };
64    /// 从毫秒构造 `TimeSpec`。
65    pub fn from_millsecond(millsecond: usize) -> Self {
66        Self {
67            tv_sec: millsecond / 1_000,
68            tv_nsec: millsecond % 1_000 * 1_000_000,
69        }
70    }
71}
72
73impl core::ops::Add<TimeSpec> for TimeSpec {
74    type Output = Self;
75    fn add(self, rhs: Self) -> Self::Output {
76        let mut ans = Self {
77            tv_sec: self.tv_sec + rhs.tv_sec,
78            tv_nsec: self.tv_nsec + rhs.tv_nsec,
79        };
80        // 纳秒进位归一化到 [0, 1e9) 区间。
81        if ans.tv_nsec > 1_000_000_000 {
82            ans.tv_sec += 1;
83            ans.tv_nsec -= 1_000_000_000;
84        }
85        ans
86    }
87}
88
89impl core::fmt::Display for TimeSpec {
90    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
91        write!(f, "TimeSpec({}.{:09})", self.tv_sec, self.tv_nsec)
92    }
93}