From: FUJITA Tomonori <tomo@flapping.org>
To: a.hindborg@kernel.org, aliceryhl@google.com, arve@android.com,
boqun@kernel.org, brauner@kernel.org, cmllamas@google.com,
gary@garyguo.net, gregkh@linuxfoundation.org, ojeda@kernel.org,
tkjos@android.com
Cc: acourbot@nvidia.com, anna-maria@linutronix.de,
bjorn3_gh@protonmail.com, dakr@kernel.org,
daniel.almeida@collabora.com, frederic@kernel.org,
jstultz@google.com, lossin@kernel.org, lyude@redhat.com,
sboyd@kernel.org, tamird@kernel.org, tglx@kernel.org,
tmgross@umich.edu, work@onurozkan.dev,
rust-for-linux@vger.kernel.org,
FUJITA Tomonori <fujita.tomonori@gmail.com>
Subject: [PATCH v5 1/7] rust: time: make Delta generic over its time unit
Date: Thu, 6 Aug 2026 16:32:35 +0900 [thread overview]
Message-ID: <20260806073241.1024319-2-tomo@flapping.org> (raw)
In-Reply-To: <20260806073241.1024319-1-tomo@flapping.org>
From: FUJITA Tomonori <fujita.tomonori@gmail.com>
Delta hardcodes its value as i64 nanoseconds. A later patch adds a
jiffies span, whose natural representation is isize jiffies rather than
i64 nanoseconds, and a separate type per unit would duplicate the
arithmetic and comparison machinery.
Make Delta generic over its time unit so the jiffies span can reuse that
machinery. The nanosecond Delta keeps its current representation and API
via the default unit parameter, so no functional change.
users.
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
rust/kernel/time.rs | 72 ++++++++++++++++++++++++++++++---------------
1 file changed, 48 insertions(+), 24 deletions(-)
diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index b8463823aed9..589bd7827523 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -246,7 +246,7 @@ impl<C: ClockSource> ops::Sub for Instant<C> {
#[inline]
fn sub(self, other: Instant<C>) -> Delta {
Delta {
- nanos: self.inner - other.inner,
+ value: self.inner - other.inner,
}
}
}
@@ -258,7 +258,7 @@ impl<T: ClockSource> ops::Add<Delta> for Instant<T> {
fn add(self, rhs: Delta) -> Self::Output {
// INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
// (e.g. go above `KTIME_MAX`)
- let res = self.inner + rhs.nanos;
+ let res = self.inner + rhs.value;
// INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
#[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
@@ -278,7 +278,7 @@ impl<T: ClockSource> ops::Sub<Delta> for Instant<T> {
fn sub(self, rhs: Delta) -> Self::Output {
// INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
// (e.g. go above `KTIME_MAX`)
- let res = self.inner - rhs.nanos;
+ let res = self.inner - rhs.value;
// INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
#[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
@@ -291,14 +291,38 @@ fn sub(self, rhs: Delta) -> Self::Output {
}
}
+mod private {
+ pub trait Sealed {}
+
+ impl Sealed for super::Nsec {}
+}
+
+/// A trait for time units.
+pub trait TimeUnit: private::Sealed {
+ /// The underlying representation of the time unit.
+ type Repr: Copy + Clone + PartialEq + PartialOrd + Eq + Ord + core::fmt::Debug;
+}
+
+/// A time unit of nanoseconds.
+///
+/// A [`Delta<Nsec>`] stores its value as `i64` nanoseconds and can represent
+/// any `i64` value, including negative, zero, and positive numbers.
+#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
+pub struct Nsec;
+
+impl TimeUnit for Nsec {
+ type Repr = i64;
+}
+
/// A span of time.
///
-/// This struct represents a span of time, with its value stored as nanoseconds.
-/// The value can represent any valid i64 value, including negative, zero, and
-/// positive numbers.
+/// The span is stored in the unit given by the type parameter `U` (see
+/// [`TimeUnit`]); its value has type `U::Repr`. `U` defaults to [`Nsec`], so a
+/// plain [`Delta`] is a span in nanoseconds. The value can be negative, zero, or
+/// positive.
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
-pub struct Delta {
- nanos: i64,
+pub struct Delta<U: TimeUnit = Nsec> {
+ value: U::Repr,
}
impl ops::Add for Delta {
@@ -307,7 +331,7 @@ impl ops::Add for Delta {
#[inline]
fn add(self, rhs: Self) -> Self {
Self {
- nanos: self.nanos + rhs.nanos,
+ value: self.value + rhs.value,
}
}
}
@@ -315,7 +339,7 @@ fn add(self, rhs: Self) -> Self {
impl ops::AddAssign for Delta {
#[inline]
fn add_assign(&mut self, rhs: Self) {
- self.nanos += rhs.nanos;
+ self.value += rhs.value;
}
}
@@ -325,7 +349,7 @@ impl ops::Sub for Delta {
#[inline]
fn sub(self, rhs: Self) -> Self::Output {
Self {
- nanos: self.nanos - rhs.nanos,
+ value: self.value - rhs.value,
}
}
}
@@ -333,7 +357,7 @@ fn sub(self, rhs: Self) -> Self::Output {
impl ops::SubAssign for Delta {
#[inline]
fn sub_assign(&mut self, rhs: Self) {
- self.nanos -= rhs.nanos;
+ self.value -= rhs.value;
}
}
@@ -343,7 +367,7 @@ impl ops::Mul<i64> for Delta {
#[inline]
fn mul(self, rhs: i64) -> Self::Output {
Self {
- nanos: self.nanos * rhs,
+ value: self.value * rhs,
}
}
}
@@ -351,7 +375,7 @@ fn mul(self, rhs: i64) -> Self::Output {
impl ops::MulAssign<i64> for Delta {
#[inline]
fn mul_assign(&mut self, rhs: i64) {
- self.nanos *= rhs;
+ self.value *= rhs;
}
}
@@ -362,25 +386,25 @@ impl ops::Div for Delta {
fn div(self, rhs: Self) -> Self::Output {
#[cfg(CONFIG_64BIT)]
{
- self.nanos / rhs.nanos
+ self.value / rhs.value
}
#[cfg(not(CONFIG_64BIT))]
{
// SAFETY: This function is always safe to call regardless of the input values
- unsafe { bindings::div64_s64(self.nanos, rhs.nanos) }
+ unsafe { bindings::div64_s64(self.value, rhs.value) }
}
}
}
impl Delta {
/// A span of time equal to zero.
- pub const ZERO: Self = Self { nanos: 0 };
+ pub const ZERO: Self = Self { value: 0 };
/// Create a new [`Delta`] from a number of nanoseconds.
#[inline]
pub const fn from_nanos(nanos: i64) -> Self {
- Self { nanos }
+ Self { value: nanos }
}
/// Create a new [`Delta`] from a number of microseconds.
@@ -391,7 +415,7 @@ pub const fn from_nanos(nanos: i64) -> Self {
#[inline]
pub const fn from_micros(micros: i64) -> Self {
Self {
- nanos: micros.saturating_mul(NSEC_PER_USEC),
+ value: micros.saturating_mul(NSEC_PER_USEC),
}
}
@@ -403,7 +427,7 @@ pub const fn from_micros(micros: i64) -> Self {
#[inline]
pub const fn from_millis(millis: i64) -> Self {
Self {
- nanos: millis.saturating_mul(NSEC_PER_MSEC),
+ value: millis.saturating_mul(NSEC_PER_MSEC),
}
}
@@ -415,7 +439,7 @@ pub const fn from_millis(millis: i64) -> Self {
#[inline]
pub const fn from_secs(secs: i64) -> Self {
Self {
- nanos: secs.saturating_mul(NSEC_PER_SEC),
+ value: secs.saturating_mul(NSEC_PER_SEC),
}
}
@@ -434,7 +458,7 @@ pub fn is_negative(self) -> bool {
/// Return the number of nanoseconds in the [`Delta`].
#[inline]
pub const fn as_nanos(self) -> i64 {
- self.nanos
+ self.value
}
/// Return the smallest number of microseconds greater than or equal
@@ -484,7 +508,7 @@ pub fn rem_nanos(self, dividend: i32) -> Self {
#[cfg(CONFIG_64BIT)]
{
Self {
- nanos: self.as_nanos() % i64::from(dividend),
+ value: self.as_nanos() % i64::from(dividend),
}
}
@@ -496,7 +520,7 @@ pub fn rem_nanos(self, dividend: i32) -> Self {
unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) };
Self {
- nanos: i64::from(rem),
+ value: i64::from(rem),
}
}
}
--
2.43.0
next prev parent reply other threads:[~2026-08-06 7:33 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 7:32 [PATCH v5 0/7] rust: use Delta instead of raw jiffies for timeouts and delays FUJITA Tomonori
2026-08-06 7:32 ` FUJITA Tomonori [this message]
2026-08-06 9:44 ` [PATCH v5 1/7] rust: time: make Delta generic over its time unit Andreas Hindborg
2026-08-07 12:10 ` FUJITA Tomonori
2026-08-06 7:32 ` [PATCH v5 2/7] rust: time: add jiffies time unit for Delta FUJITA Tomonori
2026-08-06 7:32 ` [PATCH v5 3/7] rust: time: add Delta::as_millis_ceil() FUJITA Tomonori
2026-08-06 9:47 ` Andreas Hindborg
2026-08-07 13:26 ` FUJITA Tomonori
2026-08-06 7:32 ` [PATCH v5 4/7] rust: time: add Delta::to_jiffies() for timeout conversion FUJITA Tomonori
2026-08-06 9:50 ` Andreas Hindborg
2026-08-07 12:15 ` FUJITA Tomonori
2026-08-06 11:50 ` Gary Guo
2026-08-07 12:38 ` FUJITA Tomonori
2026-08-07 12:59 ` Gary Guo
2026-08-07 13:13 ` FUJITA Tomonori
2026-08-06 7:32 ` [PATCH v5 5/7] rust: workqueue: take a Delta<Jiffy> for the enqueue delay FUJITA Tomonori
2026-08-06 7:32 ` [PATCH v5 6/7] rust: sync: condvar: use Delta<Jiffy> for timeout and result FUJITA Tomonori
2026-08-06 7:32 ` [PATCH v5 7/7] rust: time: remove unused Jiffies/Msecs helpers FUJITA Tomonori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260806073241.1024319-2-tomo@flapping.org \
--to=tomo@flapping.org \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=anna-maria@linutronix.de \
--cc=arve@android.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=brauner@kernel.org \
--cc=cmllamas@google.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=frederic@kernel.org \
--cc=fujita.tomonori@gmail.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=jstultz@google.com \
--cc=lossin@kernel.org \
--cc=lyude@redhat.com \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=sboyd@kernel.org \
--cc=tamird@kernel.org \
--cc=tglx@kernel.org \
--cc=tkjos@android.com \
--cc=tmgross@umich.edu \
--cc=work@onurozkan.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox