History

rust: time: Add Ktime

Introduce a wrapper around `ktime_t` with a few different useful methods. Rust Binder will use these bindings to compute how many milliseconds a transaction has been active for when dumping the current state of the Binder driver. This replicates the logic in C Binder [1]. For a usage example in Rust Binder, see [2]. ktime_get() cannot be safely called in NMI context. This requirement is not checked by these abstractions, but it is intended that klint [3] or a similar tool will be used to check it in the future.

Alice Ryhl committed 2 years ago

Commit 48b7f4d1 parent 8ff1e6c1 file · +60 −0Browse files

Unified · Split

rust/kernel/time.rs+60−0
@@ -5,6 +5,9 @@ · 4 unmodified lines
5//! This module contains the kernel APIs related to time and timers that5//! This module contains the kernel APIs related to time and timers that
6//! have been ported or wrapped for usage by Rust code in the kernel.6//! have been ported or wrapped for usage by Rust code in the kernel.
7 7
8/// The number of nanoseconds per millisecond.
9pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64;
10
8/// The time unit of Linux kernel. One jiffy equals (1/HZ) second.11/// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
9pub type Jiffies = core::ffi::c_ulong;12pub type Jiffies = core::ffi::c_ulong;
10 13
@@ -18,3 +21,60 @@ pub fn msecs_to_jiffies(msecs: Msecs) -> Jiffies { · 7 unmodified lines
18 // matter what the argument is.21 // matter what the argument is.
19 unsafe { bindings::__msecs_to_jiffies(msecs) }22 unsafe { bindings::__msecs_to_jiffies(msecs) }
20}23}
24
25/// A Rust wrapper around a `ktime_t`.
26#[repr(transparent)]
27#[derive(Copy, Clone)]
28pub struct Ktime {
29 inner: bindings::ktime_t,
30}
31
32impl Ktime {
33 /// Create a `Ktime` from a raw `ktime_t`.
34 #[inline]
35 pub fn from_raw(inner: bindings::ktime_t) -> Self {
36 Self { inner }
37 }
38
39 /// Get the current time using `CLOCK_MONOTONIC`.
40 #[inline]
41 pub fn ktime_get() -> Self {
42 // SAFETY: It is always safe to call `ktime_get` outside of NMI context.
43 Self::from_raw(unsafe { bindings::ktime_get() })
44 }
45
46 /// Divide the number of nanoseconds by a compile-time constant.
47 #[inline]
48 fn divns_constant<const DIV: i64>(self) -> i64 {
49 self.to_ns() / DIV
50 }
51
52 /// Returns the number of nanoseconds.
53 #[inline]
54 pub fn to_ns(self) -> i64 {
55 self.inner
56 }
57
58 /// Returns the number of milliseconds.
59 #[inline]
60 pub fn to_ms(self) -> i64 {
61 self.divns_constant::<NSEC_PER_MSEC>()
62 }
63}
64
65/// Returns the number of milliseconds between two ktimes.
66#[inline]
67pub fn ktime_ms_delta(later: Ktime, earlier: Ktime) -> i64 {
68 (later - earlier).to_ms()
69}
70
71impl core::ops::Sub for Ktime {
72 type Output = Ktime;
73
74 #[inline]
75 fn sub(self, other: Ktime) -> Ktime {
76 Self {
77 inner: self.inner - other.inner,
78 }
79 }
80}