Skip to content

Commit ddc6715

Browse files
fujitaAndreas Hindborg
authored andcommitted
rust: time: Introduce Instant type
Introduce a type representing a specific point in time. We could use the Ktime type but C's ktime_t is used for both timestamp and timedelta. To avoid confusion, introduce a new Instant type for timestamp. Rename Ktime to Instant and modify their methods for timestamp. Implement the subtraction operator for Instant: Delta = Instant A - Instant B Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Fiona Behrens <me@kloenk.dev> Tested-by: Daniel Almeida <daniel.almeida@collabora.com> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Link: https://lore.kernel.org/r/20250423192857.199712-5-fujita.tomonori@gmail.com Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
1 parent fae0cdc commit ddc6715

File tree

1 file changed

+39
-38
lines changed

1 file changed

+39
-38
lines changed

rust/kernel/time.rs

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@
55
//! This module contains the kernel APIs related to time and timers that
66
//! have been ported or wrapped for usage by Rust code in the kernel.
77
//!
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+
//!
824
//! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h).
925
//! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h).
1026
@@ -33,59 +49,44 @@ pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
3349
unsafe { bindings::__msecs_to_jiffies(msecs) }
3450
}
3551

36-
/// A Rust wrapper around a `ktime_t`.
52+
/// A specific point in time.
53+
///
54+
/// # Invariants
55+
///
56+
/// The `inner` value is in the range from 0 to `KTIME_MAX`.
3757
#[repr(transparent)]
3858
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)]
39-
pub struct Ktime {
59+
pub struct Instant {
4060
inner: bindings::ktime_t,
4161
}
4262

43-
impl Ktime {
44-
/// Create a `Ktime` from a raw `ktime_t`.
45-
#[inline]
46-
pub fn from_raw(inner: bindings::ktime_t) -> Self {
47-
Self { inner }
48-
}
49-
63+
impl Instant {
5064
/// Get the current time using `CLOCK_MONOTONIC`.
5165
#[inline]
52-
pub fn ktime_get() -> Self {
53-
// SAFETY: It is always safe to call `ktime_get` outside of NMI context.
54-
Self::from_raw(unsafe { bindings::ktime_get() })
55-
}
56-
57-
/// Divide the number of nanoseconds by a compile-time constant.
58-
#[inline]
59-
fn divns_constant<const DIV: i64>(self) -> i64 {
60-
self.to_ns() / DIV
61-
}
62-
63-
/// Returns the number of nanoseconds.
64-
#[inline]
65-
pub fn to_ns(self) -> i64 {
66-
self.inner
66+
pub fn now() -> Self {
67+
// INVARIANT: The `ktime_get()` function returns a value in the range
68+
// from 0 to `KTIME_MAX`.
69+
Self {
70+
// SAFETY: It is always safe to call `ktime_get()` outside of NMI context.
71+
inner: unsafe { bindings::ktime_get() },
72+
}
6773
}
6874

69-
/// Returns the number of milliseconds.
75+
/// Return the amount of time elapsed since the [`Instant`].
7076
#[inline]
71-
pub fn to_ms(self) -> i64 {
72-
self.divns_constant::<NSEC_PER_MSEC>()
77+
pub fn elapsed(&self) -> Delta {
78+
Self::now() - *self
7379
}
7480
}
7581

76-
/// Returns the number of milliseconds between two ktimes.
77-
#[inline]
78-
pub fn ktime_ms_delta(later: Ktime, earlier: Ktime) -> i64 {
79-
(later - earlier).to_ms()
80-
}
81-
82-
impl core::ops::Sub for Ktime {
83-
type Output = Ktime;
82+
impl core::ops::Sub for Instant {
83+
type Output = Delta;
8484

85+
// By the type invariant, it never overflows.
8586
#[inline]
86-
fn sub(self, other: Ktime) -> Ktime {
87-
Self {
88-
inner: self.inner - other.inner,
87+
fn sub(self, other: Instant) -> Delta {
88+
Delta {
89+
nanos: self.inner - other.inner,
8990
}
9091
}
9192
}

0 commit comments

Comments
 (0)