xref: /linux/rust/kernel/time.rs (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
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 use core::ops;
29 
30 pub mod delay;
31 pub mod hrtimer;
32 
33 /// The number of nanoseconds per microsecond.
34 pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64;
35 
36 /// The number of nanoseconds per millisecond.
37 pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64;
38 
39 /// The number of nanoseconds per second.
40 pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64;
41 
42 /// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
43 pub type Jiffies = crate::ffi::c_ulong;
44 
45 /// The millisecond time unit.
46 pub type Msecs = crate::ffi::c_uint;
47 
48 /// Converts milliseconds to jiffies.
49 #[inline]
50 pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
51     // SAFETY: The `__msecs_to_jiffies` function is always safe to call no
52     // matter what the argument is.
53     unsafe { bindings::__msecs_to_jiffies(msecs) }
54 }
55 
56 /// Trait for clock sources.
57 ///
58 /// Selection of the clock source depends on the use case. In some cases the usage of a
59 /// particular clock is mandatory, e.g. in network protocols, filesystems. In other
60 /// cases the user of the clock has to decide which clock is best suited for the
61 /// purpose. In most scenarios clock [`Monotonic`] is the best choice as it
62 /// provides a accurate monotonic notion of time (leap second smearing ignored).
63 pub trait ClockSource {
64     /// The kernel clock ID associated with this clock source.
65     ///
66     /// This constant corresponds to the C side `clockid_t` value.
67     const ID: bindings::clockid_t;
68 
69     /// Get the current time from the clock source.
70     ///
71     /// The function must return a value in the range from 0 to `KTIME_MAX`.
72     fn ktime_get() -> bindings::ktime_t;
73 }
74 
75 /// A monotonically increasing clock.
76 ///
77 /// A nonsettable system-wide clock that represents monotonic time since as
78 /// described by POSIX, "some unspecified point in the past". On Linux, that
79 /// point corresponds to the number of seconds that the system has been
80 /// running since it was booted.
81 ///
82 /// The CLOCK_MONOTONIC clock is not affected by discontinuous jumps in the
83 /// CLOCK_REAL (e.g., if the system administrator manually changes the
84 /// clock), but is affected by frequency adjustments. This clock does not
85 /// count time that the system is suspended.
86 pub struct Monotonic;
87 
88 impl ClockSource for Monotonic {
89     const ID: bindings::clockid_t = bindings::CLOCK_MONOTONIC as bindings::clockid_t;
90 
91     fn ktime_get() -> bindings::ktime_t {
92         // SAFETY: It is always safe to call `ktime_get()` outside of NMI context.
93         unsafe { bindings::ktime_get() }
94     }
95 }
96 
97 /// A settable system-wide clock that measures real (i.e., wall-clock) time.
98 ///
99 /// Setting this clock requires appropriate privileges. This clock is
100 /// affected by discontinuous jumps in the system time (e.g., if the system
101 /// administrator manually changes the clock), and by frequency adjustments
102 /// performed by NTP and similar applications via adjtime(3), adjtimex(2),
103 /// clock_adjtime(2), and ntp_adjtime(3). This clock normally counts the
104 /// number of seconds since 1970-01-01 00:00:00 Coordinated Universal Time
105 /// (UTC) except that it ignores leap seconds; near a leap second it may be
106 /// adjusted by leap second smearing to stay roughly in sync with UTC. Leap
107 /// second smearing applies frequency adjustments to the clock to speed up
108 /// or slow down the clock to account for the leap second without
109 /// discontinuities in the clock. If leap second smearing is not applied,
110 /// the clock will experience discontinuity around leap second adjustment.
111 pub struct RealTime;
112 
113 impl ClockSource for RealTime {
114     const ID: bindings::clockid_t = bindings::CLOCK_REALTIME as bindings::clockid_t;
115 
116     fn ktime_get() -> bindings::ktime_t {
117         // SAFETY: It is always safe to call `ktime_get_real()` outside of NMI context.
118         unsafe { bindings::ktime_get_real() }
119     }
120 }
121 
122 /// A monotonic that ticks while system is suspended.
123 ///
124 /// A nonsettable system-wide clock that is identical to CLOCK_MONOTONIC,
125 /// except that it also includes any time that the system is suspended. This
126 /// allows applications to get a suspend-aware monotonic clock without
127 /// having to deal with the complications of CLOCK_REALTIME, which may have
128 /// discontinuities if the time is changed using settimeofday(2) or similar.
129 pub struct BootTime;
130 
131 impl ClockSource for BootTime {
132     const ID: bindings::clockid_t = bindings::CLOCK_BOOTTIME as bindings::clockid_t;
133 
134     fn ktime_get() -> bindings::ktime_t {
135         // SAFETY: It is always safe to call `ktime_get_boottime()` outside of NMI context.
136         unsafe { bindings::ktime_get_boottime() }
137     }
138 }
139 
140 /// International Atomic Time.
141 ///
142 /// A system-wide clock derived from wall-clock time but counting leap seconds.
143 ///
144 /// This clock is coupled to CLOCK_REALTIME and will be set when CLOCK_REALTIME is
145 /// set, or when the offset to CLOCK_REALTIME is changed via adjtimex(2). This
146 /// usually happens during boot and **should** not happen during normal operations.
147 /// However, if NTP or another application adjusts CLOCK_REALTIME by leap second
148 /// smearing, this clock will not be precise during leap second smearing.
149 ///
150 /// The acronym TAI refers to International Atomic Time.
151 pub struct Tai;
152 
153 impl ClockSource for Tai {
154     const ID: bindings::clockid_t = bindings::CLOCK_TAI as bindings::clockid_t;
155 
156     fn ktime_get() -> bindings::ktime_t {
157         // SAFETY: It is always safe to call `ktime_get_tai()` outside of NMI context.
158         unsafe { bindings::ktime_get_clocktai() }
159     }
160 }
161 
162 /// A specific point in time.
163 ///
164 /// # Invariants
165 ///
166 /// The `inner` value is in the range from 0 to `KTIME_MAX`.
167 #[repr(transparent)]
168 #[derive(PartialEq, PartialOrd, Eq, Ord)]
169 pub struct Instant<C: ClockSource> {
170     inner: bindings::ktime_t,
171     _c: PhantomData<C>,
172 }
173 
174 impl<C: ClockSource> Clone for Instant<C> {
175     fn clone(&self) -> Self {
176         *self
177     }
178 }
179 
180 impl<C: ClockSource> Copy for Instant<C> {}
181 
182 impl<C: ClockSource> Instant<C> {
183     /// Get the current time from the clock source.
184     #[inline]
185     pub fn now() -> Self {
186         // INVARIANT: The `ClockSource::ktime_get()` function returns a value in the range
187         // from 0 to `KTIME_MAX`.
188         Self {
189             inner: C::ktime_get(),
190             _c: PhantomData,
191         }
192     }
193 
194     /// Return the amount of time elapsed since the [`Instant`].
195     #[inline]
196     pub fn elapsed(&self) -> Delta {
197         Self::now() - *self
198     }
199 
200     #[inline]
201     pub(crate) fn as_nanos(&self) -> i64 {
202         self.inner
203     }
204 
205     /// Create an [`Instant`] from a `ktime_t` without checking if it is non-negative.
206     ///
207     /// # Panics
208     ///
209     /// On debug builds, this function will panic if `ktime` is not in the range from 0 to
210     /// `KTIME_MAX`.
211     ///
212     /// # Safety
213     ///
214     /// The caller promises that `ktime` is in the range from 0 to `KTIME_MAX`.
215     #[inline]
216     pub(crate) unsafe fn from_ktime(ktime: bindings::ktime_t) -> Self {
217         debug_assert!(ktime >= 0);
218 
219         // INVARIANT: Our safety contract ensures that `ktime` is in the range from 0 to
220         // `KTIME_MAX`.
221         Self {
222             inner: ktime,
223             _c: PhantomData,
224         }
225     }
226 }
227 
228 impl<C: ClockSource> ops::Sub for Instant<C> {
229     type Output = Delta;
230 
231     // By the type invariant, it never overflows.
232     #[inline]
233     fn sub(self, other: Instant<C>) -> Delta {
234         Delta {
235             nanos: self.inner - other.inner,
236         }
237     }
238 }
239 
240 impl<T: ClockSource> ops::Add<Delta> for Instant<T> {
241     type Output = Self;
242 
243     #[inline]
244     fn add(self, rhs: Delta) -> Self::Output {
245         // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
246         // (e.g. go above `KTIME_MAX`)
247         let res = self.inner + rhs.nanos;
248 
249         // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
250         #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
251         assert!(res >= 0);
252 
253         Self {
254             inner: res,
255             _c: PhantomData,
256         }
257     }
258 }
259 
260 impl<T: ClockSource> ops::Sub<Delta> for Instant<T> {
261     type Output = Self;
262 
263     #[inline]
264     fn sub(self, rhs: Delta) -> Self::Output {
265         // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
266         // (e.g. go above `KTIME_MAX`)
267         let res = self.inner - rhs.nanos;
268 
269         // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
270         #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
271         assert!(res >= 0);
272 
273         Self {
274             inner: res,
275             _c: PhantomData,
276         }
277     }
278 }
279 
280 /// A span of time.
281 ///
282 /// This struct represents a span of time, with its value stored as nanoseconds.
283 /// The value can represent any valid i64 value, including negative, zero, and
284 /// positive numbers.
285 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
286 pub struct Delta {
287     nanos: i64,
288 }
289 
290 impl ops::Add for Delta {
291     type Output = Self;
292 
293     #[inline]
294     fn add(self, rhs: Self) -> Self {
295         Self {
296             nanos: self.nanos + rhs.nanos,
297         }
298     }
299 }
300 
301 impl ops::AddAssign for Delta {
302     #[inline]
303     fn add_assign(&mut self, rhs: Self) {
304         self.nanos += rhs.nanos;
305     }
306 }
307 
308 impl ops::Sub for Delta {
309     type Output = Self;
310 
311     #[inline]
312     fn sub(self, rhs: Self) -> Self::Output {
313         Self {
314             nanos: self.nanos - rhs.nanos,
315         }
316     }
317 }
318 
319 impl ops::SubAssign for Delta {
320     #[inline]
321     fn sub_assign(&mut self, rhs: Self) {
322         self.nanos -= rhs.nanos;
323     }
324 }
325 
326 impl ops::Mul<i64> for Delta {
327     type Output = Self;
328 
329     #[inline]
330     fn mul(self, rhs: i64) -> Self::Output {
331         Self {
332             nanos: self.nanos * rhs,
333         }
334     }
335 }
336 
337 impl ops::MulAssign<i64> for Delta {
338     #[inline]
339     fn mul_assign(&mut self, rhs: i64) {
340         self.nanos *= rhs;
341     }
342 }
343 
344 impl ops::Div for Delta {
345     type Output = i64;
346 
347     #[inline]
348     fn div(self, rhs: Self) -> Self::Output {
349         #[cfg(CONFIG_64BIT)]
350         {
351             self.nanos / rhs.nanos
352         }
353 
354         #[cfg(not(CONFIG_64BIT))]
355         {
356             // SAFETY: This function is always safe to call regardless of the input values
357             unsafe { bindings::div64_s64(self.nanos, rhs.nanos) }
358         }
359     }
360 }
361 
362 impl Delta {
363     /// A span of time equal to zero.
364     pub const ZERO: Self = Self { nanos: 0 };
365 
366     /// Create a new [`Delta`] from a number of microseconds.
367     ///
368     /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775.
369     /// If `micros` is outside this range, `i64::MIN` is used for negative values,
370     /// and `i64::MAX` is used for positive values due to saturation.
371     #[inline]
372     pub const fn from_micros(micros: i64) -> Self {
373         Self {
374             nanos: micros.saturating_mul(NSEC_PER_USEC),
375         }
376     }
377 
378     /// Create a new [`Delta`] from a number of milliseconds.
379     ///
380     /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854.
381     /// If `millis` is outside this range, `i64::MIN` is used for negative values,
382     /// and `i64::MAX` is used for positive values due to saturation.
383     #[inline]
384     pub const fn from_millis(millis: i64) -> Self {
385         Self {
386             nanos: millis.saturating_mul(NSEC_PER_MSEC),
387         }
388     }
389 
390     /// Create a new [`Delta`] from a number of seconds.
391     ///
392     /// The `secs` can range from -9_223_372_036 to 9_223_372_036.
393     /// If `secs` is outside this range, `i64::MIN` is used for negative values,
394     /// and `i64::MAX` is used for positive values due to saturation.
395     #[inline]
396     pub const fn from_secs(secs: i64) -> Self {
397         Self {
398             nanos: secs.saturating_mul(NSEC_PER_SEC),
399         }
400     }
401 
402     /// Return `true` if the [`Delta`] spans no time.
403     #[inline]
404     pub fn is_zero(self) -> bool {
405         self.as_nanos() == 0
406     }
407 
408     /// Return `true` if the [`Delta`] spans a negative amount of time.
409     #[inline]
410     pub fn is_negative(self) -> bool {
411         self.as_nanos() < 0
412     }
413 
414     /// Return the number of nanoseconds in the [`Delta`].
415     #[inline]
416     pub const fn as_nanos(self) -> i64 {
417         self.nanos
418     }
419 
420     /// Return the smallest number of microseconds greater than or equal
421     /// to the value in the [`Delta`].
422     #[inline]
423     pub fn as_micros_ceil(self) -> i64 {
424         #[cfg(CONFIG_64BIT)]
425         {
426             self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC
427         }
428 
429         #[cfg(not(CONFIG_64BIT))]
430         // SAFETY: It is always safe to call `ktime_to_us()` with any value.
431         unsafe {
432             bindings::ktime_to_us(self.as_nanos().saturating_add(NSEC_PER_USEC - 1))
433         }
434     }
435 
436     /// Return the number of milliseconds in the [`Delta`].
437     #[inline]
438     pub fn as_millis(self) -> i64 {
439         #[cfg(CONFIG_64BIT)]
440         {
441             self.as_nanos() / NSEC_PER_MSEC
442         }
443 
444         #[cfg(not(CONFIG_64BIT))]
445         // SAFETY: It is always safe to call `ktime_to_ms()` with any value.
446         unsafe {
447             bindings::ktime_to_ms(self.as_nanos())
448         }
449     }
450 
451     /// Return `self % dividend` where `dividend` is in nanoseconds.
452     ///
453     /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is
454     /// limited to 32 bit dividends.
455     #[inline]
456     pub fn rem_nanos(self, dividend: i32) -> Self {
457         #[cfg(CONFIG_64BIT)]
458         {
459             Self {
460                 nanos: self.as_nanos() % i64::from(dividend),
461             }
462         }
463 
464         #[cfg(not(CONFIG_64BIT))]
465         {
466             let mut rem = 0;
467 
468             // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it.
469             unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) };
470 
471             Self {
472                 nanos: i64::from(rem),
473             }
474         }
475     }
476 }
477