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

View file

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

View file

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

View file

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

View file

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

View file

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

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)]
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;
}
}
}