aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-executor/src/raw/deadline.rs62
-rw-r--r--embassy-executor/src/raw/mod.rs2
2 files changed, 53 insertions, 11 deletions
diff --git a/embassy-executor/src/raw/deadline.rs b/embassy-executor/src/raw/deadline.rs
index c8cc94c52..0b88ee2d6 100644
--- a/embassy-executor/src/raw/deadline.rs
+++ b/embassy-executor/src/raw/deadline.rs
@@ -10,6 +10,16 @@ pub struct Deadline {
10} 10}
11 11
12impl Deadline { 12impl Deadline {
13 /// Sentinel value representing an "unset" deadline, which has lower priority
14 /// than any other set deadline value
15 pub const UNSET_DEADLINE_TICKS: u64 = u64::MAX;
16
17 /// Does the given Deadline represent an "unset" deadline?
18 #[inline]
19 pub fn is_unset(&self) -> bool {
20 self.instant_ticks == Self::UNSET_DEADLINE_TICKS
21 }
22
13 /// Set the current task's deadline at exactly `instant_ticks` 23 /// Set the current task's deadline at exactly `instant_ticks`
14 /// 24 ///
15 /// This method is a future in order to access the currently executing task's 25 /// This method is a future in order to access the currently executing task's
@@ -17,7 +27,7 @@ impl Deadline {
17 /// 27 ///
18 /// Analogous to `Timer::at`. 28 /// Analogous to `Timer::at`.
19 /// 29 ///
20 /// TODO: Should we check/panic if the deadline is in the past? 30 /// This method does NOT check whether the deadline has already passed.
21 #[must_use = "Setting deadline must be polled to be effective"] 31 #[must_use = "Setting deadline must be polled to be effective"]
22 pub fn set_current_task_deadline(instant_ticks: u64) -> impl Future<Output = ()> { 32 pub fn set_current_task_deadline(instant_ticks: u64) -> impl Future<Output = ()> {
23 poll_fn(move |cx| { 33 poll_fn(move |cx| {
@@ -32,16 +42,16 @@ impl Deadline {
32 } 42 }
33 43
34 /// Set the current task's deadline `duration_ticks` in the future from when 44 /// Set the current task's deadline `duration_ticks` in the future from when
35 /// this future is polled. 45 /// this future is polled. This deadline is saturated to the max tick value.
36 /// 46 ///
37 /// This method is a future in order to access the currently executing task's 47 /// This method is a future in order to access the currently executing task's
38 /// header which contains the deadline 48 /// header which contains the deadline.
39 /// 49 ///
40 /// Analogous to `Timer::after` 50 /// Analogous to `Timer::after`.
41 /// 51 ///
42 /// TODO: Do we want to return what the deadline is? 52 /// Returns the deadline that was set.
43 #[must_use = "Setting deadline must be polled to be effective"] 53 #[must_use = "Setting deadline must be polled to be effective"]
44 pub fn set_current_task_deadline_after(duration_ticks: u64) -> impl Future<Output = ()> { 54 pub fn set_current_task_deadline_after(duration_ticks: u64) -> impl Future<Output = Deadline> {
45 poll_fn(move |cx| { 55 poll_fn(move |cx| {
46 let task = super::task_from_waker(cx.waker()); 56 let task = super::task_from_waker(cx.waker());
47 let now = embassy_time_driver::now(); 57 let now = embassy_time_driver::now();
@@ -56,12 +66,16 @@ impl Deadline {
56 unsafe { 66 unsafe {
57 task.header().deadline.set(deadline); 67 task.header().deadline.set(deadline);
58 } 68 }
59 Poll::Ready(()) 69 Poll::Ready(Deadline {
70 instant_ticks: deadline,
71 })
60 }) 72 })
61 } 73 }
62 74
63 /// Set the current task's deadline `increment_ticks` from the previous deadline. 75 /// Set the current task's deadline `increment_ticks` from the previous deadline.
64 /// 76 ///
77 /// This deadline is saturated to the max tick value.
78 ///
65 /// Note that by default (unless otherwise set), tasks start life with the deadline 79 /// Note that by default (unless otherwise set), tasks start life with the deadline
66 /// u64::MAX, which means this method will have no effect. 80 /// u64::MAX, which means this method will have no effect.
67 /// 81 ///
@@ -70,9 +84,9 @@ impl Deadline {
70 /// 84 ///
71 /// Analogous to one increment of `Ticker::every().next()`. 85 /// Analogous to one increment of `Ticker::every().next()`.
72 /// 86 ///
73 /// TODO: Do we want to return what the deadline is? 87 /// Returns the deadline that was set.
74 #[must_use = "Setting deadline must be polled to be effective"] 88 #[must_use = "Setting deadline must be polled to be effective"]
75 pub fn increment_current_task_deadline(increment_ticks: u64) -> impl Future<Output = ()> { 89 pub fn increment_current_task_deadline(increment_ticks: u64) -> impl Future<Output = Deadline> {
76 poll_fn(move |cx| { 90 poll_fn(move |cx| {
77 let task = super::task_from_waker(cx.waker()); 91 let task = super::task_from_waker(cx.waker());
78 92
@@ -89,8 +103,11 @@ impl Deadline {
89 103
90 // Store the new value 104 // Store the new value
91 task.header().deadline.set(deadline); 105 task.header().deadline.set(deadline);
106
107 Poll::Ready(Deadline {
108 instant_ticks: deadline,
109 })
92 } 110 }
93 Poll::Ready(())
94 }) 111 })
95 } 112 }
96 113
@@ -110,4 +127,29 @@ impl Deadline {
110 }) 127 })
111 }) 128 })
112 } 129 }
130
131 /// Clear the current task's deadline, returning the previous value.
132 ///
133 /// This sets the deadline to the default value of `u64::MAX`, meaning all
134 /// tasks with set deadlines will be scheduled BEFORE this task.
135 pub fn clear_current_task_deadline() -> impl Future<Output = Self> {
136 poll_fn(move |cx| {
137 let task = super::task_from_waker(cx.waker());
138
139 // SAFETY: A task can only modify its own deadline, while the task is being
140 // polled, meaning that there cannot be concurrent access to the deadline.
141 let deadline = unsafe {
142 // get the old value
143 let d = task.header().deadline.get();
144 // Store the default value
145 task.header().deadline.set(Self::UNSET_DEADLINE_TICKS);
146 // return the old value
147 d
148 };
149
150 Poll::Ready(Self {
151 instant_ticks: deadline,
152 })
153 })
154 }
113} 155}
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs
index f4fbe1bfc..a0890a864 100644
--- a/embassy-executor/src/raw/mod.rs
+++ b/embassy-executor/src/raw/mod.rs
@@ -316,7 +316,7 @@ impl<F: Future + 'static> AvailableTask<F> {
316 // By default, deadlines are set to the maximum value, so that any task WITH 316 // By default, deadlines are set to the maximum value, so that any task WITH
317 // a set deadline will ALWAYS be scheduled BEFORE a task WITHOUT a set deadline 317 // a set deadline will ALWAYS be scheduled BEFORE a task WITHOUT a set deadline
318 #[cfg(feature = "drs-scheduler")] 318 #[cfg(feature = "drs-scheduler")]
319 self.task.raw.deadline.set(u64::MAX); 319 self.task.raw.deadline.set(deadline::Deadline::UNSET_DEADLINE_TICKS);
320 320
321 let task = TaskRef::new(self.task); 321 let task = TaskRef::new(self.task);
322 322