Skip to main content

kernel/
time.rs

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
27use core::marker::PhantomData;
28use core::ops;
29
30pub mod delay;
31pub mod hrtimer;
32
33/// The number of nanoseconds per microsecond.
34pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64;
35
36/// The number of nanoseconds per millisecond.
37pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64;
38
39/// The number of nanoseconds per second.
40pub 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.
43pub type Jiffies = crate::ffi::c_ulong;
44
45/// The millisecond time unit.
46pub type Msecs = crate::ffi::c_uint;
47
48/// Converts milliseconds to jiffies.
49#[inline]
50pub 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`).
69pub 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.
92pub struct Monotonic;
93
94// SAFETY: The kernel's `ktime_get()` is guaranteed to return a value
95// in `0..=KTIME_MAX`.
96unsafe 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.
119pub struct RealTime;
120
121// SAFETY: The kernel's `ktime_get_real()` is guaranteed to return a value
122// in `0..=KTIME_MAX`.
123unsafe 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.
139pub struct BootTime;
140
141// SAFETY: The kernel's `ktime_get_boottime()` is guaranteed to return a value
142// in `0..=KTIME_MAX`.
143unsafe 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.
163pub struct Tai;
164
165// SAFETY: The kernel's `ktime_get_clocktai()` is guaranteed to return a value
166// in `0..=KTIME_MAX`.
167unsafe 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)]
183pub struct Instant<C: ClockSource> {
184    inner: bindings::ktime_t,
185    _c: PhantomData<C>,
186}
187
188impl<C: ClockSource> Clone for Instant<C> {
189    fn clone(&self) -> Self {
190        *self
191    }
192}
193
194impl<C: ClockSource> Copy for Instant<C> {}
195
196impl<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
242impl<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
254impl<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
274impl<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
294mod 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.
302pub 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)]
312pub enum Nsec {}
313
314impl 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)]
323pub enum Jiffy {}
324
325impl 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)]
336pub struct Delta<U: TimeUnit = Nsec> {
337    value: U::Repr,
338}
339
340impl 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
354impl 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
365impl ops::AddAssign for Delta {
366    #[inline]
367    fn add_assign(&mut self, rhs: Self) {
368        self.value += rhs.value;
369    }
370}
371
372impl 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
383impl ops::SubAssign for Delta {
384    #[inline]
385    fn sub_assign(&mut self, rhs: Self) {
386        self.value -= rhs.value;
387    }
388}
389
390impl 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
401impl ops::MulAssign<i64> for Delta {
402    #[inline]
403    fn mul_assign(&mut self, rhs: i64) {
404        self.value *= rhs;
405    }
406}
407
408impl 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
426impl 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}