Commit 3efb9ce9 authored by Lyude Paul's avatar Lyude Paul Committed by Andreas Hindborg
Browse files

rust: hrtimer: Add HrTimer::raw_forward() and forward()



Within the hrtimer API there are quite a number of functions that can only
be safely called from one of two contexts:

* When we have exclusive access to the hrtimer and the timer is not active.
* When we're within the hrtimer's callback context as it is being executed.

This commit adds bindings for hrtimer_forward() for the first such context,
along with HrTimer::raw_forward() for later use in implementing the
hrtimer_forward() in the latter context.

Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
Reviewed-by: default avatarDaniel Almeida <daniel.almeida@collabora.com>
Reviewed-by: default avatarAndreas Hindborg <a.hindborg@kernel.org>
Link: https://lore.kernel.org/r/20250821193259.964504-4-lyude@redhat.com


Signed-off-by: default avatarAndreas Hindborg <a.hindborg@kernel.org>
parent 0e2aab67
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -168,6 +168,46 @@ pub(crate) unsafe fn raw_cancel(this: *const Self) -> bool {
        // handled on the C side.
        unsafe { bindings::hrtimer_cancel(c_timer_ptr) != 0 }
    }

    /// Forward the timer expiry for a given timer pointer.
    ///
    /// # Safety
    ///
    /// - `self_ptr` must point to a valid `Self`.
    /// - The caller must either have exclusive access to the data pointed at by `self_ptr`, or be
    ///   within the context of the timer callback.
    #[inline]
    unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimerInstant<T>, interval: Delta) -> u64
    where
        T: HasHrTimer<T>,
    {
        // SAFETY:
        // * The C API requirements for this function are fulfilled by our safety contract.
        // * `self_ptr` is guaranteed to point to a valid `Self` via our safety contract
        unsafe {
            bindings::hrtimer_forward(Self::raw_get(self_ptr), now.as_nanos(), interval.as_nanos())
        }
    }

    /// Conditionally forward the timer.
    ///
    /// If the timer expires after `now`, this function does nothing and returns 0. If the timer
    /// expired at or before `now`, this function forwards the timer by `interval` until the timer
    /// expires after `now` and then returns the number of times the timer was forwarded by
    /// `interval`.
    ///
    /// Returns the number of overruns that occurred as a result of the timer expiry change.
    pub fn forward(self: Pin<&mut Self>, now: HrTimerInstant<T>, interval: Delta) -> u64
    where
        T: HasHrTimer<T>,
    {
        // SAFETY: `raw_forward` does not move `Self`
        let this = unsafe { self.get_unchecked_mut() };

        // SAFETY: By existence of `Pin<&mut Self>`, the pointer passed to `raw_forward` points to a
        // valid `Self` that we have exclusive access to.
        unsafe { Self::raw_forward(this, now, interval) }
    }
}

/// Implemented by pointer types that point to structs that contain a [`HrTimer`].