diff options
Diffstat (limited to 'embassy-executor/src/raw/timer_queue.rs')
| -rw-r--r-- | embassy-executor/src/raw/timer_queue.rs | 35 |
1 files changed, 14 insertions, 21 deletions
diff --git a/embassy-executor/src/raw/timer_queue.rs b/embassy-executor/src/raw/timer_queue.rs index 24c31892a..57d6d3cda 100644 --- a/embassy-executor/src/raw/timer_queue.rs +++ b/embassy-executor/src/raw/timer_queue.rs | |||
| @@ -1,45 +1,39 @@ | |||
| 1 | use core::cell::Cell; | 1 | use core::cell::Cell; |
| 2 | use core::cmp::min; | 2 | use core::cmp::min; |
| 3 | use core::ptr; | ||
| 4 | use core::ptr::NonNull; | ||
| 5 | 3 | ||
| 6 | use atomic_polyfill::Ordering; | 4 | use atomic_polyfill::Ordering; |
| 7 | use embassy_time::Instant; | 5 | use embassy_time::Instant; |
| 8 | 6 | ||
| 9 | use super::{TaskHeader, STATE_TIMER_QUEUED}; | 7 | use super::{TaskRef, STATE_TIMER_QUEUED}; |
| 10 | 8 | ||
| 11 | pub(crate) struct TimerQueueItem { | 9 | pub(crate) struct TimerQueueItem { |
| 12 | next: Cell<*mut TaskHeader>, | 10 | next: Cell<Option<TaskRef>>, |
| 13 | } | 11 | } |
| 14 | 12 | ||
| 15 | impl TimerQueueItem { | 13 | impl TimerQueueItem { |
| 16 | pub const fn new() -> Self { | 14 | pub const fn new() -> Self { |
| 17 | Self { | 15 | Self { next: Cell::new(None) } |
| 18 | next: Cell::new(ptr::null_mut()), | ||
| 19 | } | ||
| 20 | } | 16 | } |
| 21 | } | 17 | } |
| 22 | 18 | ||
| 23 | pub(crate) struct TimerQueue { | 19 | pub(crate) struct TimerQueue { |
| 24 | head: Cell<*mut TaskHeader>, | 20 | head: Cell<Option<TaskRef>>, |
| 25 | } | 21 | } |
| 26 | 22 | ||
| 27 | impl TimerQueue { | 23 | impl TimerQueue { |
| 28 | pub const fn new() -> Self { | 24 | pub const fn new() -> Self { |
| 29 | Self { | 25 | Self { head: Cell::new(None) } |
| 30 | head: Cell::new(ptr::null_mut()), | ||
| 31 | } | ||
| 32 | } | 26 | } |
| 33 | 27 | ||
| 34 | pub(crate) unsafe fn update(&self, p: NonNull<TaskHeader>) { | 28 | pub(crate) unsafe fn update(&self, p: TaskRef) { |
| 35 | let task = p.as_ref(); | 29 | let task = p.header(); |
| 36 | if task.expires_at.get() != Instant::MAX { | 30 | if task.expires_at.get() != Instant::MAX { |
| 37 | let old_state = task.state.fetch_or(STATE_TIMER_QUEUED, Ordering::AcqRel); | 31 | let old_state = task.state.fetch_or(STATE_TIMER_QUEUED, Ordering::AcqRel); |
| 38 | let is_new = old_state & STATE_TIMER_QUEUED == 0; | 32 | let is_new = old_state & STATE_TIMER_QUEUED == 0; |
| 39 | 33 | ||
| 40 | if is_new { | 34 | if is_new { |
| 41 | task.timer_queue_item.next.set(self.head.get()); | 35 | task.timer_queue_item.next.set(self.head.get()); |
| 42 | self.head.set(p.as_ptr()); | 36 | self.head.set(Some(p)); |
| 43 | } | 37 | } |
| 44 | } | 38 | } |
| 45 | } | 39 | } |
| @@ -47,7 +41,7 @@ impl TimerQueue { | |||
| 47 | pub(crate) unsafe fn next_expiration(&self) -> Instant { | 41 | pub(crate) unsafe fn next_expiration(&self) -> Instant { |
| 48 | let mut res = Instant::MAX; | 42 | let mut res = Instant::MAX; |
| 49 | self.retain(|p| { | 43 | self.retain(|p| { |
| 50 | let task = p.as_ref(); | 44 | let task = p.header(); |
| 51 | let expires = task.expires_at.get(); | 45 | let expires = task.expires_at.get(); |
| 52 | res = min(res, expires); | 46 | res = min(res, expires); |
| 53 | expires != Instant::MAX | 47 | expires != Instant::MAX |
| @@ -55,9 +49,9 @@ impl TimerQueue { | |||
| 55 | res | 49 | res |
| 56 | } | 50 | } |
| 57 | 51 | ||
| 58 | pub(crate) unsafe fn dequeue_expired(&self, now: Instant, on_task: impl Fn(NonNull<TaskHeader>)) { | 52 | pub(crate) unsafe fn dequeue_expired(&self, now: Instant, on_task: impl Fn(TaskRef)) { |
| 59 | self.retain(|p| { | 53 | self.retain(|p| { |
| 60 | let task = p.as_ref(); | 54 | let task = p.header(); |
| 61 | if task.expires_at.get() <= now { | 55 | if task.expires_at.get() <= now { |
| 62 | on_task(p); | 56 | on_task(p); |
| 63 | false | 57 | false |
| @@ -67,11 +61,10 @@ impl TimerQueue { | |||
| 67 | }); | 61 | }); |
| 68 | } | 62 | } |
| 69 | 63 | ||
| 70 | pub(crate) unsafe fn retain(&self, mut f: impl FnMut(NonNull<TaskHeader>) -> bool) { | 64 | pub(crate) unsafe fn retain(&self, mut f: impl FnMut(TaskRef) -> bool) { |
| 71 | let mut prev = &self.head; | 65 | let mut prev = &self.head; |
| 72 | while !prev.get().is_null() { | 66 | while let Some(p) = prev.get() { |
| 73 | let p = NonNull::new_unchecked(prev.get()); | 67 | let task = p.header(); |
| 74 | let task = &*p.as_ptr(); | ||
| 75 | if f(p) { | 68 | if f(p) { |
| 76 | // Skip to next | 69 | // Skip to next |
| 77 | prev = &task.timer_queue_item.next; | 70 | prev = &task.timer_queue_item.next; |
