Skip to content

Commit fae0cdc

Browse files
fujitaAndreas Hindborg
authored andcommitted
rust: time: Introduce Delta type
Introduce a type representing a span of time. Define our own type because `core::time::Duration` is large and could panic during creation. time::Ktime could be also used for time duration but timestamp and timedelta are different so better to use a new type. i64 is used instead of u64 to represent a span of time; some C drivers uses negative Deltas and i64 is more compatible with Ktime using i64 too (e.g., ktime_[us|ms]_delta() APIs return i64 so we create Delta object without type conversion. i64 is used instead of bindings::ktime_t because when the ktime_t type is used as timestamp, it represents values from 0 to KTIME_MAX, which is different from Delta. as_millis() method isn't used in this patchset. It's planned to be used in Binder driver. Reviewed-by: Andrew Lunn <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Reviewed-by: Gary Guo <[email protected]> Reviewed-by: Fiona Behrens <[email protected]> Tested-by: Daniel Almeida <[email protected]> Reviewed-by: Andreas Hindborg <[email protected]> Signed-off-by: FUJITA Tomonori <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Andreas Hindborg <[email protected]>
1 parent 3caad57 commit fae0cdc

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

rust/kernel/time.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,15 @@
1010
1111
pub mod hrtimer;
1212

13+
/// The number of nanoseconds per microsecond.
14+
pub const NSEC_PER_USEC: i64 = bindings::NSEC_PER_USEC as i64;
15+
1316
/// The number of nanoseconds per millisecond.
1417
pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64;
1518

19+
/// The number of nanoseconds per second.
20+
pub const NSEC_PER_SEC: i64 = bindings::NSEC_PER_SEC as i64;
21+
1622
/// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
1723
pub type Jiffies = crate::ffi::c_ulong;
1824

@@ -149,3 +155,85 @@ impl ClockId {
149155
self as bindings::clockid_t
150156
}
151157
}
158+
159+
/// A span of time.
160+
///
161+
/// This struct represents a span of time, with its value stored as nanoseconds.
162+
/// The value can represent any valid i64 value, including negative, zero, and
163+
/// positive numbers.
164+
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
165+
pub struct Delta {
166+
nanos: i64,
167+
}
168+
169+
impl Delta {
170+
/// A span of time equal to zero.
171+
pub const ZERO: Self = Self { nanos: 0 };
172+
173+
/// Create a new [`Delta`] from a number of microseconds.
174+
///
175+
/// The `micros` can range from -9_223_372_036_854_775 to 9_223_372_036_854_775.
176+
/// If `micros` is outside this range, `i64::MIN` is used for negative values,
177+
/// and `i64::MAX` is used for positive values due to saturation.
178+
#[inline]
179+
pub const fn from_micros(micros: i64) -> Self {
180+
Self {
181+
nanos: micros.saturating_mul(NSEC_PER_USEC),
182+
}
183+
}
184+
185+
/// Create a new [`Delta`] from a number of milliseconds.
186+
///
187+
/// The `millis` can range from -9_223_372_036_854 to 9_223_372_036_854.
188+
/// If `millis` is outside this range, `i64::MIN` is used for negative values,
189+
/// and `i64::MAX` is used for positive values due to saturation.
190+
#[inline]
191+
pub const fn from_millis(millis: i64) -> Self {
192+
Self {
193+
nanos: millis.saturating_mul(NSEC_PER_MSEC),
194+
}
195+
}
196+
197+
/// Create a new [`Delta`] from a number of seconds.
198+
///
199+
/// The `secs` can range from -9_223_372_036 to 9_223_372_036.
200+
/// If `secs` is outside this range, `i64::MIN` is used for negative values,
201+
/// and `i64::MAX` is used for positive values due to saturation.
202+
#[inline]
203+
pub const fn from_secs(secs: i64) -> Self {
204+
Self {
205+
nanos: secs.saturating_mul(NSEC_PER_SEC),
206+
}
207+
}
208+
209+
/// Return `true` if the [`Delta`] spans no time.
210+
#[inline]
211+
pub fn is_zero(self) -> bool {
212+
self.as_nanos() == 0
213+
}
214+
215+
/// Return `true` if the [`Delta`] spans a negative amount of time.
216+
#[inline]
217+
pub fn is_negative(self) -> bool {
218+
self.as_nanos() < 0
219+
}
220+
221+
/// Return the number of nanoseconds in the [`Delta`].
222+
#[inline]
223+
pub const fn as_nanos(self) -> i64 {
224+
self.nanos
225+
}
226+
227+
/// Return the smallest number of microseconds greater than or equal
228+
/// to the value in the [`Delta`].
229+
#[inline]
230+
pub const fn as_micros_ceil(self) -> i64 {
231+
self.as_nanos().saturating_add(NSEC_PER_USEC - 1) / NSEC_PER_USEC
232+
}
233+
234+
/// Return the number of milliseconds in the [`Delta`].
235+
#[inline]
236+
pub const fn as_millis(self) -> i64 {
237+
self.as_nanos() / NSEC_PER_MSEC
238+
}
239+
}

0 commit comments

Comments
 (0)