5
5
//! This module contains the kernel APIs related to time and timers that
6
6
//! have been ported or wrapped for usage by Rust code in the kernel.
7
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
+ //!
8
24
//! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h).
9
25
//! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h).
10
26
11
27
pub mod hrtimer;
12
28
29
+ /// The number of nanoseconds per microsecond.
30
+ pub const NSEC_PER_USEC : i64 = bindings:: NSEC_PER_USEC as i64 ;
31
+
13
32
/// The number of nanoseconds per millisecond.
14
33
pub const NSEC_PER_MSEC : i64 = bindings:: NSEC_PER_MSEC as i64 ;
15
34
35
+ /// The number of nanoseconds per second.
36
+ pub const NSEC_PER_SEC : i64 = bindings:: NSEC_PER_SEC as i64 ;
37
+
16
38
/// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
17
39
pub type Jiffies = crate :: ffi:: c_ulong ;
18
40
@@ -27,59 +49,44 @@ pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
27
49
unsafe { bindings:: __msecs_to_jiffies ( msecs) }
28
50
}
29
51
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`.
31
57
#[ repr( transparent) ]
32
- #[ derive( Copy , Clone ) ]
33
- pub struct Ktime {
58
+ #[ derive( Copy , Clone , PartialEq , PartialOrd , Eq , Ord ) ]
59
+ pub struct Instant {
34
60
inner : bindings:: ktime_t ,
35
61
}
36
62
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 {
44
64
/// Get the current time using `CLOCK_MONOTONIC`.
45
65
#[ 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
+ }
61
73
}
62
74
63
- /// Returns the number of milliseconds .
75
+ /// Return the amount of time elapsed since the [`Instant`] .
64
76
#[ 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
67
79
}
68
80
}
69
81
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 ;
78
84
85
+ // By the type invariant, it never overflows.
79
86
#[ 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 ,
83
90
}
84
91
}
85
92
}
@@ -149,3 +156,85 @@ impl ClockId {
149
156
self as bindings:: clockid_t
150
157
}
151
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
+ }
0 commit comments