2424//! C header: [`include/linux/jiffies.h`](srctree/include/linux/jiffies.h).
2525//! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h).
2626
27+ use core:: marker:: PhantomData ;
28+
29+ pub mod delay;
2730pub mod hrtimer;
2831
2932/// The number of nanoseconds per microsecond.
@@ -49,26 +52,141 @@ pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies {
4952 unsafe { bindings:: __msecs_to_jiffies ( msecs) }
5053}
5154
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+
52161/// A specific point in time.
53162///
54163/// # Invariants
55164///
56165/// The `inner` value is in the range from 0 to `KTIME_MAX`.
57166#[ repr( transparent) ]
58- #[ derive( Copy , Clone , PartialEq , PartialOrd , Eq , Ord ) ]
59- pub struct Instant {
167+ #[ derive( PartialEq , PartialOrd , Eq , Ord ) ]
168+ pub struct Instant < C : ClockSource > {
60169 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+ }
61177}
62178
63- impl Instant {
64- /// Get the current time using `CLOCK_MONOTONIC`.
179+ impl < C : ClockSource > Copy for Instant < C > { }
180+
181+ impl < C : ClockSource > Instant < C > {
182+ /// Get the current time from the clock source.
65183 #[ inline]
66184 pub fn now ( ) -> Self {
67- // INVARIANT: The `ktime_get()` function returns a value in the range
185+ // INVARIANT: The `ClockSource:: ktime_get()` function returns a value in the range
68186 // from 0 to `KTIME_MAX`.
69187 Self {
70- // SAFETY: It is always safe to call ` ktime_get()` outside of NMI context.
71- inner : unsafe { bindings :: ktime_get ( ) } ,
188+ inner : C :: ktime_get ( ) ,
189+ _c : PhantomData ,
72190 }
73191 }
74192
@@ -77,86 +195,25 @@ impl Instant {
77195 pub fn elapsed ( & self ) -> Delta {
78196 Self :: now ( ) - * self
79197 }
198+
199+ #[ inline]
200+ pub ( crate ) fn as_nanos ( & self ) -> i64 {
201+ self . inner
202+ }
80203}
81204
82- impl core:: ops:: Sub for Instant {
205+ impl < C : ClockSource > core:: ops:: Sub for Instant < C > {
83206 type Output = Delta ;
84207
85208 // By the type invariant, it never overflows.
86209 #[ inline]
87- fn sub ( self , other : Instant ) -> Delta {
210+ fn sub ( self , other : Instant < C > ) -> Delta {
88211 Delta {
89212 nanos : self . inner - other. inner ,
90213 }
91214 }
92215}
93216
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-
160217/// A span of time.
161218///
162219/// This struct represents a span of time, with its value stored as nanoseconds.
@@ -228,13 +285,31 @@ impl Delta {
228285 /// Return the smallest number of microseconds greater than or equal
229286 /// to the value in the [`Delta`].
230287 #[ inline]
231- pub const fn as_micros_ceil ( self ) -> i64 {
232- self . as_nanos ( ) . saturating_add ( NSEC_PER_USEC - 1 ) / NSEC_PER_USEC
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+ }
233299 }
234300
235301 /// Return the number of milliseconds in the [`Delta`].
236302 #[ inline]
237- pub const fn as_millis ( self ) -> i64 {
238- self . as_nanos ( ) / NSEC_PER_MSEC
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+ }
239314 }
240315}
0 commit comments