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 29 pub mod delay; 30 pub mod hrtimer; 31 32 /// The number of nanoseconds per microsecond. 33 pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64; 34 35 /// The number of nanoseconds per millisecond. 36 pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64; 37 38 /// The number of nanoseconds per second. 39 pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64; 40 41 /// The time unit of Linux kernel. One jiffy equals (1/HZ) second. 42 pub type Jiffies = crate::ffi::c_ulong; 43 44 /// The millisecond time unit. 45 pub type Msecs = crate::ffi::c_uint; 46 47 /// Converts milliseconds to jiffies. 48 #[inline] 49 pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies { 50 // SAFETY: The `__msecs_to_jiffies` function is always safe to call no 51 // matter what the argument is. 52 unsafe { bindings::__msecs_to_jiffies(msecs) } 53 } 54 55 /// Trait for clock sources. 56 /// 57 /// Selection of the clock source depends on the use case. In some cases the usage of a 58 /// particular clock is mandatory, e.g. in network protocols, filesystems. In other 59 /// cases the user of the clock has to decide which clock is best suited for the 60 /// purpose. In most scenarios clock [`Monotonic`] is the best choice as it 61 /// provides a accurate monotonic notion of time (leap second smearing ignored). 62 pub trait ClockSource { 63 /// The kernel clock ID associated with this clock source. 64 /// 65 /// This constant corresponds to the C side `clockid_t` value. 66 const ID: bindings::clockid_t; 67 68 /// Get the current time from the clock source. 69 /// 70 /// The function must return a value in the range from 0 to `KTIME_MAX`. 71 fn ktime_get() -> bindings::ktime_t; 72 } 73 74 /// A monotonically increasing clock. 75 /// 76 /// A nonsettable system-wide clock that represents monotonic time since as 77 /// described by POSIX, "some unspecified point in the past". On Linux, that 78 /// point corresponds to the number of seconds that the system has been 79 /// running since it was booted. 80 /// 81 /// The CLOCK_MONOTONIC clock is not affected by discontinuous jumps in the 82 /// CLOCK_REAL (e.g., if the system administrator manually changes the 83 /// clock), but is affected by frequency adjustments. This clock does not 84 /// count time that the system is suspended. 85 pub struct Monotonic; 86 87 impl ClockSource for Monotonic { 88 const ID: bindings::clockid_t = bindings::CLOCK_MONOTONIC as bindings::clockid_t; 89 90 fn ktime_get() -> bindings::ktime_t { 91 // SAFETY: It is always safe to call `ktime_get()` outside of NMI context. 92 unsafe { bindings::ktime_get() } 93 } 94 } 95 96 /// A settable system-wide clock that measures real (i.e., wall-clock) time. 97 /// 98 /// Setting this clock requires appropriate privileges. This clock is 99 /// affected by discontinuous jumps in the system time (e.g., if the system 100 /// administrator manually changes the clock), and by frequency adjustments 101 /// performed by NTP and similar applications via adjtime(3), adjtimex(2), 102 /// clock_adjtime(2), and ntp_adjtime(3). This clock normally counts the 103 /// number of seconds since 1970-01-01 00:00:00 Coordinated Universal Time 104 /// (UTC) except that it ignores leap seconds; near a leap second it may be 105 /// adjusted by leap second smearing to stay roughly in sync with UTC. Leap 106 /// second smearing applies frequency adjustments to the clock to speed up 107 /// or slow down the clock to account for the leap second without 108 /// discontinuities in the clock. If leap second smearing is not applied, 109 /// the clock will experience discontinuity around leap second adjustment. 110 pub struct RealTime; 111 112 impl ClockSource for RealTime { 113 const ID: bindings::clockid_t = bindings::CLOCK_REALTIME as bindings::clockid_t; 114 115 fn ktime_get() -> bindings::ktime_t { 116 // SAFETY: It is always safe to call `ktime_get_real()` outside of NMI context. 117 unsafe { bindings::ktime_get_real() } 118 } 119 } 120 121 /// A monotonic that ticks while system is suspended. 122 /// 123 /// A nonsettable system-wide clock that is identical to CLOCK_MONOTONIC, 124 /// except that it also includes any time that the system is suspended. This 125 /// allows applications to get a suspend-aware monotonic clock without 126 /// having to deal with the complications of CLOCK_REALTIME, which may have 127 /// discontinuities if the time is changed using settimeofday(2) or similar. 128 pub struct BootTime; 129 130 impl ClockSource for BootTime { 131 const ID: bindings::clockid_t = bindings::CLOCK_BOOTTIME as bindings::clockid_t; 132 133 fn ktime_get() -> bindings::ktime_t { 134 // SAFETY: It is always safe to call `ktime_get_boottime()` outside of NMI context. 135 unsafe { bindings::ktime_get_boottime() } 136 } 137 } 138 139 /// International Atomic Time. 140 /// 141 /// A system-wide clock derived from wall-clock time but counting leap seconds. 142 /// 143 /// This clock is coupled to CLOCK_REALTIME and will be set when CLOCK_REALTIME is 144 /// set, or when the offset to CLOCK_REALTIME is changed via adjtimex(2). This 145 /// usually happens during boot and **should** not happen during normal operations. 146 /// However, if NTP or another application adjusts CLOCK_REALTIME by leap second 147 /// smearing, this clock will not be precise during leap second smearing. 148 /// 149 /// The acronym TAI refers to International Atomic Time. 150 pub struct Tai; 151 152 impl ClockSource for Tai { 153 const ID: bindings::clockid_t = bindings::CLOCK_TAI as bindings::clockid_t; 154 155 fn ktime_get() -> bindings::ktime_t { 156 // SAFETY: It is always safe to call `ktime_get_tai()` outside of NMI context. 157 unsafe { bindings::ktime_get_clocktai() } 158 } 159 } 160 161 /// A specific point in time. 162 /// 163 /// # Invariants 164 /// 165 /// The `inner` value is in the range from 0 to `KTIME_MAX`. 166 #[repr(transparent)] 167 #[derive(PartialEq, PartialOrd, Eq, Ord)] 168 pub struct Instant<C: ClockSource> { 169 inner: bindings::ktime_t, 170 _c: PhantomData<C>, 171 } 172 173 impl<C: ClockSource> Clone for Instant<C> { 174 fn clone(&self) -> Self { 175 *self 176 } 177 } 178 179 impl<C: ClockSource> Copy for Instant<C> {} 180 181 impl<C: ClockSource> Instant<C> { 182 /// Get the current time from the clock source. 183 #[inline] 184 pub fn now() -> Self { 185 // INVARIANT: The `ClockSource::ktime_get()` function returns a value in the range 186 // from 0 to `KTIME_MAX`. 187 Self { 188 inner: C::ktime_get(), 189 _c: PhantomData, 190 } 191 } 192 193 /// Return the amount of time elapsed since the [`Instant`]. 194 #[inline] 195 pub fn elapsed(&self) -> Delta { 196 Self::now() - *self 197 } 198 199 #[inline] 200 pub(crate) fn as_nanos(&self) -> i64 { 201 self.inner 202 } 203 204 /// Create an [`Instant`] from a `ktime_t` without checking if it is non-negative. 205 /// 206 /// # Panics 207 /// 208 /// On debug builds, this function will panic if `ktime` is not in the range from 0 to 209 /// `KTIME_MAX`. 210 /// 211 /// # Safety 212 /// 213 /// The caller promises that `ktime` is in the range from 0 to `KTIME_MAX`. 214 #[inline] 215 pub(crate) unsafe fn from_ktime(ktime: bindings::ktime_t) -> Self { 216 debug_assert!(ktime >= 0); 217 218 // INVARIANT: Our safety contract ensures that `ktime` is in the range from 0 to 219 // `KTIME_MAX`. 220 Self { 221 inner: ktime, 222 _c: PhantomData, 223 } 224 } 225 } 226 227 impl<C: ClockSource> core::ops::Sub for Instant<C> { 228 type Output = Delta; 229 230 // By the type invariant, it never overflows. 231 #[inline] 232 fn sub(self, other: Instant<C>) -> Delta { 233 Delta { 234 nanos: self.inner - other.inner, 235 } 236 } 237 } 238 239 /// A span of time. 240 /// 241 /// This struct represents a span of time, with its value stored as nanoseconds. 242 /// The value can represent any valid i64 value, including negative, zero, and 243 /// positive numbers. 244 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 245 pub struct Delta { 246 nanos: i64, 247 } 248 249 impl Delta { 250 /// A span of time equal to zero. 251 pub const ZERO: Self = Self { nanos: 0 }; 252 253 /// Create a new [`Delta`] from a number of microseconds. 254 /// 255 /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775. 256 /// If `micros` is outside this range, `i64::MIN` is used for negative values, 257 /// and `i64::MAX` is used for positive values due to saturation. 258 #[inline] 259 pub const fn from_micros(micros: i64) -> Self { 260 Self { 261 nanos: micros.saturating_mul(NSEC_PER_USEC), 262 } 263 } 264 265 /// Create a new [`Delta`] from a number of milliseconds. 266 /// 267 /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854. 268 /// If `millis` is outside this range, `i64::MIN` is used for negative values, 269 /// and `i64::MAX` is used for positive values due to saturation. 270 #[inline] 271 pub const fn from_millis(millis: i64) -> Self { 272 Self { 273 nanos: millis.saturating_mul(NSEC_PER_MSEC), 274 } 275 } 276 277 /// Create a new [`Delta`] from a number of seconds. 278 /// 279 /// The `secs` can range from -9_223_372_036 to 9_223_372_036. 280 /// If `secs` is outside this range, `i64::MIN` is used for negative values, 281 /// and `i64::MAX` is used for positive values due to saturation. 282 #[inline] 283 pub const fn from_secs(secs: i64) -> Self { 284 Self { 285 nanos: secs.saturating_mul(NSEC_PER_SEC), 286 } 287 } 288 289 /// Return `true` if the [`Delta`] spans no time. 290 #[inline] 291 pub fn is_zero(self) -> bool { 292 self.as_nanos() == 0 293 } 294 295 /// Return `true` if the [`Delta`] spans a negative amount of time. 296 #[inline] 297 pub fn is_negative(self) -> bool { 298 self.as_nanos() < 0 299 } 300 301 /// Return the number of nanoseconds in the [`Delta`]. 302 #[inline] 303 pub const fn as_nanos(self) -> i64 { 304 self.nanos 305 } 306 307 /// Return the smallest number of microseconds greater than or equal 308 /// to the value in the [`Delta`]. 309 #[inline] 310 pub fn as_micros_ceil(self) -> i64 { 311 #[cfg(CONFIG_64BIT)] 312 { 313 self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC 314 } 315 316 #[cfg(not(CONFIG_64BIT))] 317 // SAFETY: It is always safe to call `ktime_to_us()` with any value. 318 unsafe { 319 bindings::ktime_to_us(self.as_nanos().saturating_add(NSEC_PER_USEC - 1)) 320 } 321 } 322 323 /// Return the number of milliseconds in the [`Delta`]. 324 #[inline] 325 pub fn as_millis(self) -> i64 { 326 #[cfg(CONFIG_64BIT)] 327 { 328 self.as_nanos() / NSEC_PER_MSEC 329 } 330 331 #[cfg(not(CONFIG_64BIT))] 332 // SAFETY: It is always safe to call `ktime_to_ms()` with any value. 333 unsafe { 334 bindings::ktime_to_ms(self.as_nanos()) 335 } 336 } 337 } 338