aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src/time/instant.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-executor/src/time/instant.rs')
-rw-r--r--embassy-executor/src/time/instant.rs159
1 files changed, 159 insertions, 0 deletions
diff --git a/embassy-executor/src/time/instant.rs b/embassy-executor/src/time/instant.rs
new file mode 100644
index 000000000..6a4925f47
--- /dev/null
+++ b/embassy-executor/src/time/instant.rs
@@ -0,0 +1,159 @@
1use core::fmt;
2use core::ops::{Add, AddAssign, Sub, SubAssign};
3
4use super::{driver, Duration, GCD_1K, GCD_1M, TICKS_PER_SECOND};
5
6#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
8/// An Instant in time, based on the MCU's clock ticks since startup.
9pub struct Instant {
10 ticks: u64,
11}
12
13impl Instant {
14 /// The smallest (earliest) value that can be represented by the `Instant` type.
15 pub const MIN: Instant = Instant { ticks: u64::MIN };
16 /// The largest (latest) value that can be represented by the `Instant` type.
17 pub const MAX: Instant = Instant { ticks: u64::MAX };
18
19 /// Returns an Instant representing the current time.
20 pub fn now() -> Instant {
21 Instant { ticks: driver::now() }
22 }
23
24 /// Create an Instant from a tick count since system boot.
25 pub const fn from_ticks(ticks: u64) -> Self {
26 Self { ticks }
27 }
28
29 /// Create an Instant from a microsecond count since system boot.
30 pub const fn from_micros(micros: u64) -> Self {
31 Self {
32 ticks: micros * (TICKS_PER_SECOND / GCD_1M) / (1_000_000 / GCD_1M),
33 }
34 }
35
36 /// Create an Instant from a millisecond count since system boot.
37 pub const fn from_millis(millis: u64) -> Self {
38 Self {
39 ticks: millis * (TICKS_PER_SECOND / GCD_1K) / (1000 / GCD_1K),
40 }
41 }
42
43 /// Create an Instant from a second count since system boot.
44 pub const fn from_secs(seconds: u64) -> Self {
45 Self {
46 ticks: seconds * TICKS_PER_SECOND,
47 }
48 }
49
50 /// Tick count since system boot.
51 pub const fn as_ticks(&self) -> u64 {
52 self.ticks
53 }
54
55 /// Seconds since system boot.
56 pub const fn as_secs(&self) -> u64 {
57 self.ticks / TICKS_PER_SECOND
58 }
59
60 /// Milliseconds since system boot.
61 pub const fn as_millis(&self) -> u64 {
62 self.ticks * (1000 / GCD_1K) / (TICKS_PER_SECOND / GCD_1K)
63 }
64
65 /// Microseconds since system boot.
66 pub const fn as_micros(&self) -> u64 {
67 self.ticks * (1_000_000 / GCD_1M) / (TICKS_PER_SECOND / GCD_1M)
68 }
69
70 /// Duration between this Instant and another Instant
71 /// Panics on over/underflow.
72 pub fn duration_since(&self, earlier: Instant) -> Duration {
73 Duration {
74 ticks: self.ticks.checked_sub(earlier.ticks).unwrap(),
75 }
76 }
77
78 /// Duration between this Instant and another Instant
79 pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
80 if self.ticks < earlier.ticks {
81 None
82 } else {
83 Some(Duration {
84 ticks: self.ticks - earlier.ticks,
85 })
86 }
87 }
88
89 /// Returns the duration since the "earlier" Instant.
90 /// If the "earlier" instant is in the future, the duration is set to zero.
91 pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
92 Duration {
93 ticks: if self.ticks < earlier.ticks {
94 0
95 } else {
96 self.ticks - earlier.ticks
97 },
98 }
99 }
100
101 /// Duration elapsed since this Instant.
102 pub fn elapsed(&self) -> Duration {
103 Instant::now() - *self
104 }
105
106 /// Adds one Duration to self, returning a new `Instant` or None in the event of an overflow.
107 pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
108 self.ticks.checked_add(duration.ticks).map(|ticks| Instant { ticks })
109 }
110
111 /// Subtracts one Duration to self, returning a new `Instant` or None in the event of an overflow.
112 pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
113 self.ticks.checked_sub(duration.ticks).map(|ticks| Instant { ticks })
114 }
115}
116
117impl Add<Duration> for Instant {
118 type Output = Instant;
119
120 fn add(self, other: Duration) -> Instant {
121 self.checked_add(other)
122 .expect("overflow when adding duration to instant")
123 }
124}
125
126impl AddAssign<Duration> for Instant {
127 fn add_assign(&mut self, other: Duration) {
128 *self = *self + other;
129 }
130}
131
132impl Sub<Duration> for Instant {
133 type Output = Instant;
134
135 fn sub(self, other: Duration) -> Instant {
136 self.checked_sub(other)
137 .expect("overflow when subtracting duration from instant")
138 }
139}
140
141impl SubAssign<Duration> for Instant {
142 fn sub_assign(&mut self, other: Duration) {
143 *self = *self - other;
144 }
145}
146
147impl Sub<Instant> for Instant {
148 type Output = Duration;
149
150 fn sub(self, other: Instant) -> Duration {
151 self.duration_since(other)
152 }
153}
154
155impl<'a> fmt::Display for Instant {
156 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
157 write!(f, "{} ticks", self.ticks)
158 }
159}