xref: /DragonOS/kernel/src/time/mod.rs (revision c635d8a9cfe25bc11779f323ef0c7d7a0f597d4a)
1 use core::{
2     fmt,
3     intrinsics::unlikely,
4     ops::{self, Sub},
5 };
6 
7 use crate::arch::CurrentTimeArch;
8 use crate::time::syscall::PosixTimeval;
9 
10 use self::timekeeping::getnstimeofday;
11 
12 pub mod clocksource;
13 pub mod jiffies;
14 pub mod sleep;
15 pub mod syscall;
16 pub mod tick_common;
17 pub mod timeconv;
18 pub mod timekeep;
19 pub mod timekeeping;
20 pub mod timer;
21 
22 /* Time structures. (Partitially taken from smoltcp)
23 
24 The `time` module contains structures used to represent both
25 absolute and relative time.
26 
27  - [Instant] is used to represent absolute time.
28  - [Duration] is used to represent relative time.
29 
30 [Instant]: struct.Instant.html
31 [Duration]: struct.Duration.html
32 */
33 #[allow(dead_code)]
34 pub const MSEC_PER_SEC: u32 = 1000;
35 #[allow(dead_code)]
36 pub const USEC_PER_MSEC: u32 = 1000;
37 #[allow(dead_code)]
38 pub const NSEC_PER_USEC: u32 = 1000;
39 #[allow(dead_code)]
40 pub const NSEC_PER_MSEC: u32 = 1000000;
41 #[allow(dead_code)]
42 pub const USEC_PER_SEC: u32 = 1000000;
43 #[allow(dead_code)]
44 pub const NSEC_PER_SEC: u32 = 1000000000;
45 #[allow(dead_code)]
46 pub const FSEC_PER_SEC: u64 = 1000000000000000;
47 
48 /// The clock frequency of the i8253/i8254 PIT
49 pub const PIT_TICK_RATE: u64 = 1193182;
50 
51 /// 表示时间的结构体,符合POSIX标准。
52 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
53 #[repr(C)]
54 pub struct PosixTimeSpec {
55     pub tv_sec: i64,
56     pub tv_nsec: i64,
57 }
58 
59 impl PosixTimeSpec {
60     #[allow(dead_code)]
61     pub fn new(sec: i64, nsec: i64) -> PosixTimeSpec {
62         return PosixTimeSpec {
63             tv_sec: sec,
64             tv_nsec: nsec,
65         };
66     }
67 
68     /// 获取当前时间
69     #[inline(always)]
70     pub fn now() -> Self {
71         getnstimeofday()
72     }
73 
74     /// 获取当前CPU时间(使用CPU时钟周期计算,会存在回绕问题)
75     pub fn now_cpu_time() -> Self {
76         #[cfg(target_arch = "x86_64")]
77         {
78             use crate::arch::driver::tsc::TSCManager;
79             let khz = TSCManager::cpu_khz();
80             if unlikely(khz == 0) {
81                 return PosixTimeSpec::default();
82             } else {
83                 return Self::from(Duration::from_millis(
84                     CurrentTimeArch::get_cycles() as u64 / khz,
85                 ));
86             }
87         }
88 
89         #[cfg(target_arch = "riscv64")]
90         {
91             return PosixTimeSpec::new(0, 0);
92         }
93     }
94 
95     /// 换算成纳秒
96     pub fn total_nanos(&self) -> i64 {
97         self.tv_sec * 1000000000 + self.tv_nsec
98     }
99 }
100 
101 impl Sub for PosixTimeSpec {
102     type Output = Duration;
103     fn sub(self, rhs: Self) -> Self::Output {
104         let sec = self.tv_sec.checked_sub(rhs.tv_sec).unwrap_or(0);
105         let nsec = self.tv_nsec.checked_sub(rhs.tv_nsec).unwrap_or(0);
106         Duration::from_micros((sec * 1000000 + nsec / 1000) as u64)
107     }
108 }
109 
110 impl From<Duration> for PosixTimeSpec {
111     fn from(dur: Duration) -> Self {
112         PosixTimeSpec {
113             tv_sec: dur.total_micros() as i64 / 1000000,
114             tv_nsec: (dur.total_micros() as i64 % 1000000) * 1000,
115         }
116     }
117 }
118 
119 impl From<PosixTimeval> for PosixTimeSpec {
120     fn from(value: PosixTimeval) -> Self {
121         PosixTimeSpec {
122             tv_sec: value.tv_sec,
123             tv_nsec: value.tv_usec as i64 * 1000,
124         }
125     }
126 }
127 
128 impl From<PosixTimeSpec> for Duration {
129     fn from(val: PosixTimeSpec) -> Self {
130         Duration::from_micros(val.tv_sec as u64 * 1000000 + val.tv_nsec as u64 / 1000)
131     }
132 }
133 
134 /// A representation of an absolute time value.
135 ///
136 /// The `Instant` type is a wrapper around a `i64` value that
137 /// represents a number of microseconds, monotonically increasing
138 /// since an arbitrary moment in time, such as system startup.
139 ///
140 /// * A value of `0` is inherently arbitrary.
141 /// * A value less than `0` indicates a time before the starting
142 ///   point.
143 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
144 pub struct Instant {
145     micros: i64,
146 }
147 
148 #[allow(dead_code)]
149 impl Instant {
150     pub const ZERO: Instant = Instant::from_micros_const(0);
151 
152     /// mktime64 - 将日期转换为秒。
153     ///
154     /// ## 参数
155     ///
156     /// - year0: 要转换的年份
157     /// - mon0: 要转换的月份
158     /// - day: 要转换的天
159     /// - hour: 要转换的小时
160     /// - min: 要转换的分钟
161     /// - sec: 要转换的秒
162     ///
163     /// 将公历日期转换为1970-01-01 00:00:00以来的秒数。
164     /// 假设输入为正常的日期格式,即1980-12-31 23:59:59 => 年份=1980, 月=12, 日=31, 时=23, 分=59, 秒=59。
165     ///
166     /// [For the Julian calendar(俄罗斯在1917年之前使用,英国及其殖民地在大西洋1752年之前使用,
167     /// 其他地方在1582年之前使用,某些社区仍然在使用)省略-year/100+year/400项,
168     /// 并在结果上加10。]
169     ///
170     /// 这个算法最初由高斯(我认为是)发表。
171     ///
172     /// 要表示闰秒,可以通过将sec设为60(在ISO 8601允许)来调用此函数。
173     /// 闰秒与随后的秒一样处理,因为它们在UNIX时间中不存在。
174     ///
175     /// 支持将午夜作为当日末尾的24:00:00编码 - 即明天的午夜(在ISO 8601允许)。
176     ///
177     /// ## 返回
178     ///
179     /// 返回:给定输入日期自1970-01-01 00:00:00以来的秒数
180     pub fn mktime64(year0: u32, mon0: u32, day: u32, hour: u32, min: u32, sec: u32) -> Self {
181         let mut mon: i64 = mon0.into();
182         let mut year: u64 = year0.into();
183         let day: u64 = day.into();
184         let hour: u64 = hour.into();
185         let min: u64 = min.into();
186         let sec: u64 = sec.into();
187 
188         mon -= 2;
189         /* 1..12 -> 11,12,1..10 */
190         if mon <= 0 {
191             /* Puts Feb last since it has leap day */
192             mon += 12;
193             year -= 1;
194         }
195         let mon = mon as u64;
196 
197         let secs = ((((year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) + year * 365
198             - 719499)
199             * 24 + hour) /* now have hours - midnight tomorrow handled here */
200             * 60 + min)/* now have minutes */
201             * 60
202             + sec; /* finally seconds */
203 
204         Self::from_secs(secs as i64)
205     }
206 
207     /// Create a new `Instant` from a number of microseconds.
208     pub fn from_micros<T: Into<i64>>(micros: T) -> Instant {
209         Instant {
210             micros: micros.into(),
211         }
212     }
213 
214     pub const fn from_micros_const(micros: i64) -> Instant {
215         Instant { micros }
216     }
217 
218     /// Create a new `Instant` from a number of milliseconds.
219     pub fn from_millis<T: Into<i64>>(millis: T) -> Instant {
220         Instant {
221             micros: millis.into() * 1000,
222         }
223     }
224 
225     /// Create a new `Instant` from a number of milliseconds.
226     pub const fn from_millis_const(millis: i64) -> Instant {
227         Instant {
228             micros: millis * 1000,
229         }
230     }
231 
232     /// Create a new `Instant` from a number of seconds.
233     pub fn from_secs<T: Into<i64>>(secs: T) -> Instant {
234         Instant {
235             micros: secs.into() * 1000000,
236         }
237     }
238 
239     /// Create a new `Instant` from the current time
240     pub fn now() -> Instant {
241         let tm = getnstimeofday();
242         Self::from_micros(tm.tv_sec * 1000000 + tm.tv_nsec / 1000)
243     }
244 
245     /// The fractional number of milliseconds that have passed
246     /// since the beginning of time.
247     pub const fn millis(&self) -> i64 {
248         self.micros % 1000000 / 1000
249     }
250 
251     /// The fractional number of microseconds that have passed
252     /// since the beginning of time.
253     pub const fn micros(&self) -> i64 {
254         self.micros % 1000000
255     }
256 
257     /// The number of whole seconds that have passed since the
258     /// beginning of time.
259     pub const fn secs(&self) -> i64 {
260         self.micros / 1000000
261     }
262 
263     /// The total number of milliseconds that have passed since
264     /// the beginning of time.
265     pub const fn total_millis(&self) -> i64 {
266         self.micros / 1000
267     }
268     /// The total number of milliseconds that have passed since
269     /// the beginning of time.
270     pub const fn total_micros(&self) -> i64 {
271         self.micros
272     }
273 }
274 
275 impl fmt::Display for Instant {
276     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
277         write!(f, "{}.{:0>3}s", self.secs(), self.millis())
278     }
279 }
280 
281 impl ops::Add<Duration> for Instant {
282     type Output = Instant;
283 
284     fn add(self, rhs: Duration) -> Instant {
285         Instant::from_micros(self.micros + rhs.total_micros() as i64)
286     }
287 }
288 
289 impl ops::AddAssign<Duration> for Instant {
290     fn add_assign(&mut self, rhs: Duration) {
291         self.micros += rhs.total_micros() as i64;
292     }
293 }
294 
295 impl ops::Sub<Duration> for Instant {
296     type Output = Instant;
297 
298     fn sub(self, rhs: Duration) -> Instant {
299         Instant::from_micros(self.micros - rhs.total_micros() as i64)
300     }
301 }
302 
303 impl ops::SubAssign<Duration> for Instant {
304     fn sub_assign(&mut self, rhs: Duration) {
305         self.micros -= rhs.total_micros() as i64;
306     }
307 }
308 
309 impl ops::Sub<Instant> for Instant {
310     type Output = Duration;
311 
312     fn sub(self, rhs: Instant) -> Duration {
313         Duration::from_micros((self.micros - rhs.micros).unsigned_abs())
314     }
315 }
316 
317 /// A relative amount of time.
318 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
319 pub struct Duration {
320     micros: u64,
321 }
322 
323 impl Duration {
324     pub const ZERO: Duration = Duration::from_micros(0);
325     /// Create a new `Duration` from a number of microseconds.
326     pub const fn from_micros(micros: u64) -> Duration {
327         Duration { micros }
328     }
329 
330     /// Create a new `Duration` from a number of milliseconds.
331     pub const fn from_millis(millis: u64) -> Duration {
332         Duration {
333             micros: millis * 1000,
334         }
335     }
336 
337     /// Create a new `Instant` from a number of seconds.
338     pub const fn from_secs(secs: u64) -> Duration {
339         Duration {
340             micros: secs * 1000000,
341         }
342     }
343 
344     /// The fractional number of milliseconds in this `Duration`.
345     pub const fn millis(&self) -> u64 {
346         self.micros / 1000 % 1000
347     }
348 
349     /// The fractional number of milliseconds in this `Duration`.
350     pub const fn micros(&self) -> u64 {
351         self.micros % 1000000
352     }
353 
354     /// The number of whole seconds in this `Duration`.
355     pub const fn secs(&self) -> u64 {
356         self.micros / 1000000
357     }
358 
359     /// The total number of milliseconds in this `Duration`.
360     pub const fn total_millis(&self) -> u64 {
361         self.micros / 1000
362     }
363 
364     /// The total number of microseconds in this `Duration`.
365     pub const fn total_micros(&self) -> u64 {
366         self.micros
367     }
368 }
369 
370 impl fmt::Display for Duration {
371     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
372         write!(f, "{}.{:03}s", self.secs(), self.millis())
373     }
374 }
375 
376 impl ops::Add<Duration> for Duration {
377     type Output = Duration;
378 
379     fn add(self, rhs: Duration) -> Duration {
380         Duration::from_micros(self.micros + rhs.total_micros())
381     }
382 }
383 
384 impl ops::AddAssign<Duration> for Duration {
385     fn add_assign(&mut self, rhs: Duration) {
386         self.micros += rhs.total_micros();
387     }
388 }
389 
390 impl ops::Sub<Duration> for Duration {
391     type Output = Duration;
392 
393     fn sub(self, rhs: Duration) -> Duration {
394         Duration::from_micros(
395             self.micros
396                 .checked_sub(rhs.total_micros())
397                 .expect("overflow when subtracting durations"),
398         )
399     }
400 }
401 
402 impl ops::SubAssign<Duration> for Duration {
403     fn sub_assign(&mut self, rhs: Duration) {
404         self.micros = self
405             .micros
406             .checked_sub(rhs.total_micros())
407             .expect("overflow when subtracting durations");
408     }
409 }
410 
411 impl ops::Mul<u32> for Duration {
412     type Output = Duration;
413 
414     fn mul(self, rhs: u32) -> Duration {
415         Duration::from_micros(self.micros * rhs as u64)
416     }
417 }
418 
419 impl ops::MulAssign<u32> for Duration {
420     fn mul_assign(&mut self, rhs: u32) {
421         self.micros *= rhs as u64;
422     }
423 }
424 
425 impl ops::Div<u32> for Duration {
426     type Output = Duration;
427 
428     fn div(self, rhs: u32) -> Duration {
429         Duration::from_micros(self.micros / rhs as u64)
430     }
431 }
432 
433 impl ops::DivAssign<u32> for Duration {
434     fn div_assign(&mut self, rhs: u32) {
435         self.micros /= rhs as u64;
436     }
437 }
438 
439 impl ops::Shl<u32> for Duration {
440     type Output = Duration;
441 
442     fn shl(self, rhs: u32) -> Duration {
443         Duration::from_micros(self.micros << rhs)
444     }
445 }
446 
447 impl ops::ShlAssign<u32> for Duration {
448     fn shl_assign(&mut self, rhs: u32) {
449         self.micros <<= rhs;
450     }
451 }
452 
453 impl ops::Shr<u32> for Duration {
454     type Output = Duration;
455 
456     fn shr(self, rhs: u32) -> Duration {
457         Duration::from_micros(self.micros >> rhs)
458     }
459 }
460 
461 impl ops::ShrAssign<u32> for Duration {
462     fn shr_assign(&mut self, rhs: u32) {
463         self.micros >>= rhs;
464     }
465 }
466 
467 impl From<::core::time::Duration> for Duration {
468     fn from(other: ::core::time::Duration) -> Duration {
469         Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64)
470     }
471 }
472 
473 impl From<Duration> for ::core::time::Duration {
474     fn from(val: Duration) -> Self {
475         ::core::time::Duration::from_micros(val.total_micros())
476     }
477 }
478 
479 /// 支持与smoltcp的时间转换
480 impl From<smoltcp::time::Instant> for Instant {
481     fn from(val: smoltcp::time::Instant) -> Self {
482         Instant::from_micros(val.micros())
483     }
484 }
485 
486 impl From<Instant> for smoltcp::time::Instant {
487     fn from(val: Instant) -> Self {
488         smoltcp::time::Instant::from_millis(val.millis())
489     }
490 }
491 
492 /// 支持与smoltcp的时间转换
493 impl From<smoltcp::time::Duration> for Duration {
494     fn from(val: smoltcp::time::Duration) -> Self {
495         Duration::from_micros(val.micros())
496     }
497 }
498 
499 impl From<Duration> for smoltcp::time::Duration {
500     fn from(val: Duration) -> Self {
501         smoltcp::time::Duration::from_millis(val.millis())
502     }
503 }
504 
505 pub trait TimeArch {
506     /// Get CPU cycles (Read from register)
507     fn get_cycles() -> usize;
508 
509     /// Calculate expire cycles
510     ///
511     /// # Arguments
512     ///
513     /// - `ns` - The time to expire in nanoseconds
514     ///
515     /// # Returns
516     ///
517     /// The expire cycles
518     fn cal_expire_cycles(ns: usize) -> usize;
519 
520     /// 将CPU的时钟周期数转换为纳秒
521     fn cycles2ns(cycles: usize) -> usize;
522 }
523