Commit 768dfbfc authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by Andreas Hindborg
Browse files

rust: time: Make Instant generic over ClockSource



Refactor the Instant type to be generic over a ClockSource type
parameter, enabling static enforcement of clock correctness across
APIs that deal with time. Previously, the clock source was implicitly
fixed (typically CLOCK_MONOTONIC), and developers had to ensure
compatibility manually.

This design eliminates runtime mismatches between clock sources, and
enables stronger type-level guarantees throughout the timer subsystem.

Reviewed-by: default avatarAndreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: default avatarBoqun Feng <boqun.feng@gmail.com>
Signed-off-by: default avatarFUJITA Tomonori <fujita.tomonori@gmail.com>
Link: https://lore.kernel.org/r/20250610093258.3435874-3-fujita.tomonori@gmail.com


Signed-off-by: default avatarAndreas Hindborg <a.hindborg@kernel.org>
parent 1664a671
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
//! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h).
//! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h).

use core::marker::PhantomData;

pub mod hrtimer;

/// The number of nanoseconds per microsecond.
@@ -136,12 +138,21 @@ impl ClockSource for Tai {
///
/// The `inner` value is in the range from 0 to `KTIME_MAX`.
#[repr(transparent)]
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct Instant {
#[derive(PartialEq, PartialOrd, Eq, Ord)]
pub struct Instant<C: ClockSource> {
    inner: bindings::ktime_t,
    _c: PhantomData<C>,
}

impl<C: ClockSource> Clone for Instant<C> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<C: ClockSource> Copy for Instant<C> {}

impl Instant {
impl<C: ClockSource> Instant<C> {
    /// Get the current time using `CLOCK_MONOTONIC`.
    #[inline]
    pub fn now() -> Self {
@@ -150,6 +161,7 @@ pub fn now() -> Self {
        Self {
            // SAFETY: It is always safe to call `ktime_get()` outside of NMI context.
            inner: unsafe { bindings::ktime_get() },
            _c: PhantomData,
        }
    }

@@ -160,12 +172,12 @@ pub fn elapsed(&self) -> Delta {
    }
}

impl core::ops::Sub for Instant {
impl<C: ClockSource> core::ops::Sub for Instant<C> {
    type Output = Delta;

    // By the type invariant, it never overflows.
    #[inline]
    fn sub(self, other: Instant) -> Delta {
    fn sub(self, other: Instant<C>) -> Delta {
        Delta {
            nanos: self.inner - other.inner,
        }