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 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)] 82 pub 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. 90 unsafe 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. 94 unsafe impl<T> Sync for HrTimer<T> {} 95 96 impl<T> HrTimer<T> { 97 /// Return an initializer for a new timer instance. new() -> impl PinInit<Self> where T: HrTimerCallback, T: HasHrTimer<T>,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`. raw_get(this: *const Self) -> *mut bindings::hrtimer130 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::cast_into(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`. raw_cancel(this: *const Self) -> bool156 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. 178 pub 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. start(self, expires: <Self::TimerMode as HrTimerMode>::Expires) -> Self::TimerHandle196 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. 210 pub 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`]. start(self, expires: <Self::TimerMode as HrTimerMode>::Expires) -> Self::TimerHandle232 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. 241 pub 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. start_scoped<T, F>(self, expires: <Self::TimerMode as HrTimerMode>::Expires, f: F) -> T where F: FnOnce() -> T249 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. 257 unsafe impl<T> ScopedHrTimerPointer for T 258 where 259 T: UnsafeHrTimerPointer, 260 { 261 type TimerMode = T::TimerMode; 262 start_scoped<U, F>( self, expires: <<T as UnsafeHrTimerPointer>::TimerMode as HrTimerMode>::Expires, f: F, ) -> U where F: FnOnce() -> U,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. 282 pub 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. run(this: *mut bindings::hrtimer) -> bindings::hrtimer_restart293 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. 297 pub 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. run(this: <Self::Pointer<'_> as RawHrTimerCallback>::CallbackTarget<'_>) -> HrTimerRestart where Self: Sized303 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.` 320 pub 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. cancel(&mut self) -> bool327 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. 341 pub 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. raw_get_timer(this: *const Self) -> *const HrTimer<T>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`. timer_container_of(ptr: *mut HrTimer<T>) -> *mut Self where Self: Sized366 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. c_timer_ptr(this: *const Self) -> *const bindings::hrtimer378 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. start(this: *const Self, expires: <Self::TimerMode as HrTimerMode>::Expires)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>::C_MODE, 402 ); 403 } 404 } 405 } 406 407 /// Restart policy for timers. 408 #[derive(Copy, Clone, PartialEq, Eq, Debug)] 409 #[repr(u32)] 410 pub 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 417 impl HrTimerRestart { into_c(self) -> bindings::hrtimer_restart418 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`]. 424 pub 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. as_nanos(&self) -> i64430 fn as_nanos(&self) -> i64; 431 } 432 433 impl<C: ClockSource> HrTimerExpires for Instant<C> { 434 #[inline] as_nanos(&self) -> i64435 fn as_nanos(&self) -> i64 { 436 Instant::<C>::as_nanos(self) 437 } 438 } 439 440 impl HrTimerExpires for Delta { 441 #[inline] as_nanos(&self) -> i64442 fn as_nanos(&self) -> i64 { 443 Delta::as_nanos(*self) 444 } 445 } 446 447 mod 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`]. 467 pub 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. 479 pub struct AbsoluteMode<C: ClockSource>(PhantomData<C>); 480 481 impl<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. 489 pub struct RelativeMode<C: ClockSource>(PhantomData<C>); 490 491 impl<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. 499 pub struct AbsolutePinnedMode<C: ClockSource>(PhantomData<C>); 500 impl<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. 508 pub struct RelativePinnedMode<C: ClockSource>(PhantomData<C>); 509 impl<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. 517 pub struct AbsoluteSoftMode<C: ClockSource>(PhantomData<C>); 518 impl<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. 526 pub struct RelativeSoftMode<C: ClockSource>(PhantomData<C>); 527 impl<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. 535 pub struct AbsolutePinnedSoftMode<C: ClockSource>(PhantomData<C>); 536 impl<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. 544 pub struct RelativePinnedSoftMode<C: ClockSource>(PhantomData<C>); 545 impl<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. 553 pub struct AbsoluteHardMode<C: ClockSource>(PhantomData<C>); 554 impl<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. 562 pub struct RelativeHardMode<C: ClockSource>(PhantomData<C>); 563 impl<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. 571 pub struct AbsolutePinnedHardMode<C: ClockSource>(PhantomData<C>); 572 impl<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. 580 pub struct RelativePinnedHardMode<C: ClockSource>(PhantomData<C>); 581 impl<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] 594 macro_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 630 mod arc; 631 pub use arc::ArcHrTimerHandle; 632 mod pin; 633 pub use pin::PinHrTimerHandle; 634 mod pin_mut; 635 pub use pin_mut::PinMutHrTimerHandle; 636 // `box` is a reserved keyword, so prefix with `t` for timer 637 mod tbox; 638 pub use tbox::BoxHrTimerHandle; 639