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 /// A specific point in time. 53 /// 54 /// # Invariants 55 /// 56 /// The `inner` value is in the range from 0 to `KTIME_MAX`. 57 #[repr(transparent)] 58 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] 59 pub struct Instant { 60 inner: bindings::ktime_t, 61 } 62 63 impl Instant { 64 /// Get the current time using `CLOCK_MONOTONIC`. 65 #[inline] 66 pub fn now() -> Self { 67 // INVARIANT: The `ktime_get()` function returns a value in the range 68 // from 0 to `KTIME_MAX`. 69 Self { 70 // SAFETY: It is always safe to call `ktime_get()` outside of NMI context. 71 inner: unsafe { bindings::ktime_get() }, 72 } 73 } 74 75 /// Return the amount of time elapsed since the [`Instant`]. 76 #[inline] 77 pub fn elapsed(&self) -> Delta { 78 Self::now() - *self 79 } 80 } 81 82 impl core::ops::Sub for Instant { 83 type Output = Delta; 84 85 // By the type invariant, it never overflows. 86 #[inline] 87 fn sub(self, other: Instant) -> Delta { 88 Delta { 89 nanos: self.inner - other.inner, 90 } 91 } 92 } 93 94 /// An identifier for a clock. Used when specifying clock sources. 95 /// 96 /// 97 /// Selection of the clock depends on the use case. In some cases the usage of a 98 /// particular clock is mandatory, e.g. in network protocols, filesystems.In other 99 /// cases the user of the clock has to decide which clock is best suited for the 100 /// purpose. In most scenarios clock [`ClockId::Monotonic`] is the best choice as it 101 /// provides a accurate monotonic notion of time (leap second smearing ignored). 102 #[derive(Clone, Copy, PartialEq, Eq, Debug)] 103 #[repr(u32)] 104 pub enum ClockId { 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 RealTime = bindings::CLOCK_REALTIME, 120 /// A monotonically increasing clock. 121 /// 122 /// A nonsettable system-wide clock that represents monotonic time since—as 123 /// described by POSIX—"some unspecified point in the past". On Linux, that 124 /// point corresponds to the number of seconds that the system has been 125 /// running since it was booted. 126 /// 127 /// The CLOCK_MONOTONIC clock is not affected by discontinuous jumps in the 128 /// CLOCK_REAL (e.g., if the system administrator manually changes the 129 /// clock), but is affected by frequency adjustments. This clock does not 130 /// count time that the system is suspended. 131 Monotonic = bindings::CLOCK_MONOTONIC, 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 BootTime = bindings::CLOCK_BOOTTIME, 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 TAI = bindings::CLOCK_TAI, 152 } 153 154 impl ClockId { 155 fn into_c(self) -> bindings::clockid_t { 156 self as bindings::clockid_t 157 } 158 } 159 160 /// A span of time. 161 /// 162 /// This struct represents a span of time, with its value stored as nanoseconds. 163 /// The value can represent any valid i64 value, including negative, zero, and 164 /// positive numbers. 165 #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] 166 pub struct Delta { 167 nanos: i64, 168 } 169 170 impl Delta { 171 /// A span of time equal to zero. 172 pub const ZERO: Self = Self { nanos: 0 }; 173 174 /// Create a new [`Delta`] from a number of microseconds. 175 /// 176 /// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775. 177 /// If `micros` is outside this range, `i64::MIN` is used for negative values, 178 /// and `i64::MAX` is used for positive values due to saturation. 179 #[inline] 180 pub const fn from_micros(micros: i64) -> Self { 181 Self { 182 nanos: micros.saturating_mul(NSEC_PER_USEC), 183 } 184 } 185 186 /// Create a new [`Delta`] from a number of milliseconds. 187 /// 188 /// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854. 189 /// If `millis` is outside this range, `i64::MIN` is used for negative values, 190 /// and `i64::MAX` is used for positive values due to saturation. 191 #[inline] 192 pub const fn from_millis(millis: i64) -> Self { 193 Self { 194 nanos: millis.saturating_mul(NSEC_PER_MSEC), 195 } 196 } 197 198 /// Create a new [`Delta`] from a number of seconds. 199 /// 200 /// The `secs` can range from -9_223_372_036 to 9_223_372_036. 201 /// If `secs` is outside this range, `i64::MIN` is used for negative values, 202 /// and `i64::MAX` is used for positive values due to saturation. 203 #[inline] 204 pub const fn from_secs(secs: i64) -> Self { 205 Self { 206 nanos: secs.saturating_mul(NSEC_PER_SEC), 207 } 208 } 209 210 /// Return `true` if the [`Delta`] spans no time. 211 #[inline] 212 pub fn is_zero(self) -> bool { 213 self.as_nanos() == 0 214 } 215 216 /// Return `true` if the [`Delta`] spans a negative amount of time. 217 #[inline] 218 pub fn is_negative(self) -> bool { 219 self.as_nanos() < 0 220 } 221 222 /// Return the number of nanoseconds in the [`Delta`]. 223 #[inline] 224 pub const fn as_nanos(self) -> i64 { 225 self.nanos 226 } 227 228 /// Return the smallest number of microseconds greater than or equal 229 /// to the value in the [`Delta`]. 230 #[inline] 231 pub const fn as_micros_ceil(self) -> i64 { 232 self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC 233 } 234 235 /// Return the number of milliseconds in the [`Delta`]. 236 #[inline] 237 pub const fn as_millis(self) -> i64 { 238 self.as_nanos() / NSEC_PER_MSEC 239 } 240 } 241