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