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).
63pub 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.
86pub struct Monotonic;
87
88impl 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.
111pub struct RealTime;
112
113impl 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.
129pub struct BootTime;
130
131impl 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.
151pub struct Tai;
152
153impl 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)]
169pub struct Instant<C: ClockSource> {
170    inner: bindings::ktime_t,
171    _c: PhantomData<C>,
172}
173
174impl<C: ClockSource> Clone for Instant<C> {
175    fn clone(&self) -> Self {
176        *self
177    }
178}
179
180impl<C: ClockSource> Copy for Instant<C> {}
181
182impl<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
228impl<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
240impl<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
260impl<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)]
286pub struct Delta {
287    nanos: i64,
288}
289
290impl 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
301impl ops::AddAssign for Delta {
302    #[inline]
303    fn add_assign(&mut self, rhs: Self) {
304        self.nanos += rhs.nanos;
305    }
306}
307
308impl 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
319impl ops::SubAssign for Delta {
320    #[inline]
321    fn sub_assign(&mut self, rhs: Self) {
322        self.nanos -= rhs.nanos;
323    }
324}
325
326impl 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
337impl ops::MulAssign<i64> for Delta {
338    #[inline]
339    fn mul_assign(&mut self, rhs: i64) {
340        self.nanos *= rhs;
341    }
342}
343
344impl 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
362impl 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}