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]
msecs_to_jiffies(msecs: Msecs) -> Jiffies50 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`.
ktime_get() -> bindings::ktime_t78 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
ktime_get() -> bindings::ktime_t99 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
ktime_get() -> bindings::ktime_t126 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
ktime_get() -> bindings::ktime_t146 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
ktime_get() -> bindings::ktime_t170 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> {
clone(&self) -> Self189 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]
now() -> Self199 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]
elapsed(&self) -> Delta210 pub fn elapsed(&self) -> Delta {
211 Self::now() - *self
212 }
213
214 #[inline]
as_nanos(&self) -> i64215 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]
from_ktime(ktime: bindings::ktime_t) -> Self230 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]
sub(self, other: Instant<C>) -> Delta247 fn sub(self, other: Instant<C>) -> Delta {
248 Delta {
249 nanos: 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]
add(self, rhs: Delta) -> Self::Output258 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.nanos;
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]
sub(self, rhs: Delta) -> Self::Output278 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.nanos;
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 /// A span of time.
295 ///
296 /// This struct represents a span of time, with its value stored as nanoseconds.
297 /// The value can represent any valid i64 value, including negative, zero, and
298 /// positive numbers.
299 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
300 pub struct Delta {
301 nanos: i64,
302 }
303
304 impl ops::Add for Delta {
305 type Output = Self;
306
307 #[inline]
add(self, rhs: Self) -> Self308 fn add(self, rhs: Self) -> Self {
309 Self {
310 nanos: self.nanos + rhs.nanos,
311 }
312 }
313 }
314
315 impl ops::AddAssign for Delta {
316 #[inline]
add_assign(&mut self, rhs: Self)317 fn add_assign(&mut self, rhs: Self) {
318 self.nanos += rhs.nanos;
319 }
320 }
321
322 impl ops::Sub for Delta {
323 type Output = Self;
324
325 #[inline]
sub(self, rhs: Self) -> Self::Output326 fn sub(self, rhs: Self) -> Self::Output {
327 Self {
328 nanos: self.nanos - rhs.nanos,
329 }
330 }
331 }
332
333 impl ops::SubAssign for Delta {
334 #[inline]
sub_assign(&mut self, rhs: Self)335 fn sub_assign(&mut self, rhs: Self) {
336 self.nanos -= rhs.nanos;
337 }
338 }
339
340 impl ops::Mul<i64> for Delta {
341 type Output = Self;
342
343 #[inline]
mul(self, rhs: i64) -> Self::Output344 fn mul(self, rhs: i64) -> Self::Output {
345 Self {
346 nanos: self.nanos * rhs,
347 }
348 }
349 }
350
351 impl ops::MulAssign<i64> for Delta {
352 #[inline]
mul_assign(&mut self, rhs: i64)353 fn mul_assign(&mut self, rhs: i64) {
354 self.nanos *= rhs;
355 }
356 }
357
358 impl ops::Div for Delta {
359 type Output = i64;
360
361 #[inline]
div(self, rhs: Self) -> Self::Output362 fn div(self, rhs: Self) -> Self::Output {
363 #[cfg(CONFIG_64BIT)]
364 {
365 self.nanos / rhs.nanos
366 }
367
368 #[cfg(not(CONFIG_64BIT))]
369 {
370 // SAFETY: This function is always safe to call regardless of the input values
371 unsafe { bindings::div64_s64(self.nanos, rhs.nanos) }
372 }
373 }
374 }
375
376 impl Delta {
377 /// A span of time equal to zero.
378 pub const ZERO: Self = Self { nanos: 0 };
379
380 /// Create a new [`Delta`] from a number of nanoseconds.
381 #[inline]
from_nanos(nanos: i64) -> Self382 pub const fn from_nanos(nanos: i64) -> Self {
383 Self { nanos }
384 }
385
386 /// Create a new [`Delta`] from a number of microseconds.
387 ///
388 /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775.
389 /// If `micros` is outside this range, `i64::MIN` is used for negative values,
390 /// and `i64::MAX` is used for positive values due to saturation.
391 #[inline]
from_micros(micros: i64) -> Self392 pub const fn from_micros(micros: i64) -> Self {
393 Self {
394 nanos: micros.saturating_mul(NSEC_PER_USEC),
395 }
396 }
397
398 /// Create a new [`Delta`] from a number of milliseconds.
399 ///
400 /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854.
401 /// If `millis` is outside this range, `i64::MIN` is used for negative values,
402 /// and `i64::MAX` is used for positive values due to saturation.
403 #[inline]
from_millis(millis: i64) -> Self404 pub const fn from_millis(millis: i64) -> Self {
405 Self {
406 nanos: millis.saturating_mul(NSEC_PER_MSEC),
407 }
408 }
409
410 /// Create a new [`Delta`] from a number of seconds.
411 ///
412 /// The `secs` can range from -9_223_372_036 to 9_223_372_036.
413 /// If `secs` is outside this range, `i64::MIN` is used for negative values,
414 /// and `i64::MAX` is used for positive values due to saturation.
415 #[inline]
from_secs(secs: i64) -> Self416 pub const fn from_secs(secs: i64) -> Self {
417 Self {
418 nanos: secs.saturating_mul(NSEC_PER_SEC),
419 }
420 }
421
422 /// Return `true` if the [`Delta`] spans no time.
423 #[inline]
is_zero(self) -> bool424 pub fn is_zero(self) -> bool {
425 self.as_nanos() == 0
426 }
427
428 /// Return `true` if the [`Delta`] spans a negative amount of time.
429 #[inline]
is_negative(self) -> bool430 pub fn is_negative(self) -> bool {
431 self.as_nanos() < 0
432 }
433
434 /// Return the number of nanoseconds in the [`Delta`].
435 #[inline]
as_nanos(self) -> i64436 pub const fn as_nanos(self) -> i64 {
437 self.nanos
438 }
439
440 /// Return the smallest number of microseconds greater than or equal
441 /// to the value in the [`Delta`].
442 #[inline]
as_micros_ceil(self) -> i64443 pub fn as_micros_ceil(self) -> i64 {
444 #[cfg(CONFIG_64BIT)]
445 {
446 self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC
447 }
448
449 #[cfg(not(CONFIG_64BIT))]
450 // SAFETY: It is always safe to call `ktime_to_us()` with any value.
451 unsafe {
452 bindings::ktime_to_us(self.as_nanos().saturating_add(NSEC_PER_USEC - 1))
453 }
454 }
455
456 /// Return the number of milliseconds in the [`Delta`].
457 #[inline]
as_millis(self) -> i64458 pub fn as_millis(self) -> i64 {
459 #[cfg(CONFIG_64BIT)]
460 {
461 self.as_nanos() / NSEC_PER_MSEC
462 }
463
464 #[cfg(not(CONFIG_64BIT))]
465 // SAFETY: It is always safe to call `ktime_to_ms()` with any value.
466 unsafe {
467 bindings::ktime_to_ms(self.as_nanos())
468 }
469 }
470
471 /// Return `self % dividend` where `dividend` is in nanoseconds.
472 ///
473 /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is
474 /// limited to 32 bit dividends.
475 #[inline]
rem_nanos(self, dividend: i32) -> Self476 pub fn rem_nanos(self, dividend: i32) -> Self {
477 #[cfg(CONFIG_64BIT)]
478 {
479 Self {
480 nanos: self.as_nanos() % i64::from(dividend),
481 }
482 }
483
484 #[cfg(not(CONFIG_64BIT))]
485 {
486 let mut rem = 0;
487
488 // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it.
489 unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) };
490
491 Self {
492 nanos: i64::from(rem),
493 }
494 }
495 }
496 }
497