[PATCH v8 2/7] rust: time: Introduce Delta type
From: FUJITA Tomonori <fujita.tomonori@gmail.com>
Date: 2025-01-16 04:42:41
Also in:
lkml, rust-for-linux
Subsystem:
delay, sleep, timekeeping, timers [rust], rust, the rest · Maintainers:
Andreas Hindborg, Miguel Ojeda, Linus Torvalds
Introduce a type representing a span of time. Define our own type because `core::time::Duration` is large and could panic during creation. time::Ktime could be also used for time duration but timestamp and timedelta are different so better to use a new type. i64 is used instead of u64 to represent a span of time; some C drivers uses negative Deltas and i64 is more compatible with Ktime using i64 too (e.g., ktime_[us|ms]_delta() APIs return i64 so we create Delta object without type conversion. i64 is used instead of bindings::ktime_t because when the ktime_t type is used as timestamp, it represents values from 0 to KTIME_MAX, which different from Delta. Delta::from_[millis|secs] APIs take i64. When a span of time overflows, i64::MAX is used. Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> --- rust/kernel/time.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index 48b71e6641ce..55a365af85a3 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs@@ -8,9 +8,15 @@ //! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h). //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h). +/// The number of nanoseconds per microsecond. +pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64; + /// The number of nanoseconds per millisecond. pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64; +/// The number of nanoseconds per second. +pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64; + /// The time unit of Linux kernel. One jiffy equals (1/HZ) second. pub type Jiffies = crate::ffi::c_ulong;
@@ -81,3 +87,60 @@ fn sub(self, other: Ktime) -> Ktime { } } } + +/// A span of time. +#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] +pub struct Delta { + nanos: i64, +} + +impl Delta { + /// Create a new `Delta` from a number of microseconds. + #[inline] + pub const fn from_micros(micros: i64) -> Self { + Self { + nanos: micros.saturating_mul(NSEC_PER_USEC), + } + } + + /// Create a new `Delta` from a number of milliseconds. + #[inline] + pub const fn from_millis(millis: i64) -> Self { + Self { + nanos: millis.saturating_mul(NSEC_PER_MSEC), + } + } + + /// Create a new `Delta` from a number of seconds. + #[inline] + pub const fn from_secs(secs: i64) -> Self { + Self { + nanos: secs.saturating_mul(NSEC_PER_SEC), + } + } + + /// Return `true` if the `Detla` spans no time. + #[inline] + pub fn is_zero(self) -> bool { + self.as_nanos() == 0 + } + + /// Return `true` if the `Detla` spans a negative amount of time. + #[inline] + pub fn is_negative(self) -> bool { + self.as_nanos() < 0 + } + + /// Return the number of nanoseconds in the `Delta`. + #[inline] + pub fn as_nanos(self) -> i64 { + self.nanos + } + + /// Return the smallest number of microseconds greater than or equal + /// to the value in the `Delta`. + #[inline] + pub fn as_micros_ceil(self) -> i64 { + self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC + } +}
--
2.43.0