kernel/time/
hrtimer.rs

1// SPDX-License-Identifier: GPL-2.0
2
3//! Intrusive high resolution timers.
4//!
5//! Allows running timer callbacks without doing allocations at the time of
6//! starting the timer. For now, only one timer per type is allowed.
7//!
8//! # Vocabulary
9//!
10//! States:
11//!
12//! - Stopped: initialized but not started, or cancelled, or not restarted.
13//! - Started: initialized and started or restarted.
14//! - Running: executing the callback.
15//!
16//! Operations:
17//!
18//! * Start
19//! * Cancel
20//! * Restart
21//!
22//! Events:
23//!
24//! * Expire
25//!
26//! ## State Diagram
27//!
28//! ```text
29//!                                                   Return NoRestart
30//!                       +---------------------------------------------------------------------+
31//!                       |                                                                     |
32//!                       |                                                                     |
33//!                       |                                                                     |
34//!                       |                                         Return Restart              |
35//!                       |                                      +------------------------+     |
36//!                       |                                      |                        |     |
37//!                       |                                      |                        |     |
38//!                       v                                      v                        |     |
39//!           +-----------------+      Start      +------------------+           +--------+-----+--+
40//!           |                 +---------------->|                  |           |                 |
41//! Init      |                 |                 |                  |  Expire   |                 |
42//! --------->|    Stopped      |                 |      Started     +---------->|     Running     |
43//!           |                 |     Cancel      |                  |           |                 |
44//!           |                 |<----------------+                  |           |                 |
45//!           +-----------------+                 +---------------+--+           +-----------------+
46//!                                                     ^         |
47//!                                                     |         |
48//!                                                     +---------+
49//!                                                      Restart
50//! ```
51//!
52//!
53//! A timer is initialized in the **stopped** state. A stopped timer can be
54//! **started** by the `start` operation, with an **expiry** time. After the
55//! `start` operation, the timer is in the **started** state. When the timer
56//! **expires**, the timer enters the **running** state and the handler is
57//! executed. After the handler has returned, the timer may enter the
58//! **started* or **stopped** state, depending on the return value of the
59//! handler. A timer in the **started** or **running** state may be **canceled**
60//! by the `cancel` operation. A timer that is cancelled enters the **stopped**
61//! state.
62//!
63//! A `cancel` or `restart` operation on a timer in the **running** state takes
64//! effect after the handler has returned and the timer has transitioned
65//! out of the **running** state.
66//!
67//! A `restart` operation on a timer in the **stopped** state is equivalent to a
68//! `start` operation.
69
70use super::{ClockSource, Delta, Instant};
71use crate::{prelude::*, types::Opaque};
72use core::marker::PhantomData;
73use pin_init::PinInit;
74
75/// A timer backed by a C `struct hrtimer`.
76///
77/// # Invariants
78///
79/// * `self.timer` is initialized by `bindings::hrtimer_setup`.
80#[pin_data]
81#[repr(C)]
82pub struct HrTimer<T> {
83    #[pin]
84    timer: Opaque<bindings::hrtimer>,
85    _t: PhantomData<T>,
86}
87
88// SAFETY: Ownership of an `HrTimer` can be moved to other threads and
89// used/dropped from there.
90unsafe impl<T> Send for HrTimer<T> {}
91
92// SAFETY: Timer operations are locked on the C side, so it is safe to operate
93// on a timer from multiple threads.
94unsafe impl<T> Sync for HrTimer<T> {}
95
96impl<T> HrTimer<T> {
97    /// Return an initializer for a new timer instance.
98    pub fn new() -> impl PinInit<Self>
99    where
100        T: HrTimerCallback,
101        T: HasHrTimer<T>,
102    {
103        pin_init!(Self {
104            // INVARIANT: We initialize `timer` with `hrtimer_setup` below.
105            timer <- Opaque::ffi_init(move |place: *mut bindings::hrtimer| {
106                // SAFETY: By design of `pin_init!`, `place` is a pointer to a
107                // live allocation. hrtimer_setup will initialize `place` and
108                // does not require `place` to be initialized prior to the call.
109                unsafe {
110                    bindings::hrtimer_setup(
111                        place,
112                        Some(T::Pointer::run),
113                        <<T as HasHrTimer<T>>::TimerMode as HrTimerMode>::Clock::ID,
114                        <T as HasHrTimer<T>>::TimerMode::C_MODE,
115                    );
116                }
117            }),
118            _t: PhantomData,
119        })
120    }
121
122    /// Get a pointer to the contained `bindings::hrtimer`.
123    ///
124    /// This function is useful to get access to the value without creating
125    /// intermediate references.
126    ///
127    /// # Safety
128    ///
129    /// `this` must point to a live allocation of at least the size of `Self`.
130    unsafe fn raw_get(this: *const Self) -> *mut bindings::hrtimer {
131        // SAFETY: The field projection to `timer` does not go out of bounds,
132        // because the caller of this function promises that `this` points to an
133        // allocation of at least the size of `Self`.
134        unsafe { Opaque::raw_get(core::ptr::addr_of!((*this).timer)) }
135    }
136
137    /// Cancel an initialized and potentially running timer.
138    ///
139    /// If the timer handler is running, this function will block until the
140    /// handler returns.
141    ///
142    /// Note that the timer might be started by a concurrent start operation. If
143    /// so, the timer might not be in the **stopped** state when this function
144    /// returns.
145    ///
146    /// Users of the `HrTimer` API would not usually call this method directly.
147    /// Instead they would use the safe [`HrTimerHandle::cancel`] on the handle
148    /// returned when the timer was started.
149    ///
150    /// This function is useful to get access to the value without creating
151    /// intermediate references.
152    ///
153    /// # Safety
154    ///
155    /// `this` must point to a valid `Self`.
156    pub(crate) unsafe fn raw_cancel(this: *const Self) -> bool {
157        // SAFETY: `this` points to an allocation of at least `HrTimer` size.
158        let c_timer_ptr = unsafe { HrTimer::raw_get(this) };
159
160        // If the handler is running, this will wait for the handler to return
161        // before returning.
162        // SAFETY: `c_timer_ptr` is initialized and valid. Synchronization is
163        // handled on the C side.
164        unsafe { bindings::hrtimer_cancel(c_timer_ptr) != 0 }
165    }
166}
167
168/// Implemented by pointer types that point to structs that contain a [`HrTimer`].
169///
170/// `Self` must be [`Sync`] because it is passed to timer callbacks in another
171/// thread of execution (hard or soft interrupt context).
172///
173/// Starting a timer returns a [`HrTimerHandle`] that can be used to manipulate
174/// the timer. Note that it is OK to call the start function repeatedly, and
175/// that more than one [`HrTimerHandle`] associated with a [`HrTimerPointer`] may
176/// exist. A timer can be manipulated through any of the handles, and a handle
177/// may represent a cancelled timer.
178pub trait HrTimerPointer: Sync + Sized {
179    /// The operational mode associated with this timer.
180    ///
181    /// This defines how the expiration value is interpreted.
182    type TimerMode: HrTimerMode;
183
184    /// A handle representing a started or restarted timer.
185    ///
186    /// If the timer is running or if the timer callback is executing when the
187    /// handle is dropped, the drop method of [`HrTimerHandle`] should not return
188    /// until the timer is stopped and the callback has completed.
189    ///
190    /// Note: When implementing this trait, consider that it is not unsafe to
191    /// leak the handle.
192    type TimerHandle: HrTimerHandle;
193
194    /// Start the timer with expiry after `expires` time units. If the timer was
195    /// already running, it is restarted with the new expiry time.
196    fn start(self, expires: <Self::TimerMode as HrTimerMode>::Expires) -> Self::TimerHandle;
197}
198
199/// Unsafe version of [`HrTimerPointer`] for situations where leaking the
200/// [`HrTimerHandle`] returned by `start` would be unsound. This is the case for
201/// stack allocated timers.
202///
203/// Typical implementers are pinned references such as [`Pin<&T>`].
204///
205/// # Safety
206///
207/// Implementers of this trait must ensure that instances of types implementing
208/// [`UnsafeHrTimerPointer`] outlives any associated [`HrTimerPointer::TimerHandle`]
209/// instances.
210pub unsafe trait UnsafeHrTimerPointer: Sync + Sized {
211    /// The operational mode associated with this timer.
212    ///
213    /// This defines how the expiration value is interpreted.
214    type TimerMode: HrTimerMode;
215
216    /// A handle representing a running timer.
217    ///
218    /// # Safety
219    ///
220    /// If the timer is running, or if the timer callback is executing when the
221    /// handle is dropped, the drop method of [`Self::TimerHandle`] must not return
222    /// until the timer is stopped and the callback has completed.
223    type TimerHandle: HrTimerHandle;
224
225    /// Start the timer after `expires` time units. If the timer was already
226    /// running, it is restarted at the new expiry time.
227    ///
228    /// # Safety
229    ///
230    /// Caller promises keep the timer structure alive until the timer is dead.
231    /// Caller can ensure this by not leaking the returned [`Self::TimerHandle`].
232    unsafe fn start(self, expires: <Self::TimerMode as HrTimerMode>::Expires) -> Self::TimerHandle;
233}
234
235/// A trait for stack allocated timers.
236///
237/// # Safety
238///
239/// Implementers must ensure that `start_scoped` does not return until the
240/// timer is dead and the timer handler is not running.
241pub unsafe trait ScopedHrTimerPointer {
242    /// The operational mode associated with this timer.
243    ///
244    /// This defines how the expiration value is interpreted.
245    type TimerMode: HrTimerMode;
246
247    /// Start the timer to run after `expires` time units and immediately
248    /// after call `f`. When `f` returns, the timer is cancelled.
249    fn start_scoped<T, F>(self, expires: <Self::TimerMode as HrTimerMode>::Expires, f: F) -> T
250    where
251        F: FnOnce() -> T;
252}
253
254// SAFETY: By the safety requirement of [`UnsafeHrTimerPointer`], dropping the
255// handle returned by [`UnsafeHrTimerPointer::start`] ensures that the timer is
256// killed.
257unsafe impl<T> ScopedHrTimerPointer for T
258where
259    T: UnsafeHrTimerPointer,
260{
261    type TimerMode = T::TimerMode;
262
263    fn start_scoped<U, F>(
264        self,
265        expires: <<T as UnsafeHrTimerPointer>::TimerMode as HrTimerMode>::Expires,
266        f: F,
267    ) -> U
268    where
269        F: FnOnce() -> U,
270    {
271        // SAFETY: We drop the timer handle below before returning.
272        let handle = unsafe { UnsafeHrTimerPointer::start(self, expires) };
273        let t = f();
274        drop(handle);
275        t
276    }
277}
278
279/// Implemented by [`HrTimerPointer`] implementers to give the C timer callback a
280/// function to call.
281// This is split from `HrTimerPointer` to make it easier to specify trait bounds.
282pub trait RawHrTimerCallback {
283    /// Type of the parameter passed to [`HrTimerCallback::run`]. It may be
284    /// [`Self`], or a pointer type derived from [`Self`].
285    type CallbackTarget<'a>;
286
287    /// Callback to be called from C when timer fires.
288    ///
289    /// # Safety
290    ///
291    /// Only to be called by C code in the `hrtimer` subsystem. `this` must point
292    /// to the `bindings::hrtimer` structure that was used to start the timer.
293    unsafe extern "C" fn run(this: *mut bindings::hrtimer) -> bindings::hrtimer_restart;
294}
295
296/// Implemented by structs that can be the target of a timer callback.
297pub trait HrTimerCallback {
298    /// The type whose [`RawHrTimerCallback::run`] method will be invoked when
299    /// the timer expires.
300    type Pointer<'a>: RawHrTimerCallback;
301
302    /// Called by the timer logic when the timer fires.
303    fn run(this: <Self::Pointer<'_> as RawHrTimerCallback>::CallbackTarget<'_>) -> HrTimerRestart
304    where
305        Self: Sized;
306}
307
308/// A handle representing a potentially running timer.
309///
310/// More than one handle representing the same timer might exist.
311///
312/// # Safety
313///
314/// When dropped, the timer represented by this handle must be cancelled, if it
315/// is running. If the timer handler is running when the handle is dropped, the
316/// drop method must wait for the handler to return before returning.
317///
318/// Note: One way to satisfy the safety requirement is to call `Self::cancel` in
319/// the drop implementation for `Self.`
320pub unsafe trait HrTimerHandle {
321    /// Cancel the timer. If the timer is in the running state, block till the
322    /// handler has returned.
323    ///
324    /// Note that the timer might be started by a concurrent start operation. If
325    /// so, the timer might not be in the **stopped** state when this function
326    /// returns.
327    fn cancel(&mut self) -> bool;
328}
329
330/// Implemented by structs that contain timer nodes.
331///
332/// Clients of the timer API would usually safely implement this trait by using
333/// the [`crate::impl_has_hr_timer`] macro.
334///
335/// # Safety
336///
337/// Implementers of this trait must ensure that the implementer has a
338/// [`HrTimer`] field and that all trait methods are implemented according to
339/// their documentation. All the methods of this trait must operate on the same
340/// field.
341pub unsafe trait HasHrTimer<T> {
342    /// The operational mode associated with this timer.
343    ///
344    /// This defines how the expiration value is interpreted.
345    type TimerMode: HrTimerMode;
346
347    /// Return a pointer to the [`HrTimer`] within `Self`.
348    ///
349    /// This function is useful to get access to the value without creating
350    /// intermediate references.
351    ///
352    /// # Safety
353    ///
354    /// `this` must be a valid pointer.
355    unsafe fn raw_get_timer(this: *const Self) -> *const HrTimer<T>;
356
357    /// Return a pointer to the struct that is containing the [`HrTimer`] pointed
358    /// to by `ptr`.
359    ///
360    /// This function is useful to get access to the value without creating
361    /// intermediate references.
362    ///
363    /// # Safety
364    ///
365    /// `ptr` must point to a [`HrTimer<T>`] field in a struct of type `Self`.
366    unsafe fn timer_container_of(ptr: *mut HrTimer<T>) -> *mut Self
367    where
368        Self: Sized;
369
370    /// Get pointer to the contained `bindings::hrtimer` struct.
371    ///
372    /// This function is useful to get access to the value without creating
373    /// intermediate references.
374    ///
375    /// # Safety
376    ///
377    /// `this` must be a valid pointer.
378    unsafe fn c_timer_ptr(this: *const Self) -> *const bindings::hrtimer {
379        // SAFETY: `this` is a valid pointer to a `Self`.
380        let timer_ptr = unsafe { Self::raw_get_timer(this) };
381
382        // SAFETY: timer_ptr points to an allocation of at least `HrTimer` size.
383        unsafe { HrTimer::raw_get(timer_ptr) }
384    }
385
386    /// Start the timer contained in the `Self` pointed to by `self_ptr`. If
387    /// it is already running it is removed and inserted.
388    ///
389    /// # Safety
390    ///
391    /// - `this` must point to a valid `Self`.
392    /// - Caller must ensure that the pointee of `this` lives until the timer
393    ///   fires or is canceled.
394    unsafe fn start(this: *const Self, expires: <Self::TimerMode as HrTimerMode>::Expires) {
395        // SAFETY: By function safety requirement, `this` is a valid `Self`.
396        unsafe {
397            bindings::hrtimer_start_range_ns(
398                Self::c_timer_ptr(this).cast_mut(),
399                expires.as_nanos(),
400                0,
401                <Self::TimerMode as HrTimerMode>::Clock::ID as u32,
402            );
403        }
404    }
405}
406
407/// Restart policy for timers.
408#[derive(Copy, Clone, PartialEq, Eq, Debug)]
409#[repr(u32)]
410pub enum HrTimerRestart {
411    /// Timer should not be restarted.
412    NoRestart = bindings::hrtimer_restart_HRTIMER_NORESTART,
413    /// Timer should be restarted.
414    Restart = bindings::hrtimer_restart_HRTIMER_RESTART,
415}
416
417impl HrTimerRestart {
418    fn into_c(self) -> bindings::hrtimer_restart {
419        self as bindings::hrtimer_restart
420    }
421}
422
423/// Time representations that can be used as expiration values in [`HrTimer`].
424pub trait HrTimerExpires {
425    /// Converts the expiration time into a nanosecond representation.
426    ///
427    /// This value corresponds to a raw ktime_t value, suitable for passing to kernel
428    /// timer functions. The interpretation (absolute vs relative) depends on the
429    /// associated [HrTimerMode] in use.
430    fn as_nanos(&self) -> i64;
431}
432
433impl<C: ClockSource> HrTimerExpires for Instant<C> {
434    #[inline]
435    fn as_nanos(&self) -> i64 {
436        Instant::<C>::as_nanos(self)
437    }
438}
439
440impl HrTimerExpires for Delta {
441    #[inline]
442    fn as_nanos(&self) -> i64 {
443        Delta::as_nanos(*self)
444    }
445}
446
447mod private {
448    use crate::time::ClockSource;
449
450    pub trait Sealed {}
451
452    impl<C: ClockSource> Sealed for super::AbsoluteMode<C> {}
453    impl<C: ClockSource> Sealed for super::RelativeMode<C> {}
454    impl<C: ClockSource> Sealed for super::AbsolutePinnedMode<C> {}
455    impl<C: ClockSource> Sealed for super::RelativePinnedMode<C> {}
456    impl<C: ClockSource> Sealed for super::AbsoluteSoftMode<C> {}
457    impl<C: ClockSource> Sealed for super::RelativeSoftMode<C> {}
458    impl<C: ClockSource> Sealed for super::AbsolutePinnedSoftMode<C> {}
459    impl<C: ClockSource> Sealed for super::RelativePinnedSoftMode<C> {}
460    impl<C: ClockSource> Sealed for super::AbsoluteHardMode<C> {}
461    impl<C: ClockSource> Sealed for super::RelativeHardMode<C> {}
462    impl<C: ClockSource> Sealed for super::AbsolutePinnedHardMode<C> {}
463    impl<C: ClockSource> Sealed for super::RelativePinnedHardMode<C> {}
464}
465
466/// Operational mode of [`HrTimer`].
467pub trait HrTimerMode: private::Sealed {
468    /// The C representation of hrtimer mode.
469    const C_MODE: bindings::hrtimer_mode;
470
471    /// Type representing the clock source.
472    type Clock: ClockSource;
473
474    /// Type representing the expiration specification (absolute or relative time).
475    type Expires: HrTimerExpires;
476}
477
478/// Timer that expires at a fixed point in time.
479pub struct AbsoluteMode<C: ClockSource>(PhantomData<C>);
480
481impl<C: ClockSource> HrTimerMode for AbsoluteMode<C> {
482    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS;
483
484    type Clock = C;
485    type Expires = Instant<C>;
486}
487
488/// Timer that expires after a delay from now.
489pub struct RelativeMode<C: ClockSource>(PhantomData<C>);
490
491impl<C: ClockSource> HrTimerMode for RelativeMode<C> {
492    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL;
493
494    type Clock = C;
495    type Expires = Delta;
496}
497
498/// Timer with absolute expiration time, pinned to its current CPU.
499pub struct AbsolutePinnedMode<C: ClockSource>(PhantomData<C>);
500impl<C: ClockSource> HrTimerMode for AbsolutePinnedMode<C> {
501    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_PINNED;
502
503    type Clock = C;
504    type Expires = Instant<C>;
505}
506
507/// Timer with relative expiration time, pinned to its current CPU.
508pub struct RelativePinnedMode<C: ClockSource>(PhantomData<C>);
509impl<C: ClockSource> HrTimerMode for RelativePinnedMode<C> {
510    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_PINNED;
511
512    type Clock = C;
513    type Expires = Delta;
514}
515
516/// Timer with absolute expiration, handled in soft irq context.
517pub struct AbsoluteSoftMode<C: ClockSource>(PhantomData<C>);
518impl<C: ClockSource> HrTimerMode for AbsoluteSoftMode<C> {
519    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_SOFT;
520
521    type Clock = C;
522    type Expires = Instant<C>;
523}
524
525/// Timer with relative expiration, handled in soft irq context.
526pub struct RelativeSoftMode<C: ClockSource>(PhantomData<C>);
527impl<C: ClockSource> HrTimerMode for RelativeSoftMode<C> {
528    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_SOFT;
529
530    type Clock = C;
531    type Expires = Delta;
532}
533
534/// Timer with absolute expiration, pinned to CPU and handled in soft irq context.
535pub struct AbsolutePinnedSoftMode<C: ClockSource>(PhantomData<C>);
536impl<C: ClockSource> HrTimerMode for AbsolutePinnedSoftMode<C> {
537    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_PINNED_SOFT;
538
539    type Clock = C;
540    type Expires = Instant<C>;
541}
542
543/// Timer with absolute expiration, pinned to CPU and handled in soft irq context.
544pub struct RelativePinnedSoftMode<C: ClockSource>(PhantomData<C>);
545impl<C: ClockSource> HrTimerMode for RelativePinnedSoftMode<C> {
546    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_PINNED_SOFT;
547
548    type Clock = C;
549    type Expires = Delta;
550}
551
552/// Timer with absolute expiration, handled in hard irq context.
553pub struct AbsoluteHardMode<C: ClockSource>(PhantomData<C>);
554impl<C: ClockSource> HrTimerMode for AbsoluteHardMode<C> {
555    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_HARD;
556
557    type Clock = C;
558    type Expires = Instant<C>;
559}
560
561/// Timer with relative expiration, handled in hard irq context.
562pub struct RelativeHardMode<C: ClockSource>(PhantomData<C>);
563impl<C: ClockSource> HrTimerMode for RelativeHardMode<C> {
564    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_HARD;
565
566    type Clock = C;
567    type Expires = Delta;
568}
569
570/// Timer with absolute expiration, pinned to CPU and handled in hard irq context.
571pub struct AbsolutePinnedHardMode<C: ClockSource>(PhantomData<C>);
572impl<C: ClockSource> HrTimerMode for AbsolutePinnedHardMode<C> {
573    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_ABS_PINNED_HARD;
574
575    type Clock = C;
576    type Expires = Instant<C>;
577}
578
579/// Timer with relative expiration, pinned to CPU and handled in hard irq context.
580pub struct RelativePinnedHardMode<C: ClockSource>(PhantomData<C>);
581impl<C: ClockSource> HrTimerMode for RelativePinnedHardMode<C> {
582    const C_MODE: bindings::hrtimer_mode = bindings::hrtimer_mode_HRTIMER_MODE_REL_PINNED_HARD;
583
584    type Clock = C;
585    type Expires = Delta;
586}
587
588/// Use to implement the [`HasHrTimer<T>`] trait.
589///
590/// See [`module`] documentation for an example.
591///
592/// [`module`]: crate::time::hrtimer
593#[macro_export]
594macro_rules! impl_has_hr_timer {
595    (
596        impl$({$($generics:tt)*})?
597            HasHrTimer<$timer_type:ty>
598            for $self:ty
599        {
600            mode : $mode:ty,
601            field : self.$field:ident $(,)?
602        }
603        $($rest:tt)*
604    ) => {
605        // SAFETY: This implementation of `raw_get_timer` only compiles if the
606        // field has the right type.
607        unsafe impl$(<$($generics)*>)? $crate::time::hrtimer::HasHrTimer<$timer_type> for $self {
608            type TimerMode = $mode;
609
610            #[inline]
611            unsafe fn raw_get_timer(
612                this: *const Self,
613            ) -> *const $crate::time::hrtimer::HrTimer<$timer_type> {
614                // SAFETY: The caller promises that the pointer is not dangling.
615                unsafe { ::core::ptr::addr_of!((*this).$field) }
616            }
617
618            #[inline]
619            unsafe fn timer_container_of(
620                ptr: *mut $crate::time::hrtimer::HrTimer<$timer_type>,
621            ) -> *mut Self {
622                // SAFETY: As per the safety requirement of this function, `ptr`
623                // is pointing inside a `$timer_type`.
624                unsafe { ::kernel::container_of!(ptr, $timer_type, $field) }
625            }
626        }
627    }
628}
629
630mod arc;
631pub use arc::ArcHrTimerHandle;
632mod pin;
633pub use pin::PinHrTimerHandle;
634mod pin_mut;
635pub use pin_mut::PinMutHrTimerHandle;
636// `box` is a reserved keyword, so prefix with `t` for timer
637mod tbox;
638pub use tbox::BoxHrTimerHandle;