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 pub trait ClockSource { 64 /// The kernel clock ID associated with this clock source. 65 /// 66 /// This constant corresponds to the C side `clockid_t` value. 67 const ID: bindings::clockid_t; 68 69 /// Get the current time from the clock source. 70 /// 71 /// The function must return a value in the range from 0 to `KTIME_MAX`. 72 fn ktime_get() -> bindings::ktime_t; 73 } 74 75 /// A monotonically increasing clock. 76 /// 77 /// A nonsettable system-wide clock that represents monotonic time since as 78 /// described by POSIX, "some unspecified point in the past". On Linux, that 79 /// point corresponds to the number of seconds that the system has been 80 /// running since it was booted. 81 /// 82 /// The CLOCK_MONOTONIC clock is not affected by discontinuous jumps in the 83 /// CLOCK_REAL (e.g., if the system administrator manually changes the 84 /// clock), but is affected by frequency adjustments. This clock does not 85 /// count time that the system is suspended. 86 pub struct Monotonic; 87 88 impl ClockSource for Monotonic { 89 const ID: bindings::clockid_t = bindings::CLOCK_MONOTONIC as bindings::clockid_t; 90 91 fn ktime_get() -> bindings::ktime_t { 92 // SAFETY: It is always safe to call `ktime_get()` outside of NMI context. 93 unsafe { bindings::ktime_get() } 94 } 95 } 96 97 /// A settable system-wide clock that measures real (i.e., wall-clock) time. 98 /// 99 /// Setting this clock requires appropriate privileges. This clock is 100 /// affected by discontinuous jumps in the system time (e.g., if the system 101 /// administrator manually changes the clock), and by frequency adjustments 102 /// performed by NTP and similar applications via adjtime(3), adjtimex(2), 103 /// clock_adjtime(2), and ntp_adjtime(3). This clock normally counts the 104 /// number of seconds since 1970-01-01 00:00:00 Coordinated Universal Time 105 /// (UTC) except that it ignores leap seconds; near a leap second it may be 106 /// adjusted by leap second smearing to stay roughly in sync with UTC. Leap 107 /// second smearing applies frequency adjustments to the clock to speed up 108 /// or slow down the clock to account for the leap second without 109 /// discontinuities in the clock. If leap second smearing is not applied, 110 /// the clock will experience discontinuity around leap second adjustment. 111 pub struct RealTime; 112 113 impl ClockSource for RealTime { 114 const ID: bindings::clockid_t = bindings::CLOCK_REALTIME as bindings::clockid_t; 115 116 fn ktime_get() -> bindings::ktime_t { 117 // SAFETY: It is always safe to call `ktime_get_real()` outside of NMI context. 118 unsafe { bindings::ktime_get_real() } 119 } 120 } 121 122 /// A monotonic that ticks while system is suspended. 123 /// 124 /// A nonsettable system-wide clock that is identical to CLOCK_MONOTONIC, 125 /// except that it also includes any time that the system is suspended. This 126 /// allows applications to get a suspend-aware monotonic clock without 127 /// having to deal with the complications of CLOCK_REALTIME, which may have 128 /// discontinuities if the time is changed using settimeofday(2) or similar. 129 pub struct BootTime; 130 131 impl ClockSource for BootTime { 132 const ID: bindings::clockid_t = bindings::CLOCK_BOOTTIME as bindings::clockid_t; 133 134 fn ktime_get() -> bindings::ktime_t { 135 // SAFETY: It is always safe to call `ktime_get_boottime()` outside of NMI context. 136 unsafe { bindings::ktime_get_boottime() } 137 } 138 } 139 140 /// International Atomic Time. 141 /// 142 /// A system-wide clock derived from wall-clock time but counting leap seconds. 143 /// 144 /// This clock is coupled to CLOCK_REALTIME and will be set when CLOCK_REALTIME is 145 /// set, or when the offset to CLOCK_REALTIME is changed via adjtimex(2). This 146 /// usually happens during boot and **should** not happen during normal operations. 147 /// However, if NTP or another application adjusts CLOCK_REALTIME by leap second 148 /// smearing, this clock will not be precise during leap second smearing. 149 /// 150 /// The acronym TAI refers to International Atomic Time. 151 pub struct Tai; 152 153 impl ClockSource for Tai { 154 const ID: bindings::clockid_t = bindings::CLOCK_TAI as bindings::clockid_t; 155 156 fn ktime_get() -> bindings::ktime_t { 157 // SAFETY: It is always safe to call `ktime_get_tai()` outside of NMI context. 158 unsafe { bindings::ktime_get_clocktai() } 159 } 160 } 161 162 /// A specific point in time. 163 /// 164 /// # Invariants 165 /// 166 /// The `inner` value is in the range from 0 to `KTIME_MAX`. 167 #[repr(transparent)] 168 #[derive(PartialEq, PartialOrd, Eq, Ord)] 169 pub struct Instant<C: ClockSource> { 170 inner: bindings::ktime_t, 171 _c: PhantomData<C>, 172 } 173 174 impl<C: ClockSource> Clone for Instant<C> { 175 fn clone(&self) -> Self { 176 *self 177 } 178 } 179 180 impl<C: ClockSource> Copy for Instant<C> {} 181 182 impl<C: ClockSource> Instant<C> { 183 /// Get the current time from the clock source. 184 #[inline] 185 pub fn now() -> Self { 186 // INVARIANT: The `ClockSource::ktime_get()` function returns a value in the range 187 // from 0 to `KTIME_MAX`. 188 Self { 189 inner: C::ktime_get(), 190 _c: PhantomData, 191 } 192 } 193 194 /// Return the amount of time elapsed since the [`Instant`]. 195 #[inline] 196 pub fn elapsed(&self) -> Delta { 197 Self::now() - *self 198 } 199 200 #[inline] 201 pub(crate) fn as_nanos(&self) -> i64 { 202 self.inner 203 } 204 205 /// Create an [`Instant`] from a `ktime_t` without checking if it is non-negative. 206 /// 207 /// # Panics 208 /// 209 /// On debug builds, this function will panic if `ktime` is not in the range from 0 to 210 /// `KTIME_MAX`. 211 /// 212 /// # Safety 213 /// 214 /// The caller promises that `ktime` is in the range from 0 to `KTIME_MAX`. 215 #[inline] 216 pub(crate) unsafe fn from_ktime(ktime: bindings::ktime_t) -> Self { 217 debug_assert!(ktime >= 0); 218 219 // INVARIANT: Our safety contract ensures that `ktime` is in the range from 0 to 220 // `KTIME_MAX`. 221 Self { 222 inner: ktime, 223 _c: PhantomData, 224 } 225 } 226 } 227 228 impl<C: ClockSource> ops::Sub for Instant<C> { 229 type Output = Delta; 230 231 // By the type invariant, it never overflows. 232 #[inline] 233 fn sub(self, other: Instant<C>) -> Delta { 234 Delta { 235 nanos: self.inner - other.inner, 236 } 237 } 238 } 239 240 impl<T: ClockSource> ops::Add<Delta> for Instant<T> { 241 type Output = Self; 242 243 #[inline] 244 fn add(self, rhs: Delta) -> Self::Output { 245 // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow 246 // (e.g. go above `KTIME_MAX`) 247 let res = self.inner + rhs.nanos; 248 249 // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0 250 #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)] 251 assert!(res >= 0); 252 253 Self { 254 inner: res, 255 _c: PhantomData, 256 } 257 } 258 } 259 260 impl<T: ClockSource> ops::Sub<Delta> for Instant<T> { 261 type Output = Self; 262 263 #[inline] 264 fn sub(self, rhs: Delta) -> Self::Output { 265 // INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow 266 // (e.g. go above `KTIME_MAX`) 267 let res = self.inner - rhs.nanos; 268 269 // INVARIANT: With overflow checks enabled, we verify here that the value is >= 0 270 #[cfg(CONFIG_RUST_OVERFLOW_CHECKS)] 271 assert!(res >= 0); 272 273 Self { 274 inner: res, 275 _c: PhantomData, 276 } 277 } 278 } 279 280 /// A span of time. 281 /// 282 /// This struct represents a span of time, with its value stored as nanoseconds. 283 /// The value can represent any valid i64 value, including negative, zero, and 284 /// positive numbers. 285 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 286 pub struct Delta { 287 nanos: i64, 288 } 289 290 impl ops::Add for Delta { 291 type Output = Self; 292 293 #[inline] 294 fn add(self, rhs: Self) -> Self { 295 Self { 296 nanos: self.nanos + rhs.nanos, 297 } 298 } 299 } 300 301 impl ops::AddAssign for Delta { 302 #[inline] 303 fn add_assign(&mut self, rhs: Self) { 304 self.nanos += rhs.nanos; 305 } 306 } 307 308 impl ops::Sub for Delta { 309 type Output = Self; 310 311 #[inline] 312 fn sub(self, rhs: Self) -> Self::Output { 313 Self { 314 nanos: self.nanos - rhs.nanos, 315 } 316 } 317 } 318 319 impl ops::SubAssign for Delta { 320 #[inline] 321 fn sub_assign(&mut self, rhs: Self) { 322 self.nanos -= rhs.nanos; 323 } 324 } 325 326 impl ops::Mul<i64> for Delta { 327 type Output = Self; 328 329 #[inline] 330 fn mul(self, rhs: i64) -> Self::Output { 331 Self { 332 nanos: self.nanos * rhs, 333 } 334 } 335 } 336 337 impl ops::MulAssign<i64> for Delta { 338 #[inline] 339 fn mul_assign(&mut self, rhs: i64) { 340 self.nanos *= rhs; 341 } 342 } 343 344 impl ops::Div for Delta { 345 type Output = i64; 346 347 #[inline] 348 fn div(self, rhs: Self) -> Self::Output { 349 #[cfg(CONFIG_64BIT)] 350 { 351 self.nanos / rhs.nanos 352 } 353 354 #[cfg(not(CONFIG_64BIT))] 355 { 356 // SAFETY: This function is always safe to call regardless of the input values 357 unsafe { bindings::div64_s64(self.nanos, rhs.nanos) } 358 } 359 } 360 } 361 362 impl Delta { 363 /// A span of time equal to zero. 364 pub const ZERO: Self = Self { nanos: 0 }; 365 366 /// Create a new [`Delta`] from a number of microseconds. 367 /// 368 /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775. 369 /// If `micros` is outside this range, `i64::MIN` is used for negative values, 370 /// and `i64::MAX` is used for positive values due to saturation. 371 #[inline] 372 pub const fn from_micros(micros: i64) -> Self { 373 Self { 374 nanos: micros.saturating_mul(NSEC_PER_USEC), 375 } 376 } 377 378 /// Create a new [`Delta`] from a number of milliseconds. 379 /// 380 /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854. 381 /// If `millis` is outside this range, `i64::MIN` is used for negative values, 382 /// and `i64::MAX` is used for positive values due to saturation. 383 #[inline] 384 pub const fn from_millis(millis: i64) -> Self { 385 Self { 386 nanos: millis.saturating_mul(NSEC_PER_MSEC), 387 } 388 } 389 390 /// Create a new [`Delta`] from a number of seconds. 391 /// 392 /// The `secs` can range from -9_223_372_036 to 9_223_372_036. 393 /// If `secs` is outside this range, `i64::MIN` is used for negative values, 394 /// and `i64::MAX` is used for positive values due to saturation. 395 #[inline] 396 pub const fn from_secs(secs: i64) -> Self { 397 Self { 398 nanos: secs.saturating_mul(NSEC_PER_SEC), 399 } 400 } 401 402 /// Return `true` if the [`Delta`] spans no time. 403 #[inline] 404 pub fn is_zero(self) -> bool { 405 self.as_nanos() == 0 406 } 407 408 /// Return `true` if the [`Delta`] spans a negative amount of time. 409 #[inline] 410 pub fn is_negative(self) -> bool { 411 self.as_nanos() < 0 412 } 413 414 /// Return the number of nanoseconds in the [`Delta`]. 415 #[inline] 416 pub const fn as_nanos(self) -> i64 { 417 self.nanos 418 } 419 420 /// Return the smallest number of microseconds greater than or equal 421 /// to the value in the [`Delta`]. 422 #[inline] 423 pub fn as_micros_ceil(self) -> i64 { 424 #[cfg(CONFIG_64BIT)] 425 { 426 self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC 427 } 428 429 #[cfg(not(CONFIG_64BIT))] 430 // SAFETY: It is always safe to call `ktime_to_us()` with any value. 431 unsafe { 432 bindings::ktime_to_us(self.as_nanos().saturating_add(NSEC_PER_USEC - 1)) 433 } 434 } 435 436 /// Return the number of milliseconds in the [`Delta`]. 437 #[inline] 438 pub fn as_millis(self) -> i64 { 439 #[cfg(CONFIG_64BIT)] 440 { 441 self.as_nanos() / NSEC_PER_MSEC 442 } 443 444 #[cfg(not(CONFIG_64BIT))] 445 // SAFETY: It is always safe to call `ktime_to_ms()` with any value. 446 unsafe { 447 bindings::ktime_to_ms(self.as_nanos()) 448 } 449 } 450 451 /// Return `self % dividend` where `dividend` is in nanoseconds. 452 /// 453 /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit platforms, so this is 454 /// limited to 32 bit dividends. 455 #[inline] 456 pub fn rem_nanos(self, dividend: i32) -> Self { 457 #[cfg(CONFIG_64BIT)] 458 { 459 Self { 460 nanos: self.as_nanos() % i64::from(dividend), 461 } 462 } 463 464 #[cfg(not(CONFIG_64BIT))] 465 { 466 let mut rem = 0; 467 468 // SAFETY: `rem` is in the stack, so we can always provide a valid pointer to it. 469 unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut rem) }; 470 471 Self { 472 nanos: i64::from(rem), 473 } 474 } 475 } 476 } 477