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