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: Lyude Paul <lyude@redhat.com>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Link: https://lore.kernel.org/r/20250821193259.964504-4-lyude@redhat.com
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
This commit is contained in:
Lyude Paul 2025-08-21 15:32:43 -04:00 committed by Andreas Hindborg
parent 0e2aab67f2
commit 3efb9ce91c

View File

@ -168,6 +168,46 @@ impl<T> HrTimer<T> {
// 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`].