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