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}