1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Time related primitives. 4 //! 5 //! This module contains the kernel APIs related to time and timers that 6 //! have been ported or wrapped for usage by Rust code in the kernel. 7 //! 8 //! There are two types in this module: 9 //! 10 //! - The [`Instant`] type represents a specific point in time. 11 //! - The [`Delta`] type represents a span of time. 12 //! 13 //! Note that the C side uses `ktime_t` type to represent both. However, timestamp 14 //! and timedelta are different. To avoid confusion, we use two different types. 15 //! 16 //! A [`Instant`] object can be created by calling the [`Instant::now()`] function. 17 //! It represents a point in time at which the object was created. 18 //! By calling the [`Instant::elapsed()`] method, a [`Delta`] object representing 19 //! the elapsed time can be created. The [`Delta`] object can also be created 20 //! by subtracting two [`Instant`] objects. 21 //! 22 //! A [`Delta`] type supports methods to retrieve the duration in various units. 23 //! 24 //! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h). 25 //! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h). 26 27 use core::marker::PhantomData; 28 use core::ops; 29 30 pub mod delay; 31 pub mod hrtimer; 32 33 /// The number of nanoseconds per microsecond. 34 pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64; 35 36 /// The number of nanoseconds per millisecond. 37 pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64; 38 39 /// The number of nanoseconds per second. 40 pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64; 41 42 /// The time unit of Linux kernel. One jiffy equals (1/HZ) second. 43 pub type Jiffies = crate::ffi::c_ulong; 44 45 /// The millisecond time unit. 46 pub type Msecs = crate::ffi::c_uint; 47 48 /// Converts milliseconds to jiffies. 49 #[inline] 50 pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies { 51 // SAFETY: The `__msecs_to_jiffies` function is always safe to call no 52 // matter what the argument is. 53 unsafe { bindings::__msecs_to_jiffies(msecs) } 54 } 55 56 /// Trait for clock sources. 57 /// 58 /// Selection of the clock source depends on the use case. In some cases the usage of a 59 /// particular clock is mandatory, e.g. in network protocols, filesystems. In other 60 /// cases the user of the clock has to decide which clock is best suited for the 61 /// purpose. In most scenarios clock [`Monotonic`] is the best choice as it 62 /// provides a accurate monotonic notion of time (leap second smearing ignored). 63 /// 64 /// # Safety 65 /// 66 /// Implementers must ensure that `ktime_get()` returns a value in the inclusive range 67 /// `0..=KTIME_MAX` (i.e., greater than or equal to 0 and less than or equal to 68 /// `KTIME_MAX`, where `KTIME_MAX` equals `i64::MAX`). 69 pub unsafe trait ClockSource { 70 /// The kernel clock ID associated with this clock source. 71 /// 72 /// This constant corresponds to the C side `clockid_t` value. 73 const ID: bindings::clockid_t; 74 75 /// Get the current time from the clock source. 76 /// 77 /// The function must return a value in the range `0..=KTIME_MAX`. 78 fn ktime_get() -> bindings::ktime_t; 79 } 80 81 /// A monotonically increasing clock. 82 /// 83 /// A nonsettable system-wide clock that represents monotonic time since as 84 /// described by POSIX, "some unspecified point in the past". On Linux, that 85 /// point corresponds to the number of seconds that the system has been 86 /// running since it was booted. 87 /// 88 /// The CLOCK_MONOTONIC clock is not affected by discontinuous jumps in the 89 /// CLOCK_REAL (e.g., if the system administrator manually changes the 90 /// clock), but is affected by frequency adjustments. This clock does not 91 /// count time that the system is suspended. 92 pub struct Monotonic; 93 94 // SAFETY: The kernel's `ktime_get()` is guaranteed to return a value 95 // in `0..=KTIME_MAX`. 96 unsafe impl ClockSource for Monotonic { 97 const ID: bindings::clockid_t = bindings::CLOCK_MONOTONIC as bindings::clockid_t; 98 99 fn ktime_get() -> bindings::ktime_t { 100 // SAFETY: It is always safe to call `ktime_get()` outside of NMI context. 101 unsafe { bindings::ktime_get() } 102 } 103 } 104 105 /// A settable system-wide clock that measures real (i.e., wall-clock) time. 106 /// 107 /// Setting this clock requires appropriate privileges. This clock is 108 /// affected by discontinuous jumps in the system time (e.g., if the system 109 /// administrator manually changes the clock), and by frequency adjustments 110 /// performed by NTP and similar applications via adjtime(3), adjtimex(2), 111 /// clock_adjtime(2), and ntp_adjtime(3). This clock normally counts the 112 /// number of seconds since 1970-01-01 00:00:00 Coordinated Universal Time 113 /// (UTC) except that it ignores leap seconds; near a leap second it may be 114 /// adjusted by leap second smearing to stay roughly in sync with UTC. Leap 115 /// second smearing applies frequency adjustments to the clock to speed up 116 /// or slow down the clock to account for the leap second without 117 /// discontinuities in the clock. If leap second smearing is not applied, 118 /// the clock will experience discontinuity around leap second adjustment. 119 pub struct RealTime; 120 121 // SAFETY: The kernel's `ktime_get_real()` is guaranteed to return a value 122 // in `0..=KTIME_MAX`. 123 unsafe impl ClockSource for RealTime { 124 const ID: bindings::clockid_t = bindings::CLOCK_REALTIME as bindings::clockid_t; 125 126 fn ktime_get() -> bindings::ktime_t { 127 // SAFETY: It is always safe to call `ktime_get_real()` outside of NMI context. 128 unsafe { bindings::ktime_get_real() } 129 } 130 } 131 132 /// A monotonic that ticks while system is suspended. 133 /// 134 /// A nonsettable system-wide clock that is identical to CLOCK_MONOTONIC, 135 /// except that it also includes any time that the system is suspended. This 136 /// allows applications to get a suspend-aware monotonic clock without 137 /// having to deal with the complications of CLOCK_REALTIME, which may have 138 /// discontinuities if the time is changed using settimeofday(2) or similar. 139 pub struct BootTime; 140 141 // SAFETY: The kernel's `ktime_get_boottime()` is guaranteed to return a value 142 // in `0..=KTIME_MAX`. 143 unsafe impl ClockSource for BootTime { 144 const ID: bindings::clockid_t = bindings::CLOCK_BOOTTIME as bindings::clockid_t; 145 146 fn ktime_get() -> bindings::ktime_t { 147 // SAFETY: It is always safe to call `ktime_get_boottime()` outside of NMI context. 148 unsafe { bindings::ktime_get_boottime() } 149 } 150 } 151 152 /// International Atomic Time. 153 /// 154 /// A system-wide clock derived from wall-clock time but counting leap seconds. 155 /// 156 /// This clock is coupled to CLOCK_REALTIME and will be set when CLOCK_REALTIME is 157 /// set, or when the offset to CLOCK_REALTIME is changed via adjtimex(2). This 158 /// usually happens during boot and **should** not happen during normal operations. 159 /// However, if NTP or another application adjusts CLOCK_REALTIME by leap second 160 /// smearing, this clock will not be precise during leap second smearing. 161 /// 162 /// The acronym TAI refers to International Atomic Time. 163 pub struct Tai; 164 165 // SAFETY: The kernel's `ktime_get_clocktai()` is guaranteed to return a value 166 // in `0..=KTIME_MAX`. 167 unsafe impl ClockSource for Tai { 168 const ID: bindings::clockid_t = bindings::CLOCK_TAI as bindings::clockid_t; 169 170 fn ktime_get() -> bindings::ktime_t { 171 // SAFETY: It is always safe to call `ktime_get_tai()` outside of NMI context. 172 unsafe { bindings::ktime_get_clocktai() } 173 } 174 } 175 176 /// A specific point in time. 177 /// 178 /// # Invariants 179 /// 180 /// The `inner` value is in the range from 0 to `KTIME_MAX`. 181 #[repr(transparent)] 182 #[derive(PartialEq, PartialOrd, Eq, Ord)] 183 pub struct Instant<C: ClockSource> { 184 inner: bindings::ktime_t, 185 _c: PhantomData<C>, 186 } 187 188 impl<C: ClockSource> Clone for Instant<C> { 189 fn clone(&self) -> Self { 190 *self 191 } 192 } 193 194 impl<C: ClockSource> Copy for Instant<C> {} 195 196 impl<C: ClockSource> Instant<C> { 197 /// Get the current time from the clock source. 198 #[inline] 199 pub fn now() -> Self { 200 // INVARIANT: The `ClockSource::ktime_get()` function returns a value in the range 201 // from 0 to `KTIME_MAX`. 202 Self { 203 inner: C::ktime_get(), 204 _c: PhantomData, 205 } 206 } 207 208 /// Return the amount of time elapsed since the [`Instant`]. 209 #[inline] 210 pub fn elapsed(&self) -> Delta { 211 Self::now() - *self 212 } 213 214 #[inline] 215 pub(crate) fn as_nanos(&self) -> i64 { 216 self.inner 217 } 218 219 /// Create an [`Instant`] from a `ktime_t` without checking if it is non-negative. 220 /// 221 /// # Panics 222 /// 223 /// On debug builds, this function will panic if `ktime` is not in the range from 0 to 224 /// `KTIME_MAX`. 225 /// 226 /// # Safety 227 /// 228 /// The caller promises that `ktime` is in the range from 0 to `KTIME_MAX`. 229 #[inline] 230 pub(crate) unsafe fn from_ktime(ktime: bindings::ktime_t) -> Self { 231 debug_assert!(ktime >= 0); 232 233 // INVARIANT: Our safety contract ensures that `ktime` is in the range from 0 to 234 // `KTIME_MAX`. 235 Self { 236 inner: ktime, 237 _c: PhantomData, 238 } 239 } 240 } 241 242 impl<C: ClockSource> ops::Sub for Instant<C> { 243 type Output = Delta; 244 245 // By the type invariant, it never overflows. 246 #[inline] 247 fn sub(self, other: Instant<C>) -> Delta { 248 Delta { 249 value: self.inner - other.inner, 250 } 251 } 252 } 253 254 impl<T: ClockSource> ops::Add<Delta> for Instant<T> { 255 type Output = Self; 256 257 #[inline] 258 fn add(self, rhs: Delta) -> Self::Output { 259 // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow 260 // (e.g. go above `KTIME_MAX`) 261 let res = self.inner + rhs.value; 262 263 // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0 264 #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)] 265 assert!(res >= 0); 266 267 Self { 268 inner: res, 269 _c: PhantomData, 270 } 271 } 272 } 273 274 impl<T: ClockSource> ops::Sub<Delta> for Instant<T> { 275 type Output = Self; 276 277 #[inline] 278 fn sub(self, rhs: Delta) -> Self::Output { 279 // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow 280 // (e.g. go above `KTIME_MAX`) 281 let res = self.inner - rhs.value; 282 283 // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0 284 #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)] 285 assert!(res >= 0); 286 287 Self { 288 inner: res, 289 _c: PhantomData, 290 } 291 } 292 } 293 294 mod private { 295 pub trait Sealed {} 296 297 impl Sealed for super::Nsec {} 298 impl Sealed for super::Jiffy {} 299 } 300 301 /// A trait for time units. 302 pub trait TimeUnit: private::Sealed { 303 /// The underlying representation of the time unit. 304 type Repr: Copy + Clone + PartialEq + PartialOrd + Eq + Ord + core::fmt::Debug; 305 } 306 307 /// A time unit of nanoseconds. 308 /// 309 /// A [`Delta<Nsec>`] stores its value as [`i64`] nanoseconds and can represent 310 /// any [`i64`] value, including negative, zero, and positive numbers. 311 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 312 pub enum Nsec {} 313 314 impl TimeUnit for Nsec { 315 type Repr = i64; 316 } 317 318 /// A time unit of jiffies. 319 /// 320 /// A [`Delta<Jiffy>`] stores its value as [`isize`] jiffies and can represent 321 /// any [`isize`] value, including negative, zero, and positive numbers. 322 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 323 pub enum Jiffy {} 324 325 impl TimeUnit for Jiffy { 326 type Repr = isize; 327 } 328 329 /// A span of time. 330 /// 331 /// The span is stored in the unit given by the type parameter `U` (see 332 /// [`TimeUnit`]); its value has type `U::Repr`. `U` defaults to [`Nsec`], so a 333 /// plain [`Delta`] is a span in nanoseconds. The value can be negative, zero, or 334 /// positive. 335 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 336 pub struct Delta<U: TimeUnit = Nsec> { 337 value: U::Repr, 338 } 339 340 impl Delta<Jiffy> { 341 /// Create a new [`Delta`] from a number of jiffies. 342 #[inline] 343 pub const fn from_jiffies(jiffies: isize) -> Self { 344 Self { value: jiffies } 345 } 346 347 /// Return the number of jiffies in the [`Delta`]. 348 #[inline] 349 pub const fn as_jiffies(self) -> isize { 350 self.value 351 } 352 } 353 354 impl ops::Add for Delta { 355 type Output = Self; 356 357 #[inline] 358 fn add(self, rhs: Self) -> Self { 359 Self { 360 value: self.value + rhs.value, 361 } 362 } 363 } 364 365 impl ops::AddAssign for Delta { 366 #[inline] 367 fn add_assign(&mut self, rhs: Self) { 368 self.value += rhs.value; 369 } 370 } 371 372 impl ops::Sub for Delta { 373 type Output = Self; 374 375 #[inline] 376 fn sub(self, rhs: Self) -> Self::Output { 377 Self { 378 value: self.value - rhs.value, 379 } 380 } 381 } 382 383 impl ops::SubAssign for Delta { 384 #[inline] 385 fn sub_assign(&mut self, rhs: Self) { 386 self.value -= rhs.value; 387 } 388 } 389 390 impl ops::Mul<i64> for Delta { 391 type Output = Self; 392 393 #[inline] 394 fn mul(self, rhs: i64) -> Self::Output { 395 Self { 396 value: self.value * rhs, 397 } 398 } 399 } 400 401 impl ops::MulAssign<i64> for Delta { 402 #[inline] 403 fn mul_assign(&mut self, rhs: i64) { 404 self.value *= rhs; 405 } 406 } 407 408 impl ops::Div for Delta { 409 type Output = i64; 410 411 #[inline] 412 fn div(self, rhs: Self) -> Self::Output { 413 #[cfg(CONFIG_64BIT)] 414 { 415 self.value / rhs.value 416 } 417 418 #[cfg(not(CONFIG_64BIT))] 419 { 420 // SAFETY: This function is always safe to call regardless of the input values 421 unsafe { bindings::div64_s64(self.value, rhs.value) } 422 } 423 } 424 } 425 426 impl Delta { 427 /// A span of time equal to zero. 428 pub const ZERO: Self = Self { value: 0 }; 429 430 /// Create a new [`Delta`] from a number of nanoseconds. 431 #[inline] 432 pub const fn from_nanos(nanos: i64) -> Self { 433 Self { value: nanos } 434 } 435 436 /// Create a new [`Delta`] from a number of microseconds. 437 /// 438 /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775. 439 /// If `micros` is outside this range, `i64::MIN` is used for negative values, 440 /// and `i64::MAX` is used for positive values due to saturation. 441 #[inline] 442 pub const fn from_micros(micros: i64) -> Self { 443 Self { 444 value: micros.saturating_mul(NSEC_PER_USEC), 445 } 446 } 447 448 /// Create a new [`Delta`] from a number of milliseconds. 449 /// 450 /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854. 451 /// If `millis` is outside this range, `i64::MIN` is used for negative values, 452 /// and `i64::MAX` is used for positive values due to saturation. 453 #[inline] 454 pub const fn from_millis(millis: i64) -> Self { 455 Self { 456 value: millis.saturating_mul(NSEC_PER_MSEC), 457 } 458 } 459 460 /// Create a new [`Delta`] from a number of seconds. 461 /// 462 /// The `secs` can range from -9_223_372_036 to 9_223_372_036. 463 /// If `secs` is outside this range, `i64::MIN` is used for negative values, 464 /// and `i64::MAX` is used for positive values due to saturation. 465 #[inline] 466 pub const fn from_secs(secs: i64) -> Self { 467 Self { 468 value: secs.saturating_mul(NSEC_PER_SEC), 469 } 470 } 471 472 /// Return `true` if the [`Delta`] spans no time. 473 #[inline] 474 pub fn is_zero(self) -> bool { 475 self.as_nanos() == 0 476 } 477 478 /// Return `true` if the [`Delta`] spans a negative amount of time. 479 #[inline] 480 pub fn is_negative(self) -> bool { 481 self.as_nanos() < 0 482 } 483 484 /// Return the number of nanoseconds in the [`Delta`]. 485 #[inline] 486 pub const fn as_nanos(self) -> i64 { 487 self.value 488 } 489 490 /// Return the smallest number of microseconds greater than or equal 491 /// to the value in the [`Delta`]. 492 #[inline] 493 pub fn as_micros_ceil(self) -> i64 { 494 // Only positive values need to be rounded up: truncating division already 495 // rounds towards zero, i.e. up, for negative values. 496 // 497 // The usual `(nanos + d - 1) / d` is not used because the addition overflows 498 // once `nanos` exceeds `i64::MAX - (d - 1)`; saturating the addition instead 499 // would drop the rounding bias and return a result one unit too small. 500 let n = self.as_nanos(); 501 502 let (n, add) = if n > 0 { (n - 1, 1) } else { (n, 0) }; 503 504 #[cfg(CONFIG_64BIT)] 505 { 506 n / NSEC_PER_USEC + add 507 } 508 509 #[cfg(not(CONFIG_64BIT))] 510 // SAFETY: It is always safe to call `ktime_to_us()` with any value. 511 unsafe { 512 bindings::ktime_to_us(n) + add 513 } 514 } 515 516 /// Return the number of milliseconds in the [`Delta`]. 517 #[inline] 518 pub fn as_millis(self) -> i64 { 519 #[cfg(CONFIG_64BIT)] 520 { 521 self.as_nanos() / NSEC_PER_MSEC 522 } 523 524 #[cfg(not(CONFIG_64BIT))] 525 // SAFETY: It is always safe to call `ktime_to_ms()` with any value. 526 unsafe { 527 bindings::ktime_to_ms(self.as_nanos()) 528 } 529 } 530 531 /// Return the smallest number of milliseconds greater than or equal 532 /// to the value in the [`Delta`]. 533 #[inline] 534 pub fn as_millis_ceil(self) -> i64 { 535 // Only positive values need to be rounded up: truncating division already 536 // rounds towards zero, i.e. up, for negative values. 537 // 538 // The usual `(nanos + d - 1) / d` is not used because the addition overflows 539 // once `nanos` exceeds `i64::MAX - (d - 1)`; saturating the addition instead 540 // would drop the rounding bias and return a result one unit too small. 541 let n = self.as_nanos(); 542 543 let (n, add) = if n > 0 { (n - 1, 1) } else { (n, 0) }; 544 545 #[cfg(CONFIG_64BIT)] 546 { 547 n / NSEC_PER_MSEC + add 548 } 549 550 #[cfg(not(CONFIG_64BIT))] 551 // SAFETY: It is always safe to call `ktime_to_ms()` with any value. 552 unsafe { 553 bindings::ktime_to_ms(n) + add 554 } 555 } 556 557 /// Return `self % dividend` where `dividend` is in nanoseconds. 558 /// 559 /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is 560 /// limited to 32 bit dividends. 561 #[inline] 562 pub fn rem_nanos(self, dividend: i32) -> Self { 563 #[cfg(CONFIG_64BIT)] 564 { 565 Self { 566 value: self.as_nanos() % i64::from(dividend), 567 } 568 } 569 570 #[cfg(not(CONFIG_64BIT))] 571 { 572 let mut rem = 0; 573 574 // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it. 575 unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) }; 576 577 Self { 578 value: i64::from(rem), 579 } 580 } 581 } 582 } 583