xref: /linux-6.15/rust/kernel/time.rs (revision 48b7f4d2)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Time related primitives.
4 //!
5 //! This module contains the kernel APIs related to time and timers that
6 //! have been ported or wrapped for usage by Rust code in the kernel.
7 
8 /// The number of nanoseconds per millisecond.
9 pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64;
10 
11 /// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
12 pub type Jiffies = core::ffi::c_ulong;
13 
14 /// The millisecond time unit.
15 pub type Msecs = core::ffi::c_uint;
16 
17 /// Converts milliseconds to jiffies.
18 #[inline]
19 pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
20     // SAFETY: The `__msecs_to_jiffies` function is always safe to call no
21     // matter what the argument is.
22     unsafe { bindings::__msecs_to_jiffies(msecs) }
23 }
24 
25 /// A Rust wrapper around a `ktime_t`.
26 #[repr(transparent)]
27 #[derive(Copy, Clone)]
28 pub struct Ktime {
29     inner: bindings::ktime_t,
30 }
31 
32 impl Ktime {
33     /// Create a `Ktime` from a raw `ktime_t`.
34     #[inline]
35     pub fn from_raw(inner: bindings::ktime_t) -> Self {
36         Self { inner }
37     }
38 
39     /// Get the current time using `CLOCK_MONOTONIC`.
40     #[inline]
41     pub fn ktime_get() -> Self {
42         // SAFETY: It is always safe to call `ktime_get` outside of NMI context.
43         Self::from_raw(unsafe { bindings::ktime_get() })
44     }
45 
46     /// Divide the number of nanoseconds by a compile-time constant.
47     #[inline]
48     fn divns_constant<const DIV: i64>(self) -> i64 {
49         self.to_ns() / DIV
50     }
51 
52     /// Returns the number of nanoseconds.
53     #[inline]
54     pub fn to_ns(self) -> i64 {
55         self.inner
56     }
57 
58     /// Returns the number of milliseconds.
59     #[inline]
60     pub fn to_ms(self) -> i64 {
61         self.divns_constant::<NSEC_PER_MSEC>()
62     }
63 }
64 
65 /// Returns the number of milliseconds between two ktimes.
66 #[inline]
67 pub fn ktime_ms_delta(later: Ktime, earlier: Ktime) -> i64 {
68     (later - earlier).to_ms()
69 }
70 
71 impl core::ops::Sub for Ktime {
72     type Output = Ktime;
73 
74     #[inline]
75     fn sub(self, other: Ktime) -> Ktime {
76         Self {
77             inner: self.inner - other.inner,
78         }
79     }
80 }
81