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