time/generic_queue: use Vec instead of SortedLinkedList
This commit is contained in:
parent
4976cbbe60
commit
f9da6271ce
@ -4,7 +4,7 @@ use core::task::Waker;
|
|||||||
|
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::blocking_mutex::Mutex;
|
use embassy_sync::blocking_mutex::Mutex;
|
||||||
use heapless::sorted_linked_list::{LinkedIndexU8, Min, SortedLinkedList};
|
use heapless::Vec;
|
||||||
|
|
||||||
use crate::driver::{allocate_alarm, set_alarm, set_alarm_callback, AlarmHandle};
|
use crate::driver::{allocate_alarm, set_alarm, set_alarm_callback, AlarmHandle};
|
||||||
use crate::queue::TimerQueue;
|
use crate::queue::TimerQueue;
|
||||||
@ -56,18 +56,17 @@ impl Ord for Timer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct InnerQueue {
|
struct InnerQueue {
|
||||||
queue: SortedLinkedList<Timer, LinkedIndexU8, Min, { QUEUE_SIZE }>,
|
queue: Vec<Timer, QUEUE_SIZE>,
|
||||||
alarm: AlarmHandle,
|
alarm: AlarmHandle,
|
||||||
alarm_at: Instant,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InnerQueue {
|
impl InnerQueue {
|
||||||
fn schedule_wake(&mut self, at: Instant, waker: &Waker) {
|
fn schedule_wake(&mut self, at: Instant, waker: &Waker) {
|
||||||
self.queue
|
self.queue
|
||||||
.find_mut(|timer| timer.waker.will_wake(waker))
|
.iter_mut()
|
||||||
|
.find(|timer| timer.waker.will_wake(waker))
|
||||||
.map(|mut timer| {
|
.map(|mut timer| {
|
||||||
timer.at = min(timer.at, at);
|
timer.at = min(timer.at, at);
|
||||||
timer.finish();
|
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
let mut timer = Timer {
|
let mut timer = Timer {
|
||||||
@ -96,35 +95,35 @@ impl InnerQueue {
|
|||||||
loop {
|
loop {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
|
||||||
while self.queue.peek().filter(|timer| timer.at <= now).is_some() {
|
let mut next_alarm = Instant::MAX;
|
||||||
self.queue.pop().unwrap().waker.wake();
|
|
||||||
|
let mut i = 0;
|
||||||
|
while i < self.queue.len() {
|
||||||
|
let timer = &self.queue[i];
|
||||||
|
if timer.at <= now {
|
||||||
|
let timer = self.queue.swap_remove(i);
|
||||||
|
timer.waker.wake();
|
||||||
|
} else {
|
||||||
|
next_alarm = min(next_alarm, timer.at);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.update_alarm() {
|
if self.update_alarm(next_alarm) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_alarm(&mut self) -> bool {
|
fn update_alarm(&mut self, next_alarm: Instant) -> bool {
|
||||||
if let Some(timer) = self.queue.peek() {
|
if next_alarm == Instant::MAX {
|
||||||
let new_at = timer.at;
|
true
|
||||||
|
|
||||||
if self.alarm_at != new_at {
|
|
||||||
self.alarm_at = new_at;
|
|
||||||
|
|
||||||
return set_alarm(self.alarm, self.alarm_at.as_ticks());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
self.alarm_at = Instant::MAX;
|
set_alarm(self.alarm, next_alarm.as_ticks())
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_alarm(&mut self) {
|
fn handle_alarm(&mut self) {
|
||||||
self.alarm_at = Instant::MAX;
|
|
||||||
|
|
||||||
self.dispatch();
|
self.dispatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,9 +150,8 @@ impl Queue {
|
|||||||
let handle = unsafe { allocate_alarm() }.unwrap();
|
let handle = unsafe { allocate_alarm() }.unwrap();
|
||||||
set_alarm_callback(handle, Self::handle_alarm_callback, self as *const _ as _);
|
set_alarm_callback(handle, Self::handle_alarm_callback, self as *const _ as _);
|
||||||
InnerQueue {
|
InnerQueue {
|
||||||
queue: SortedLinkedList::new_u8(),
|
queue: Vec::new(),
|
||||||
alarm: handle,
|
alarm: handle,
|
||||||
alarm_at: Instant::MAX,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.schedule_wake(at, waker)
|
.schedule_wake(at, waker)
|
||||||
|
Loading…
Reference in New Issue
Block a user