Skip to content

Commit 22b65a4

Browse files
LyudeAndreas Hindborg
authored andcommitted
rust: time: Implement Add<Delta>/Sub<Delta> for Instant
In order to copy the behavior rust currently follows for basic arithmetic operations and panic if the result of an addition or subtraction results in a value that would violate the invariants of Instant, but only if the kernel has overflow checking for rust enabled. Signed-off-by: Lyude Paul <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Reviewed-by: FUJITA Tomonori <[email protected]> Reviewed-by: Andreas Hindborg <[email protected]> Reviewed-by: Daniel Almeida <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Andreas Hindborg <[email protected]>
1 parent 4b01474 commit 22b65a4

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

rust/kernel/time.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
//! C header: [`include/linux/ktime.h`](srctree/include/linux/ktime.h).
2626
2727
use core::marker::PhantomData;
28+
use core::ops;
2829

2930
pub mod delay;
3031
pub mod hrtimer;
@@ -224,7 +225,7 @@ impl<C: ClockSource> Instant<C> {
224225
}
225226
}
226227

227-
impl<C: ClockSource> core::ops::Sub for Instant<C> {
228+
impl<C: ClockSource> ops::Sub for Instant<C> {
228229
type Output = Delta;
229230

230231
// By the type invariant, it never overflows.
@@ -236,6 +237,46 @@ impl<C: ClockSource> core::ops::Sub for Instant<C> {
236237
}
237238
}
238239

240+
impl<T: ClockSource> ops::Add<Delta> for Instant<T> {
241+
type Output = Self;
242+
243+
#[inline]
244+
fn add(self, rhs: Delta) -> Self::Output {
245+
// INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
246+
// (e.g. go above `KTIME_MAX`)
247+
let res = self.inner + rhs.nanos;
248+
249+
// INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
250+
#[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
251+
assert!(res >= 0);
252+
253+
Self {
254+
inner: res,
255+
_c: PhantomData,
256+
}
257+
}
258+
}
259+
260+
impl<T: ClockSource> ops::Sub<Delta> for Instant<T> {
261+
type Output = Self;
262+
263+
#[inline]
264+
fn sub(self, rhs: Delta) -> Self::Output {
265+
// INVARIANT: With arithmetic over/underflow checks enabled, this will panic if we overflow
266+
// (e.g. go above `KTIME_MAX`)
267+
let res = self.inner - rhs.nanos;
268+
269+
// INVARIANT: With overflow checks enabled, we verify here that the value is >= 0
270+
#[cfg(CONFIG_RUST_OVERFLOW_CHECKS)]
271+
assert!(res >= 0);
272+
273+
Self {
274+
inner: res,
275+
_c: PhantomData,
276+
}
277+
}
278+
}
279+
239280
/// A span of time.
240281
///
241282
/// This struct represents a span of time, with its value stored as nanoseconds.

0 commit comments

Comments
 (0)