55//! This module contains the kernel APIs related to time and timers that
66//! have been ported or wrapped for usage by Rust code in the kernel.
77//!
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+ //!
824//! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h).
925//! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h).
1026
1127pub mod hrtimer;
1228
29+ /// The number of nanoseconds per microsecond.
30+ pub const NSEC_PER_USEC : i64 = bindings:: NSEC_PER_USEC as i64 ;
31+
1332/// The number of nanoseconds per millisecond.
1433pub const NSEC_PER_MSEC : i64 = bindings:: NSEC_PER_MSEC as i64 ;
1534
35+ /// The number of nanoseconds per second.
36+ pub const NSEC_PER_SEC : i64 = bindings:: NSEC_PER_SEC as i64 ;
37+
1638/// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
1739pub type Jiffies = crate :: ffi:: c_ulong ;
1840
@@ -27,59 +49,44 @@ pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
2749 unsafe { bindings:: __msecs_to_jiffies ( msecs) }
2850}
2951
30- /// A Rust wrapper around a `ktime_t`.
52+ /// A specific point in time.
53+ ///
54+ /// # Invariants
55+ ///
56+ /// The `inner` value is in the range from 0 to `KTIME_MAX`.
3157#[ repr( transparent) ]
32- #[ derive( Copy , Clone ) ]
33- pub struct Ktime {
58+ #[ derive( Copy , Clone , PartialEq , PartialOrd , Eq , Ord ) ]
59+ pub struct Instant {
3460 inner : bindings:: ktime_t ,
3561}
3662
37- impl Ktime {
38- /// Create a `Ktime` from a raw `ktime_t`.
39- #[ inline]
40- pub fn from_raw ( inner : bindings:: ktime_t ) -> Self {
41- Self { inner }
42- }
43-
63+ impl Instant {
4464 /// Get the current time using `CLOCK_MONOTONIC`.
4565 #[ inline]
46- pub fn ktime_get ( ) -> Self {
47- // SAFETY: It is always safe to call `ktime_get` outside of NMI context.
48- Self :: from_raw ( unsafe { bindings:: ktime_get ( ) } )
49- }
50-
51- /// Divide the number of nanoseconds by a compile-time constant.
52- #[ inline]
53- fn divns_constant < const DIV : i64 > ( self ) -> i64 {
54- self . to_ns ( ) / DIV
55- }
56-
57- /// Returns the number of nanoseconds.
58- #[ inline]
59- pub fn to_ns ( self ) -> i64 {
60- self . inner
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+ }
6173 }
6274
63- /// Returns the number of milliseconds .
75+ /// Return the amount of time elapsed since the [`Instant`] .
6476 #[ inline]
65- pub fn to_ms ( self ) -> i64 {
66- self . divns_constant :: < NSEC_PER_MSEC > ( )
77+ pub fn elapsed ( & self ) -> Delta {
78+ Self :: now ( ) - * self
6779 }
6880}
6981
70- /// Returns the number of milliseconds between two ktimes.
71- #[ inline]
72- pub fn ktime_ms_delta ( later : Ktime , earlier : Ktime ) -> i64 {
73- ( later - earlier) . to_ms ( )
74- }
75-
76- impl core:: ops:: Sub for Ktime {
77- type Output = Ktime ;
82+ impl core:: ops:: Sub for Instant {
83+ type Output = Delta ;
7884
85+ // By the type invariant, it never overflows.
7986 #[ inline]
80- fn sub ( self , other : Ktime ) -> Ktime {
81- Self {
82- inner : self . inner - other. inner ,
87+ fn sub ( self , other : Instant ) -> Delta {
88+ Delta {
89+ nanos : self . inner - other. inner ,
8390 }
8491 }
8592}
@@ -149,3 +156,85 @@ impl ClockId {
149156 self as bindings:: clockid_t
150157 }
151158}
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+ }
0 commit comments