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