mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-29 23:14:34 +01:00
simplify timer queue dispatch
This commit is contained in:
parent
0cc456ba80
commit
cfcf25ef53
7 changed files with 58 additions and 68 deletions
|
@ -23,8 +23,8 @@
|
||||||
// ## -O3
|
// ## -O3
|
||||||
//
|
//
|
||||||
// init
|
// init
|
||||||
// a(bl=8000000, now=8000170, input=0)
|
// a(bl=8000000, now=8000172, input=0)
|
||||||
// a(bl=16000000, now=16000170, input=1)
|
// a(bl=16000000, now=16000172, input=1)
|
||||||
//
|
//
|
||||||
// ## -Os
|
// ## -Os
|
||||||
//
|
//
|
||||||
|
|
|
@ -35,16 +35,16 @@
|
||||||
//
|
//
|
||||||
// ## -O3
|
// ## -O3
|
||||||
//
|
//
|
||||||
// a(bl=16000000, now=16000215, input=0)
|
// a(bl=16000000, now=16000207, input=0)
|
||||||
// b(bl=24000000, now=24000214, input=0)
|
// b(bl=24000000, now=24000202, input=0)
|
||||||
// a(bl=32000000, now=32000215, input=1)
|
// a(bl=32000000, now=32000207, input=1)
|
||||||
// b(bl=48000000, now=48000236, input=1)
|
// b(bl=48000000, now=48000229, input=1)
|
||||||
// a(bl=48000000, now=48002281, input=2)
|
// a(bl=48000000, now=48001984, input=2)
|
||||||
// a(bl=64000000, now=64000215, input=3)
|
// a(bl=64000000, now=64000207, input=3)
|
||||||
// b(bl=72000000, now=72000214, input=2)
|
// b(bl=72000000, now=72000202, input=2)
|
||||||
// a(bl=80000000, now=80000215, input=4)
|
// a(bl=80000000, now=80000207, input=4)
|
||||||
// b(bl=96000000, now=96000236, input=3)
|
// b(bl=96000000, now=96000229, input=3)
|
||||||
// a(bl=96000000, now=96002281, input=5)
|
// a(bl=96000000, now=96001984, input=5)
|
||||||
//
|
//
|
||||||
// ## -Os
|
// ## -Os
|
||||||
//
|
//
|
||||||
|
|
|
@ -37,16 +37,16 @@
|
||||||
// ## -O3
|
// ## -O3
|
||||||
//
|
//
|
||||||
// init
|
// init
|
||||||
// a(bl=16000000, now=16000213)
|
// a(bl=16000000, now=16000198)
|
||||||
// b(bl=24000000, now=24000212)
|
// b(bl=24000000, now=24000205)
|
||||||
// a(bl=32000000, now=32000213)
|
// a(bl=32000000, now=32000198)
|
||||||
// b(bl=48000000, now=48000234)
|
// b(bl=48000000, now=48000232)
|
||||||
// a(bl=48000000, now=48001650)
|
// a(bl=48000000, now=48001454)
|
||||||
// a(bl=64000000, now=64000213)
|
// a(bl=64000000, now=64000198)
|
||||||
// b(bl=72000000, now=72000212)
|
// b(bl=72000000, now=72000205)
|
||||||
// a(bl=80000000, now=80000213)
|
// a(bl=80000000, now=80000198)
|
||||||
// b(bl=96000000, now=96000234)
|
// b(bl=96000000, now=96000232)
|
||||||
// a(bl=96000000, now=96001650)
|
// a(bl=96000000, now=96001454)
|
||||||
//
|
//
|
||||||
// ## -Os
|
// ## -Os
|
||||||
//
|
//
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
// ## -O3
|
// ## -O3
|
||||||
//
|
//
|
||||||
// init
|
// init
|
||||||
// a(bl=8000000, now=8000167)
|
// a(bl=8000000, now=8000169)
|
||||||
// a(bl=16000000, now=16000167)
|
// a(bl=16000000, now=16000169)
|
||||||
|
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
|
|
@ -364,7 +364,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
|
||||||
// XXX or take `self`?
|
// XXX or take `self`?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn post<P>(
|
pub fn post<P>(
|
||||||
&self,
|
&mut self,
|
||||||
t: &mut #krate::Threshold<P>,
|
t: &mut #krate::Threshold<P>,
|
||||||
payload: #ty,
|
payload: #ty,
|
||||||
) -> Result<(), #ty>
|
) -> Result<(), #ty>
|
||||||
|
@ -412,7 +412,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
|
||||||
// XXX or take `self`?
|
// XXX or take `self`?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn post<P>(
|
pub fn post<P>(
|
||||||
&self,
|
&mut self,
|
||||||
t: &mut #krate::Threshold<P>,
|
t: &mut #krate::Threshold<P>,
|
||||||
payload: #ty,
|
payload: #ty,
|
||||||
) -> Result<(), #ty>
|
) -> Result<(), #ty>
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub unsafe trait Resource {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
unsafe fn get() -> &'static mut Self::Data;
|
unsafe fn get() -> &'static mut Self::Data;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn borrow<'cs, P>(&'cs self, _t: &'cs Threshold<P>) -> &'cs Self::Data
|
fn borrow<'cs, P>(&'cs self, _t: &'cs Threshold<P>) -> &'cs Self::Data
|
||||||
where
|
where
|
||||||
P: IsGreaterOrEqual<Self::Ceiling, Output = True> + Unsigned,
|
P: IsGreaterOrEqual<Self::Ceiling, Output = True> + Unsigned,
|
||||||
|
@ -42,6 +43,7 @@ pub unsafe trait Resource {
|
||||||
unsafe { Self::get() }
|
unsafe { Self::get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn borrow_mut<'cs, P>(&'cs mut self, _t: &'cs Threshold<P>) -> &'cs mut Self::Data
|
fn borrow_mut<'cs, P>(&'cs mut self, _t: &'cs Threshold<P>) -> &'cs mut Self::Data
|
||||||
where
|
where
|
||||||
P: IsGreaterOrEqual<Self::Ceiling, Output = True> + Unsigned,
|
P: IsGreaterOrEqual<Self::Ceiling, Output = True> + Unsigned,
|
||||||
|
@ -49,6 +51,7 @@ pub unsafe trait Resource {
|
||||||
unsafe { Self::get() }
|
unsafe { Self::get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn claim<'cs, R, F, P>(&self, _t: &mut Threshold<P>, f: F) -> R
|
fn claim<'cs, R, F, P>(&self, _t: &mut Threshold<P>, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&Self::Data, &mut Threshold<Maximum<P, Self::Ceiling>>) -> R,
|
F: FnOnce(&Self::Data, &mut Threshold<Maximum<P, Self::Ceiling>>) -> R,
|
||||||
|
@ -71,6 +74,7 @@ pub unsafe trait Resource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn claim_mut<'cs, R, F, P>(&mut self, _t: &mut Threshold<P>, f: F) -> R
|
fn claim_mut<'cs, R, F, P>(&mut self, _t: &mut Threshold<P>, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self::Data, &mut Threshold<Maximum<P, Self::Ceiling>>) -> R,
|
F: FnOnce(&mut Self::Data, &mut Threshold<Maximum<P, Self::Ceiling>>) -> R,
|
||||||
|
|
64
src/tq.rs
64
src/tq.rs
|
@ -34,15 +34,6 @@ impl<T> PartialOrd for Message<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum State<T>
|
|
||||||
where
|
|
||||||
T: Copy,
|
|
||||||
{
|
|
||||||
Payload { task: T, index: u8 },
|
|
||||||
Baseline(Instant),
|
|
||||||
Done,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct TimerQueue<T, N>
|
pub struct TimerQueue<T, N>
|
||||||
where
|
where
|
||||||
|
@ -67,12 +58,19 @@ where
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn enqueue(&mut self, m: Message<T>) {
|
pub unsafe fn enqueue(&mut self, m: Message<T>) {
|
||||||
|
let mut is_empty = true;
|
||||||
if self.queue
|
if self.queue
|
||||||
.peek()
|
.peek()
|
||||||
.map(|head| m.baseline < head.baseline)
|
.map(|head| {
|
||||||
|
is_empty = false;
|
||||||
|
m.baseline < head.baseline
|
||||||
|
})
|
||||||
.unwrap_or(true)
|
.unwrap_or(true)
|
||||||
{
|
{
|
||||||
|
if is_empty {
|
||||||
self.syst.enable_interrupt();
|
self.syst.enable_interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
// set SysTick pending
|
// set SysTick pending
|
||||||
unsafe { (*SCB::ptr()).icsr.write(1 << 26) }
|
unsafe { (*SCB::ptr()).icsr.write(1 << 26) }
|
||||||
}
|
}
|
||||||
|
@ -91,48 +89,36 @@ where
|
||||||
TQ: Resource<Data = TimerQueue<T, N>>,
|
TQ: Resource<Data = TimerQueue<T, N>>,
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
let state = tq.claim_mut(t, |tq, _| {
|
let next = tq.claim_mut(t, |tq, _| {
|
||||||
if let Some(bl) = tq.queue.peek().map(|p| p.baseline) {
|
if let Some(bl) = tq.queue.peek().map(|p| p.baseline) {
|
||||||
if Instant::now() >= bl {
|
let diff = bl - Instant::now();
|
||||||
|
|
||||||
|
if diff < 0 {
|
||||||
// message ready
|
// message ready
|
||||||
let m = unsafe { tq.queue.pop_unchecked() };
|
let m = unsafe { tq.queue.pop_unchecked() };
|
||||||
State::Payload {
|
|
||||||
task: m.task,
|
Some((m.task, m.index))
|
||||||
index: m.index,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// set a new timeout
|
const MAX: u32 = 0x00ffffff;
|
||||||
State::Baseline(bl)
|
|
||||||
|
tq.syst.set_reload(cmp::min(MAX, diff as u32));
|
||||||
|
|
||||||
|
// start counting from the new reload
|
||||||
|
tq.syst.clear_current();
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// empty queue
|
// empty queue
|
||||||
tq.syst.disable_interrupt();
|
tq.syst.disable_interrupt();
|
||||||
State::Done
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
match state {
|
if let Some((task, index)) = next {
|
||||||
State::Payload { task, index } => f(t, task, index),
|
f(t, task, index)
|
||||||
State::Baseline(bl) => {
|
|
||||||
const MAX: u32 = 0x00ffffff;
|
|
||||||
|
|
||||||
let diff = bl - Instant::now();
|
|
||||||
|
|
||||||
if diff < 0 {
|
|
||||||
// message became ready
|
|
||||||
continue;
|
|
||||||
} else {
|
} else {
|
||||||
tq.claim_mut(t, |tq, _| {
|
|
||||||
tq.syst.set_reload(cmp::min(MAX, diff as u32));
|
|
||||||
// start counting from the new reload
|
|
||||||
tq.syst.clear_current();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
State::Done => {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue