aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src/executor/raw/timer_queue.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-08-17 23:40:16 +0200
committerDario Nieuwenhuis <[email protected]>2022-08-18 01:22:30 +0200
commit5daa173ce4b153a532b4daa9e94c7a248231f25b (patch)
tree2ef0b4d6f9b1c02dac2589e7b57982c20cbc0e66 /embassy-executor/src/executor/raw/timer_queue.rs
parent1c5b54a4823d596db730eb476c3ab78110557214 (diff)
Split embassy-time from embassy-executor.
Diffstat (limited to 'embassy-executor/src/executor/raw/timer_queue.rs')
-rw-r--r--embassy-executor/src/executor/raw/timer_queue.rs85
1 files changed, 0 insertions, 85 deletions
diff --git a/embassy-executor/src/executor/raw/timer_queue.rs b/embassy-executor/src/executor/raw/timer_queue.rs
deleted file mode 100644
index 62fcfc531..000000000
--- a/embassy-executor/src/executor/raw/timer_queue.rs
+++ /dev/null
@@ -1,85 +0,0 @@
1use core::cell::Cell;
2use core::cmp::min;
3use core::ptr;
4use core::ptr::NonNull;
5
6use atomic_polyfill::Ordering;
7
8use super::{TaskHeader, STATE_TIMER_QUEUED};
9use crate::time::Instant;
10
11pub(crate) struct TimerQueueItem {
12 next: Cell<*mut TaskHeader>,
13}
14
15impl TimerQueueItem {
16 pub const fn new() -> Self {
17 Self {
18 next: Cell::new(ptr::null_mut()),
19 }
20 }
21}
22
23pub(crate) struct TimerQueue {
24 head: Cell<*mut TaskHeader>,
25}
26
27impl TimerQueue {
28 pub const fn new() -> Self {
29 Self {
30 head: Cell::new(ptr::null_mut()),
31 }
32 }
33
34 pub(crate) unsafe fn update(&self, p: NonNull<TaskHeader>) {
35 let task = p.as_ref();
36 if task.expires_at.get() != Instant::MAX {
37 let old_state = task.state.fetch_or(STATE_TIMER_QUEUED, Ordering::AcqRel);
38 let is_new = old_state & STATE_TIMER_QUEUED == 0;
39
40 if is_new {
41 task.timer_queue_item.next.set(self.head.get());
42 self.head.set(p.as_ptr());
43 }
44 }
45 }
46
47 pub(crate) unsafe fn next_expiration(&self) -> Instant {
48 let mut res = Instant::MAX;
49 self.retain(|p| {
50 let task = p.as_ref();
51 let expires = task.expires_at.get();
52 res = min(res, expires);
53 expires != Instant::MAX
54 });
55 res
56 }
57
58 pub(crate) unsafe fn dequeue_expired(&self, now: Instant, on_task: impl Fn(NonNull<TaskHeader>)) {
59 self.retain(|p| {
60 let task = p.as_ref();
61 if task.expires_at.get() <= now {
62 on_task(p);
63 false
64 } else {
65 true
66 }
67 });
68 }
69
70 pub(crate) unsafe fn retain(&self, mut f: impl FnMut(NonNull<TaskHeader>) -> bool) {
71 let mut prev = &self.head;
72 while !prev.get().is_null() {
73 let p = NonNull::new_unchecked(prev.get());
74 let task = &*p.as_ptr();
75 if f(p) {
76 // Skip to next
77 prev = &task.timer_queue_item.next;
78 } else {
79 // Remove it
80 prev.set(task.timer_queue_item.next.get());
81 task.state.fetch_and(!STATE_TIMER_QUEUED, Ordering::AcqRel);
82 }
83 }
84 }
85}