simplify timer queue dispatch

This commit is contained in:
Jorge Aparicio 2018-05-05 10:08:17 +02:00
parent 0cc456ba80
commit cfcf25ef53
7 changed files with 58 additions and 68 deletions

View file

@ -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
// //

View file

@ -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
// //

View file

@ -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
// //

View file

@ -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)]

View file

@ -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>

View file

@ -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,

View file

@ -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; return;
} }
} }
State::Done => {
return;
}
}
}
} }