xref: /linux/rust/kernel/time.rs (revision 85cdaca6970028bf6f544c355c90035586836ddf)
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 ///
64 /// # Safety
65 ///
66 /// Implementers must ensure that `ktime_get()` returns a value in the inclusive range
67 /// `0..=KTIME_MAX` (i.e., greater than or equal to 0 and less than or equal to
68 /// `KTIME_MAX`, where `KTIME_MAX` equals `i64::MAX`).
69 pub unsafe trait ClockSource {
70     /// The kernel clock ID associated with this clock source.
71     ///
72     /// This constant corresponds to the C side `clockid_t` value.
73     const ID: bindings::clockid_t;
74 
75     /// Get the current time from the clock source.
76     ///
77     /// The function must return a value in the range `0..=KTIME_MAX`.
78     fn ktime_get() -> bindings::ktime_t;
79 }
80 
81 /// A monotonically increasing clock.
82 ///
83 /// A nonsettable system-wide clock that represents monotonic time since as
84 /// described by POSIX, "some unspecified point in the past". On Linux, that
85 /// point corresponds to the number of seconds that the system has been
86 /// running since it was booted.
87 ///
88 /// The CLOCK_MONOTONIC clock is not affected by discontinuous jumps in the
89 /// CLOCK_REAL (e.g., if the system administrator manually changes the
90 /// clock), but is affected by frequency adjustments. This clock does not
91 /// count time that the system is suspended.
92 pub struct Monotonic;
93 
94 // SAFETY: The kernel's `ktime_get()` is guaranteed to return a value
95 // in `0..=KTIME_MAX`.
96 unsafe impl ClockSource for Monotonic {
97     const ID: bindings::clockid_t = bindings::CLOCK_MONOTONIC as bindings::clockid_t;
98 
99     fn ktime_get() -> bindings::ktime_t {
100         // SAFETY: It is always safe to call `ktime_get()` outside of NMI context.
101         unsafe { bindings::ktime_get() }
102     }
103 }
104 
105 /// A settable system-wide clock that measures real (i.e., wall-clock) time.
106 ///
107 /// Setting this clock requires appropriate privileges. This clock is
108 /// affected by discontinuous jumps in the system time (e.g., if the system
109 /// administrator manually changes the clock), and by frequency adjustments
110 /// performed by NTP and similar applications via adjtime(3), adjtimex(2),
111 /// clock_adjtime(2), and ntp_adjtime(3). This clock normally counts the
112 /// number of seconds since 1970-01-01 00:00:00 Coordinated Universal Time
113 /// (UTC) except that it ignores leap seconds; near a leap second it may be
114 /// adjusted by leap second smearing to stay roughly in sync with UTC. Leap
115 /// second smearing applies frequency adjustments to the clock to speed up
116 /// or slow down the clock to account for the leap second without
117 /// discontinuities in the clock. If leap second smearing is not applied,
118 /// the clock will experience discontinuity around leap second adjustment.
119 pub struct RealTime;
120 
121 // SAFETY: The kernel's `ktime_get_real()` is guaranteed to return a value
122 // in `0..=KTIME_MAX`.
123 unsafe impl ClockSource for RealTime {
124     const ID: bindings::clockid_t = bindings::CLOCK_REALTIME as bindings::clockid_t;
125 
126     fn ktime_get() -> bindings::ktime_t {
127         // SAFETY: It is always safe to call `ktime_get_real()` outside of NMI context.
128         unsafe { bindings::ktime_get_real() }
129     }
130 }
131 
132 /// A monotonic that ticks while system is suspended.
133 ///
134 /// A nonsettable system-wide clock that is identical to CLOCK_MONOTONIC,
135 /// except that it also includes any time that the system is suspended. This
136 /// allows applications to get a suspend-aware monotonic clock without
137 /// having to deal with the complications of CLOCK_REALTIME, which may have
138 /// discontinuities if the time is changed using settimeofday(2) or similar.
139 pub struct BootTime;
140 
141 // SAFETY: The kernel's `ktime_get_boottime()` is guaranteed to return a value
142 // in `0..=KTIME_MAX`.
143 unsafe impl ClockSource for BootTime {
144     const ID: bindings::clockid_t = bindings::CLOCK_BOOTTIME as bindings::clockid_t;
145 
146     fn ktime_get() -> bindings::ktime_t {
147         // SAFETY: It is always safe to call `ktime_get_boottime()` outside of NMI context.
148         unsafe { bindings::ktime_get_boottime() }
149     }
150 }
151 
152 /// International Atomic Time.
153 ///
154 /// A system-wide clock derived from wall-clock time but counting leap seconds.
155 ///
156 /// This clock is coupled to CLOCK_REALTIME and will be set when CLOCK_REALTIME is
157 /// set, or when the offset to CLOCK_REALTIME is changed via adjtimex(2). This
158 /// usually happens during boot and **should** not happen during normal operations.
159 /// However, if NTP or another application adjusts CLOCK_REALTIME by leap second
160 /// smearing, this clock will not be precise during leap second smearing.
161 ///
162 /// The acronym TAI refers to International Atomic Time.
163 pub struct Tai;
164 
165 // SAFETY: The kernel's `ktime_get_clocktai()` is guaranteed to return a value
166 // in `0..=KTIME_MAX`.
167 unsafe impl ClockSource for Tai {
168     const ID: bindings::clockid_t = bindings::CLOCK_TAI as bindings::clockid_t;
169 
170     fn ktime_get() -> bindings::ktime_t {
171         // SAFETY: It is always safe to call `ktime_get_tai()` outside of NMI context.
172         unsafe { bindings::ktime_get_clocktai() }
173     }
174 }
175 
176 /// A specific point in time.
177 ///
178 /// # Invariants
179 ///
180 /// The `inner` value is in the range from 0 to `KTIME_MAX`.
181 #[repr(transparent)]
182 #[derive(PartialEq, PartialOrd, Eq, Ord)]
183 pub struct Instant<C: ClockSource> {
184     inner: bindings::ktime_t,
185     _c: PhantomData<C>,
186 }
187 
188 impl<C: ClockSource> Clone for Instant<C> {
189     fn clone(&self) -> Self {
190         *self
191     }
192 }
193 
194 impl<C: ClockSource> Copy for Instant<C> {}
195 
196 impl<C: ClockSource> Instant<C> {
197     /// Get the current time from the clock source.
198     #[inline]
199     pub fn now() -> Self {
200         // INVARIANT: The `ClockSource::ktime_get()` function returns a value in the range
201         // from 0 to `KTIME_MAX`.
202         Self {
203             inner: C::ktime_get(),
204             _c: PhantomData,
205         }
206     }
207 
208     /// Return the amount of time elapsed since the [`Instant`].
209     #[inline]
210     pub fn elapsed(&self) -> Delta {
211         Self::now() - *self
212     }
213 
214     #[inline]
215     pub(crate) fn as_nanos(&self) -> i64 {
216         self.inner
217     }
218 
219     /// Create an [`Instant`] from a `ktime_t` without checking if it is non-negative.
220     ///
221     /// # Panics
222     ///
223     /// On debug builds, this function will panic if `ktime` is not in the range from 0 to
224     /// `KTIME_MAX`.
225     ///
226     /// # Safety
227     ///
228     /// The caller promises that `ktime` is in the range from 0 to `KTIME_MAX`.
229     #[inline]
230     pub(crate) unsafe fn from_ktime(ktime: bindings::ktime_t) -> Self {
231         debug_assert!(ktime >= 0);
232 
233         // INVARIANT: Our safety contract ensures that `ktime` is in the range from 0 to
234         // `KTIME_MAX`.
235         Self {
236             inner: ktime,
237             _c: PhantomData,
238         }
239     }
240 }
241 
242 impl<C: ClockSource> ops::Sub for Instant<C> {
243     type Output = Delta;
244 
245     // By the type invariant, it never overflows.
246     #[inline]
247     fn sub(self, other: Instant<C>) -> Delta {
248         Delta {
249             value: self.inner - other.inner,
250         }
251     }
252 }
253 
254 impl<T: ClockSource> ops::Add<Delta> for Instant<T> {
255     type Output = Self;
256 
257     #[inline]
258     fn add(self, rhs: Delta) -> Self::Output {
259         // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
260         // (e.g. go above `KTIME_MAX`)
261         let res = self.inner + rhs.value;
262 
263         // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
264         #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
265         assert!(res >= 0);
266 
267         Self {
268             inner: res,
269             _c: PhantomData,
270         }
271     }
272 }
273 
274 impl<T: ClockSource> ops::Sub<Delta> for Instant<T> {
275     type Output = Self;
276 
277     #[inline]
278     fn sub(self, rhs: Delta) -> Self::Output {
279         // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
280         // (e.g. go above `KTIME_MAX`)
281         let res = self.inner - rhs.value;
282 
283         // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
284         #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
285         assert!(res >= 0);
286 
287         Self {
288             inner: res,
289             _c: PhantomData,
290         }
291     }
292 }
293 
294 mod private {
295     pub trait Sealed {}
296 
297     impl Sealed for super::Nsec {}
298     impl Sealed for super::Jiffy {}
299 }
300 
301 /// A trait for time units.
302 pub trait TimeUnit: private::Sealed {
303     /// The underlying representation of the time unit.
304     type Repr: Copy + Clone + PartialEq + PartialOrd + Eq + Ord + core::fmt::Debug;
305 }
306 
307 /// A time unit of nanoseconds.
308 ///
309 /// A [`Delta<Nsec>`] stores its value as [`i64`] nanoseconds and can represent
310 /// any [`i64`] value, including negative, zero, and positive numbers.
311 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
312 pub enum Nsec {}
313 
314 impl TimeUnit for Nsec {
315     type Repr = i64;
316 }
317 
318 /// A time unit of jiffies.
319 ///
320 /// A [`Delta<Jiffy>`] stores its value as [`isize`] jiffies and can represent
321 /// any [`isize`] value, including negative, zero, and positive numbers.
322 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
323 pub enum Jiffy {}
324 
325 impl TimeUnit for Jiffy {
326     type Repr = isize;
327 }
328 
329 /// A span of time.
330 ///
331 /// The span is stored in the unit given by the type parameter `U` (see
332 /// [`TimeUnit`]); its value has type `U::Repr`. `U` defaults to [`Nsec`], so a
333 /// plain [`Delta`] is a span in nanoseconds. The value can be negative, zero, or
334 /// positive.
335 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
336 pub struct Delta<U: TimeUnit = Nsec> {
337     value: U::Repr,
338 }
339 
340 impl Delta<Jiffy> {
341     /// Create a new [`Delta`] from a number of jiffies.
342     #[inline]
343     pub const fn from_jiffies(jiffies: isize) -> Self {
344         Self { value: jiffies }
345     }
346 
347     /// Return the number of jiffies in the [`Delta`].
348     #[inline]
349     pub const fn as_jiffies(self) -> isize {
350         self.value
351     }
352 }
353 
354 impl ops::Add for Delta {
355     type Output = Self;
356 
357     #[inline]
358     fn add(self, rhs: Self) -> Self {
359         Self {
360             value: self.value + rhs.value,
361         }
362     }
363 }
364 
365 impl ops::AddAssign for Delta {
366     #[inline]
367     fn add_assign(&mut self, rhs: Self) {
368         self.value += rhs.value;
369     }
370 }
371 
372 impl ops::Sub for Delta {
373     type Output = Self;
374 
375     #[inline]
376     fn sub(self, rhs: Self) -> Self::Output {
377         Self {
378             value: self.value - rhs.value,
379         }
380     }
381 }
382 
383 impl ops::SubAssign for Delta {
384     #[inline]
385     fn sub_assign(&mut self, rhs: Self) {
386         self.value -= rhs.value;
387     }
388 }
389 
390 impl ops::Mul<i64> for Delta {
391     type Output = Self;
392 
393     #[inline]
394     fn mul(self, rhs: i64) -> Self::Output {
395         Self {
396             value: self.value * rhs,
397         }
398     }
399 }
400 
401 impl ops::MulAssign<i64> for Delta {
402     #[inline]
403     fn mul_assign(&mut self, rhs: i64) {
404         self.value *= rhs;
405     }
406 }
407 
408 impl ops::Div for Delta {
409     type Output = i64;
410 
411     #[inline]
412     fn div(self, rhs: Self) -> Self::Output {
413         #[cfg(CONFIG_64BIT)]
414         {
415             self.value / rhs.value
416         }
417 
418         #[cfg(not(CONFIG_64BIT))]
419         {
420             // SAFETY: This function is always safe to call regardless of the input values
421             unsafe { bindings::div64_s64(self.value, rhs.value) }
422         }
423     }
424 }
425 
426 impl Delta {
427     /// A span of time equal to zero.
428     pub const ZERO: Self = Self { value: 0 };
429 
430     /// Create a new [`Delta`] from a number of nanoseconds.
431     #[inline]
432     pub const fn from_nanos(nanos: i64) -> Self {
433         Self { value: nanos }
434     }
435 
436     /// Create a new [`Delta`] from a number of microseconds.
437     ///
438     /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775.
439     /// If `micros` is outside this range, `i64::MIN` is used for negative values,
440     /// and `i64::MAX` is used for positive values due to saturation.
441     #[inline]
442     pub const fn from_micros(micros: i64) -> Self {
443         Self {
444             value: micros.saturating_mul(NSEC_PER_USEC),
445         }
446     }
447 
448     /// Create a new [`Delta`] from a number of milliseconds.
449     ///
450     /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854.
451     /// If `millis` is outside this range, `i64::MIN` is used for negative values,
452     /// and `i64::MAX` is used for positive values due to saturation.
453     #[inline]
454     pub const fn from_millis(millis: i64) -> Self {
455         Self {
456             value: millis.saturating_mul(NSEC_PER_MSEC),
457         }
458     }
459 
460     /// Create a new [`Delta`] from a number of seconds.
461     ///
462     /// The `secs` can range from -9_223_372_036 to 9_223_372_036.
463     /// If `secs` is outside this range, `i64::MIN` is used for negative values,
464     /// and `i64::MAX` is used for positive values due to saturation.
465     #[inline]
466     pub const fn from_secs(secs: i64) -> Self {
467         Self {
468             value: secs.saturating_mul(NSEC_PER_SEC),
469         }
470     }
471 
472     /// Return `true` if the [`Delta`] spans no time.
473     #[inline]
474     pub fn is_zero(self) -> bool {
475         self.as_nanos() == 0
476     }
477 
478     /// Return `true` if the [`Delta`] spans a negative amount of time.
479     #[inline]
480     pub fn is_negative(self) -> bool {
481         self.as_nanos() < 0
482     }
483 
484     /// Return the number of nanoseconds in the [`Delta`].
485     #[inline]
486     pub const fn as_nanos(self) -> i64 {
487         self.value
488     }
489 
490     /// Return the smallest number of microseconds greater than or equal
491     /// to the value in the [`Delta`].
492     #[inline]
493     pub fn as_micros_ceil(self) -> i64 {
494         // Only positive values need to be rounded up: truncating division already
495         // rounds towards zero, i.e. up, for negative values.
496         //
497         // The usual `(nanos + d - 1) / d` is not used because the addition overflows
498         // once `nanos` exceeds `i64::MAX - (d - 1)`; saturating the addition instead
499         // would drop the rounding bias and return a result one unit too small.
500         let n = self.as_nanos();
501 
502         let (n, add) = if n > 0 { (n - 1, 1) } else { (n, 0) };
503 
504         #[cfg(CONFIG_64BIT)]
505         {
506             n / NSEC_PER_USEC + add
507         }
508 
509         #[cfg(not(CONFIG_64BIT))]
510         // SAFETY: It is always safe to call `ktime_to_us()` with any value.
511         unsafe {
512             bindings::ktime_to_us(n) + add
513         }
514     }
515 
516     /// Return the number of milliseconds in the [`Delta`].
517     #[inline]
518     pub fn as_millis(self) -> i64 {
519         #[cfg(CONFIG_64BIT)]
520         {
521             self.as_nanos() / NSEC_PER_MSEC
522         }
523 
524         #[cfg(not(CONFIG_64BIT))]
525         // SAFETY: It is always safe to call `ktime_to_ms()` with any value.
526         unsafe {
527             bindings::ktime_to_ms(self.as_nanos())
528         }
529     }
530 
531     /// Return the smallest number of milliseconds greater than or equal
532     /// to the value in the [`Delta`].
533     #[inline]
534     pub fn as_millis_ceil(self) -> i64 {
535         // Only positive values need to be rounded up: truncating division already
536         // rounds towards zero, i.e. up, for negative values.
537         //
538         // The usual `(nanos + d - 1) / d` is not used because the addition overflows
539         // once `nanos` exceeds `i64::MAX - (d - 1)`; saturating the addition instead
540         // would drop the rounding bias and return a result one unit too small.
541         let n = self.as_nanos();
542 
543         let (n, add) = if n > 0 { (n - 1, 1) } else { (n, 0) };
544 
545         #[cfg(CONFIG_64BIT)]
546         {
547             n / NSEC_PER_MSEC + add
548         }
549 
550         #[cfg(not(CONFIG_64BIT))]
551         // SAFETY: It is always safe to call `ktime_to_ms()` with any value.
552         unsafe {
553             bindings::ktime_to_ms(n) + add
554         }
555     }
556 
557     /// Return `self % dividend` where `dividend` is in nanoseconds.
558     ///
559     /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is
560     /// limited to 32 bit dividends.
561     #[inline]
562     pub fn rem_nanos(self, dividend: i32) -> Self {
563         #[cfg(CONFIG_64BIT)]
564         {
565             Self {
566                 value: self.as_nanos() % i64::from(dividend),
567             }
568         }
569 
570         #[cfg(not(CONFIG_64BIT))]
571         {
572             let mut rem = 0;
573 
574             // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it.
575             unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) };
576 
577             Self {
578                 value: i64::from(rem),
579             }
580         }
581     }
582 }
583