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 nanos: 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.nanos; 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.nanos; 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 /// A span of time. 295 /// 296 /// This struct represents a span of time, with its value stored as nanoseconds. 297 /// The value can represent any valid i64 value, including negative, zero, and 298 /// positive numbers. 299 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 300 pub struct Delta { 301 nanos: i64, 302 } 303 304 impl ops::Add for Delta { 305 type Output = Self; 306 307 #[inline] 308 fn add(self, rhs: Self) -> Self { 309 Self { 310 nanos: self.nanos + rhs.nanos, 311 } 312 } 313 } 314 315 impl ops::AddAssign for Delta { 316 #[inline] 317 fn add_assign(&mut self, rhs: Self) { 318 self.nanos += rhs.nanos; 319 } 320 } 321 322 impl ops::Sub for Delta { 323 type Output = Self; 324 325 #[inline] 326 fn sub(self, rhs: Self) -> Self::Output { 327 Self { 328 nanos: self.nanos - rhs.nanos, 329 } 330 } 331 } 332 333 impl ops::SubAssign for Delta { 334 #[inline] 335 fn sub_assign(&mut self, rhs: Self) { 336 self.nanos -= rhs.nanos; 337 } 338 } 339 340 impl ops::Mul<i64> for Delta { 341 type Output = Self; 342 343 #[inline] 344 fn mul(self, rhs: i64) -> Self::Output { 345 Self { 346 nanos: self.nanos * rhs, 347 } 348 } 349 } 350 351 impl ops::MulAssign<i64> for Delta { 352 #[inline] 353 fn mul_assign(&mut self, rhs: i64) { 354 self.nanos *= rhs; 355 } 356 } 357 358 impl ops::Div for Delta { 359 type Output = i64; 360 361 #[inline] 362 fn div(self, rhs: Self) -> Self::Output { 363 #[cfg(CONFIG_64BIT)] 364 { 365 self.nanos / rhs.nanos 366 } 367 368 #[cfg(not(CONFIG_64BIT))] 369 { 370 // SAFETY: This function is always safe to call regardless of the input values 371 unsafe { bindings::div64_s64(self.nanos, rhs.nanos) } 372 } 373 } 374 } 375 376 impl Delta { 377 /// A span of time equal to zero. 378 pub const ZERO: Self = Self { nanos: 0 }; 379 380 /// Create a new [`Delta`] from a number of nanoseconds. 381 #[inline] 382 pub const fn from_nanos(nanos: i64) -> Self { 383 Self { nanos } 384 } 385 386 /// Create a new [`Delta`] from a number of microseconds. 387 /// 388 /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775. 389 /// If `micros` is outside this range, `i64::MIN` is used for negative values, 390 /// and `i64::MAX` is used for positive values due to saturation. 391 #[inline] 392 pub const fn from_micros(micros: i64) -> Self { 393 Self { 394 nanos: micros.saturating_mul(NSEC_PER_USEC), 395 } 396 } 397 398 /// Create a new [`Delta`] from a number of milliseconds. 399 /// 400 /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854. 401 /// If `millis` is outside this range, `i64::MIN` is used for negative values, 402 /// and `i64::MAX` is used for positive values due to saturation. 403 #[inline] 404 pub const fn from_millis(millis: i64) -> Self { 405 Self { 406 nanos: millis.saturating_mul(NSEC_PER_MSEC), 407 } 408 } 409 410 /// Create a new [`Delta`] from a number of seconds. 411 /// 412 /// The `secs` can range from -9_223_372_036 to 9_223_372_036. 413 /// If `secs` is outside this range, `i64::MIN` is used for negative values, 414 /// and `i64::MAX` is used for positive values due to saturation. 415 #[inline] 416 pub const fn from_secs(secs: i64) -> Self { 417 Self { 418 nanos: secs.saturating_mul(NSEC_PER_SEC), 419 } 420 } 421 422 /// Return `true` if the [`Delta`] spans no time. 423 #[inline] 424 pub fn is_zero(self) -> bool { 425 self.as_nanos() == 0 426 } 427 428 /// Return `true` if the [`Delta`] spans a negative amount of time. 429 #[inline] 430 pub fn is_negative(self) -> bool { 431 self.as_nanos() < 0 432 } 433 434 /// Return the number of nanoseconds in the [`Delta`]. 435 #[inline] 436 pub const fn as_nanos(self) -> i64 { 437 self.nanos 438 } 439 440 /// Return the smallest number of microseconds greater than or equal 441 /// to the value in the [`Delta`]. 442 #[inline] 443 pub fn as_micros_ceil(self) -> i64 { 444 #[cfg(CONFIG_64BIT)] 445 { 446 self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC 447 } 448 449 #[cfg(not(CONFIG_64BIT))] 450 // SAFETY: It is always safe to call `ktime_to_us()` with any value. 451 unsafe { 452 bindings::ktime_to_us(self.as_nanos().saturating_add(NSEC_PER_USEC - 1)) 453 } 454 } 455 456 /// Return the number of milliseconds in the [`Delta`]. 457 #[inline] 458 pub fn as_millis(self) -> i64 { 459 #[cfg(CONFIG_64BIT)] 460 { 461 self.as_nanos() / NSEC_PER_MSEC 462 } 463 464 #[cfg(not(CONFIG_64BIT))] 465 // SAFETY: It is always safe to call `ktime_to_ms()` with any value. 466 unsafe { 467 bindings::ktime_to_ms(self.as_nanos()) 468 } 469 } 470 471 /// Return `self % dividend` where `dividend` is in nanoseconds. 472 /// 473 /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is 474 /// limited to 32 bit dividends. 475 #[inline] 476 pub fn rem_nanos(self, dividend: i32) -> Self { 477 #[cfg(CONFIG_64BIT)] 478 { 479 Self { 480 nanos: self.as_nanos() % i64::from(dividend), 481 } 482 } 483 484 #[cfg(not(CONFIG_64BIT))] 485 { 486 let mut rem = 0; 487 488 // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it. 489 unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) }; 490 491 Self { 492 nanos: i64::from(rem), 493 } 494 } 495 } 496 } 497