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 205 impl<C: ClockSource> core::ops::Sub for Instant<C> { 206 type Output = Delta; 207 208 // By the type invariant, it never overflows. 209 #[inline] 210 fn sub(self, other: Instant<C>) -> Delta { 211 Delta { 212 nanos: self.inner - other.inner, 213 } 214 } 215 } 216 217 /// A span of time. 218 /// 219 /// This struct represents a span of time, with its value stored as nanoseconds. 220 /// The value can represent any valid i64 value, including negative, zero, and 221 /// positive numbers. 222 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 223 pub struct Delta { 224 nanos: i64, 225 } 226 227 impl Delta { 228 /// A span of time equal to zero. 229 pub const ZERO: Self = Self { nanos: 0 }; 230 231 /// Create a new [`Delta`] from a number of microseconds. 232 /// 233 /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775. 234 /// If `micros` is outside this range, `i64::MIN` is used for negative values, 235 /// and `i64::MAX` is used for positive values due to saturation. 236 #[inline] 237 pub const fn from_micros(micros: i64) -> Self { 238 Self { 239 nanos: micros.saturating_mul(NSEC_PER_USEC), 240 } 241 } 242 243 /// Create a new [`Delta`] from a number of milliseconds. 244 /// 245 /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854. 246 /// If `millis` is outside this range, `i64::MIN` is used for negative values, 247 /// and `i64::MAX` is used for positive values due to saturation. 248 #[inline] 249 pub const fn from_millis(millis: i64) -> Self { 250 Self { 251 nanos: millis.saturating_mul(NSEC_PER_MSEC), 252 } 253 } 254 255 /// Create a new [`Delta`] from a number of seconds. 256 /// 257 /// The `secs` can range from -9_223_372_036 to 9_223_372_036. 258 /// If `secs` is outside this range, `i64::MIN` is used for negative values, 259 /// and `i64::MAX` is used for positive values due to saturation. 260 #[inline] 261 pub const fn from_secs(secs: i64) -> Self { 262 Self { 263 nanos: secs.saturating_mul(NSEC_PER_SEC), 264 } 265 } 266 267 /// Return `true` if the [`Delta`] spans no time. 268 #[inline] 269 pub fn is_zero(self) -> bool { 270 self.as_nanos() == 0 271 } 272 273 /// Return `true` if the [`Delta`] spans a negative amount of time. 274 #[inline] 275 pub fn is_negative(self) -> bool { 276 self.as_nanos() < 0 277 } 278 279 /// Return the number of nanoseconds in the [`Delta`]. 280 #[inline] 281 pub const fn as_nanos(self) -> i64 { 282 self.nanos 283 } 284 285 /// Return the smallest number of microseconds greater than or equal 286 /// to the value in the [`Delta`]. 287 #[inline] 288 pub fn as_micros_ceil(self) -> i64 { 289 #[cfg(CONFIG_64BIT)] 290 { 291 self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC 292 } 293 294 #[cfg(not(CONFIG_64BIT))] 295 // SAFETY: It is always safe to call `ktime_to_us()` with any value. 296 unsafe { 297 bindings::ktime_to_us(self.as_nanos().saturating_add(NSEC_PER_USEC - 1)) 298 } 299 } 300 301 /// Return the number of milliseconds in the [`Delta`]. 302 #[inline] 303 pub fn as_millis(self) -> i64 { 304 #[cfg(CONFIG_64BIT)] 305 { 306 self.as_nanos() / NSEC_PER_MSEC 307 } 308 309 #[cfg(not(CONFIG_64BIT))] 310 // SAFETY: It is always safe to call `ktime_to_ms()` with any value. 311 unsafe { 312 bindings::ktime_to_ms(self.as_nanos()) 313 } 314 } 315 } 316