xref: /linux/rust/kernel/time.rs (revision ced9ccd21fbc8ca941e6a0c2820c2df89239ccb9)
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 //! There are two types in this module:
9 //!
10 //! - The [`Instant`] type represents a specific point in time.
11 //! - The [`Delta`] type represents a span of time.
12 //!
13 //! Note that the C side uses `ktime_t` type to represent both. However, timestamp
14 //! and timedelta are different. To avoid confusion, we use two different types.
15 //!
16 //! A [`Instant`] object can be created by calling the [`Instant::now()`] function.
17 //! It represents a point in time at which the object was created.
18 //! By calling the [`Instant::elapsed()`] method, a [`Delta`] object representing
19 //! the elapsed time can be created. The [`Delta`] object can also be created
20 //! by subtracting two [`Instant`] objects.
21 //!
22 //! A [`Delta`] type supports methods to retrieve the duration in various units.
23 //!
24 //! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h).
25 //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h).
26 
27 use core::marker::PhantomData;
28 
29 pub mod hrtimer;
30 
31 /// The number of nanoseconds per microsecond.
32 pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64;
33 
34 /// The number of nanoseconds per millisecond.
35 pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64;
36 
37 /// The number of nanoseconds per second.
38 pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64;
39 
40 /// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
41 pub type Jiffies = crate::ffi::c_ulong;
42 
43 /// The millisecond time unit.
44 pub type Msecs = crate::ffi::c_uint;
45 
46 /// Converts milliseconds to jiffies.
47 #[inline]
48 pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
49     // SAFETY: The `__msecs_to_jiffies` function is always safe to call no
50     // matter what the argument is.
51     unsafe { bindings::__msecs_to_jiffies(msecs) }
52 }
53 
54 /// Trait for clock sources.
55 ///
56 /// Selection of the clock source depends on the use case. In some cases the usage of a
57 /// particular clock is mandatory, e.g. in network protocols, filesystems. In other
58 /// cases the user of the clock has to decide which clock is best suited for the
59 /// purpose. In most scenarios clock [`Monotonic`] is the best choice as it
60 /// provides a accurate monotonic notion of time (leap second smearing ignored).
61 pub trait ClockSource {
62     /// The kernel clock ID associated with this clock source.
63     ///
64     /// This constant corresponds to the C side `clockid_t` value.
65     const ID: bindings::clockid_t;
66 
67     /// Get the current time from the clock source.
68     ///
69     /// The function must return a value in the range from 0 to `KTIME_MAX`.
70     fn ktime_get() -> bindings::ktime_t;
71 }
72 
73 /// A monotonically increasing clock.
74 ///
75 /// A nonsettable system-wide clock that represents monotonic time since as
76 /// described by POSIX, "some unspecified point in the past". On Linux, that
77 /// point corresponds to the number of seconds that the system has been
78 /// running since it was booted.
79 ///
80 /// The CLOCK_MONOTONIC clock is not affected by discontinuous jumps in the
81 /// CLOCK_REAL (e.g., if the system administrator manually changes the
82 /// clock), but is affected by frequency adjustments. This clock does not
83 /// count time that the system is suspended.
84 pub struct Monotonic;
85 
86 impl ClockSource for Monotonic {
87     const ID: bindings::clockid_t = bindings::CLOCK_MONOTONIC as bindings::clockid_t;
88 
89     fn ktime_get() -> bindings::ktime_t {
90         // SAFETY: It is always safe to call `ktime_get()` outside of NMI context.
91         unsafe { bindings::ktime_get() }
92     }
93 }
94 
95 /// A settable system-wide clock that measures real (i.e., wall-clock) time.
96 ///
97 /// Setting this clock requires appropriate privileges. This clock is
98 /// affected by discontinuous jumps in the system time (e.g., if the system
99 /// administrator manually changes the clock), and by frequency adjustments
100 /// performed by NTP and similar applications via adjtime(3), adjtimex(2),
101 /// clock_adjtime(2), and ntp_adjtime(3). This clock normally counts the
102 /// number of seconds since 1970-01-01 00:00:00 Coordinated Universal Time
103 /// (UTC) except that it ignores leap seconds; near a leap second it may be
104 /// adjusted by leap second smearing to stay roughly in sync with UTC. Leap
105 /// second smearing applies frequency adjustments to the clock to speed up
106 /// or slow down the clock to account for the leap second without
107 /// discontinuities in the clock. If leap second smearing is not applied,
108 /// the clock will experience discontinuity around leap second adjustment.
109 pub struct RealTime;
110 
111 impl ClockSource for RealTime {
112     const ID: bindings::clockid_t = bindings::CLOCK_REALTIME as bindings::clockid_t;
113 
114     fn ktime_get() -> bindings::ktime_t {
115         // SAFETY: It is always safe to call `ktime_get_real()` outside of NMI context.
116         unsafe { bindings::ktime_get_real() }
117     }
118 }
119 
120 /// A monotonic that ticks while system is suspended.
121 ///
122 /// A nonsettable system-wide clock that is identical to CLOCK_MONOTONIC,
123 /// except that it also includes any time that the system is suspended. This
124 /// allows applications to get a suspend-aware monotonic clock without
125 /// having to deal with the complications of CLOCK_REALTIME, which may have
126 /// discontinuities if the time is changed using settimeofday(2) or similar.
127 pub struct BootTime;
128 
129 impl ClockSource for BootTime {
130     const ID: bindings::clockid_t = bindings::CLOCK_BOOTTIME as bindings::clockid_t;
131 
132     fn ktime_get() -> bindings::ktime_t {
133         // SAFETY: It is always safe to call `ktime_get_boottime()` outside of NMI context.
134         unsafe { bindings::ktime_get_boottime() }
135     }
136 }
137 
138 /// International Atomic Time.
139 ///
140 /// A system-wide clock derived from wall-clock time but counting leap seconds.
141 ///
142 /// This clock is coupled to CLOCK_REALTIME and will be set when CLOCK_REALTIME is
143 /// set, or when the offset to CLOCK_REALTIME is changed via adjtimex(2). This
144 /// usually happens during boot and **should** not happen during normal operations.
145 /// However, if NTP or another application adjusts CLOCK_REALTIME by leap second
146 /// smearing, this clock will not be precise during leap second smearing.
147 ///
148 /// The acronym TAI refers to International Atomic Time.
149 pub struct Tai;
150 
151 impl ClockSource for Tai {
152     const ID: bindings::clockid_t = bindings::CLOCK_TAI as bindings::clockid_t;
153 
154     fn ktime_get() -> bindings::ktime_t {
155         // SAFETY: It is always safe to call `ktime_get_tai()` outside of NMI context.
156         unsafe { bindings::ktime_get_clocktai() }
157     }
158 }
159 
160 /// A specific point in time.
161 ///
162 /// # Invariants
163 ///
164 /// The `inner` value is in the range from 0 to `KTIME_MAX`.
165 #[repr(transparent)]
166 #[derive(PartialEq, PartialOrd, Eq, Ord)]
167 pub struct Instant<C: ClockSource> {
168     inner: bindings::ktime_t,
169     _c: PhantomData<C>,
170 }
171 
172 impl<C: ClockSource> Clone for Instant<C> {
173     fn clone(&self) -> Self {
174         *self
175     }
176 }
177 
178 impl<C: ClockSource> Copy for Instant<C> {}
179 
180 impl<C: ClockSource> Instant<C> {
181     /// Get the current time from the clock source.
182     #[inline]
183     pub fn now() -> Self {
184         // INVARIANT: The `ClockSource::ktime_get()` function returns a value in the range
185         // from 0 to `KTIME_MAX`.
186         Self {
187             inner: C::ktime_get(),
188             _c: PhantomData,
189         }
190     }
191 
192     /// Return the amount of time elapsed since the [`Instant`].
193     #[inline]
194     pub fn elapsed(&self) -> Delta {
195         Self::now() - *self
196     }
197 }
198 
199 impl<C: ClockSource> core::ops::Sub for Instant<C> {
200     type Output = Delta;
201 
202     // By the type invariant, it never overflows.
203     #[inline]
204     fn sub(self, other: Instant<C>) -> Delta {
205         Delta {
206             nanos: self.inner - other.inner,
207         }
208     }
209 }
210 
211 /// A span of time.
212 ///
213 /// This struct represents a span of time, with its value stored as nanoseconds.
214 /// The value can represent any valid i64 value, including negative, zero, and
215 /// positive numbers.
216 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
217 pub struct Delta {
218     nanos: i64,
219 }
220 
221 impl Delta {
222     /// A span of time equal to zero.
223     pub const ZERO: Self = Self { nanos: 0 };
224 
225     /// Create a new [`Delta`] from a number of microseconds.
226     ///
227     /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775.
228     /// If `micros` is outside this range, `i64::MIN` is used for negative values,
229     /// and `i64::MAX` is used for positive values due to saturation.
230     #[inline]
231     pub const fn from_micros(micros: i64) -> Self {
232         Self {
233             nanos: micros.saturating_mul(NSEC_PER_USEC),
234         }
235     }
236 
237     /// Create a new [`Delta`] from a number of milliseconds.
238     ///
239     /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854.
240     /// If `millis` is outside this range, `i64::MIN` is used for negative values,
241     /// and `i64::MAX` is used for positive values due to saturation.
242     #[inline]
243     pub const fn from_millis(millis: i64) -> Self {
244         Self {
245             nanos: millis.saturating_mul(NSEC_PER_MSEC),
246         }
247     }
248 
249     /// Create a new [`Delta`] from a number of seconds.
250     ///
251     /// The `secs` can range from -9_223_372_036 to 9_223_372_036.
252     /// If `secs` is outside this range, `i64::MIN` is used for negative values,
253     /// and `i64::MAX` is used for positive values due to saturation.
254     #[inline]
255     pub const fn from_secs(secs: i64) -> Self {
256         Self {
257             nanos: secs.saturating_mul(NSEC_PER_SEC),
258         }
259     }
260 
261     /// Return `true` if the [`Delta`] spans no time.
262     #[inline]
263     pub fn is_zero(self) -> bool {
264         self.as_nanos() == 0
265     }
266 
267     /// Return `true` if the [`Delta`] spans a negative amount of time.
268     #[inline]
269     pub fn is_negative(self) -> bool {
270         self.as_nanos() < 0
271     }
272 
273     /// Return the number of nanoseconds in the [`Delta`].
274     #[inline]
275     pub const fn as_nanos(self) -> i64 {
276         self.nanos
277     }
278 
279     /// Return the smallest number of microseconds greater than or equal
280     /// to the value in the [`Delta`].
281     #[inline]
282     pub fn as_micros_ceil(self) -> i64 {
283         #[cfg(CONFIG_64BIT)]
284         {
285             self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC
286         }
287 
288         #[cfg(not(CONFIG_64BIT))]
289         // SAFETY: It is always safe to call `ktime_to_us()` with any value.
290         unsafe {
291             bindings::ktime_to_us(self.as_nanos().saturating_add(NSEC_PER_USEC - 1))
292         }
293     }
294 
295     /// Return the number of milliseconds in the [`Delta`].
296     #[inline]
297     pub fn as_millis(self) -> i64 {
298         #[cfg(CONFIG_64BIT)]
299         {
300             self.as_nanos() / NSEC_PER_MSEC
301         }
302 
303         #[cfg(not(CONFIG_64BIT))]
304         // SAFETY: It is always safe to call `ktime_to_ms()` with any value.
305         unsafe {
306             bindings::ktime_to_ms(self.as_nanos())
307         }
308     }
309 }
310