diff options
Diffstat (limited to 'embassy-time-queue-driver/src')
| -rw-r--r-- | embassy-time-queue-driver/src/lib.rs | 14 | ||||
| -rw-r--r-- | embassy-time-queue-driver/src/queue_integrated.rs | 20 |
2 files changed, 29 insertions, 5 deletions
diff --git a/embassy-time-queue-driver/src/lib.rs b/embassy-time-queue-driver/src/lib.rs index 0c78921ed..2d5fd449a 100644 --- a/embassy-time-queue-driver/src/lib.rs +++ b/embassy-time-queue-driver/src/lib.rs | |||
| @@ -73,6 +73,20 @@ extern "Rust" { | |||
| 73 | 73 | ||
| 74 | /// Schedule the given waker to be woken at `at`. | 74 | /// Schedule the given waker to be woken at `at`. |
| 75 | pub fn schedule_wake(at: u64, waker: &Waker) { | 75 | pub fn schedule_wake(at: u64, waker: &Waker) { |
| 76 | #[cfg(feature = "integrated-timers")] | ||
| 77 | { | ||
| 78 | use embassy_executor::raw::task_from_waker; | ||
| 79 | use embassy_executor::raw::timer_queue::TimerEnqueueOperation; | ||
| 80 | // The very first thing we must do, before we even access the timer queue, is to | ||
| 81 | // mark the task a TIMER_QUEUED. This ensures that the task that is being scheduled | ||
| 82 | // can not be respawn while we are accessing the timer queue. | ||
| 83 | let task = task_from_waker(waker); | ||
| 84 | if unsafe { task.timer_enqueue() } == TimerEnqueueOperation::Ignore { | ||
| 85 | // We are not allowed to enqueue the task in the timer queue. This is because the | ||
| 86 | // task is not spawned, and so it makes no sense to schedule it. | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | } | ||
| 76 | unsafe { _embassy_time_schedule_wake(at, waker) } | 90 | unsafe { _embassy_time_schedule_wake(at, waker) } |
| 77 | } | 91 | } |
| 78 | 92 | ||
diff --git a/embassy-time-queue-driver/src/queue_integrated.rs b/embassy-time-queue-driver/src/queue_integrated.rs index cb0f79356..b905c00c3 100644 --- a/embassy-time-queue-driver/src/queue_integrated.rs +++ b/embassy-time-queue-driver/src/queue_integrated.rs | |||
| @@ -24,16 +24,21 @@ impl TimerQueue { | |||
| 24 | if item.next.get().is_none() { | 24 | if item.next.get().is_none() { |
| 25 | // If not in the queue, add it and update. | 25 | // If not in the queue, add it and update. |
| 26 | let prev = self.head.replace(Some(p)); | 26 | let prev = self.head.replace(Some(p)); |
| 27 | item.next.set(prev); | 27 | item.next.set(if prev.is_none() { |
| 28 | Some(unsafe { TaskRef::dangling() }) | ||
| 29 | } else { | ||
| 30 | prev | ||
| 31 | }); | ||
| 32 | item.expires_at.set(at); | ||
| 33 | true | ||
| 28 | } else if at <= item.expires_at.get() { | 34 | } else if at <= item.expires_at.get() { |
| 29 | // If expiration is sooner than previously set, update. | 35 | // If expiration is sooner than previously set, update. |
| 36 | item.expires_at.set(at); | ||
| 37 | true | ||
| 30 | } else { | 38 | } else { |
| 31 | // Task does not need to be updated. | 39 | // Task does not need to be updated. |
| 32 | return false; | 40 | false |
| 33 | } | 41 | } |
| 34 | |||
| 35 | item.expires_at.set(at); | ||
| 36 | true | ||
| 37 | } | 42 | } |
| 38 | 43 | ||
| 39 | /// Dequeues expired timers and returns the next alarm time. | 44 | /// Dequeues expired timers and returns the next alarm time. |
| @@ -64,6 +69,10 @@ impl TimerQueue { | |||
| 64 | fn retain(&self, mut f: impl FnMut(TaskRef) -> bool) { | 69 | fn retain(&self, mut f: impl FnMut(TaskRef) -> bool) { |
| 65 | let mut prev = &self.head; | 70 | let mut prev = &self.head; |
| 66 | while let Some(p) = prev.get() { | 71 | while let Some(p) = prev.get() { |
| 72 | if unsafe { p == TaskRef::dangling() } { | ||
| 73 | // prev was the last item, stop | ||
| 74 | break; | ||
| 75 | } | ||
| 67 | let item = p.timer_queue_item(); | 76 | let item = p.timer_queue_item(); |
| 68 | if f(p) { | 77 | if f(p) { |
| 69 | // Skip to next | 78 | // Skip to next |
| @@ -72,6 +81,7 @@ impl TimerQueue { | |||
| 72 | // Remove it | 81 | // Remove it |
| 73 | prev.set(item.next.get()); | 82 | prev.set(item.next.get()); |
| 74 | item.next.set(None); | 83 | item.next.set(None); |
| 84 | unsafe { p.timer_dequeue() }; | ||
| 75 | } | 85 | } |
| 76 | } | 86 | } |
| 77 | } | 87 | } |
