From cfcf25ef53569fced59ddc789d6f765e82fbb30c Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 5 May 2018 10:08:17 +0200 Subject: [PATCH] simplify timer queue dispatch --- examples/periodic-payload.rs | 4 +- examples/periodic-preemption-payload.rs | 20 +++---- examples/periodic-preemption.rs | 20 +++---- examples/periodic.rs | 4 +- macros/src/trans.rs | 4 +- src/resource.rs | 4 ++ src/tq.rs | 70 ++++++++++--------------- 7 files changed, 58 insertions(+), 68 deletions(-) diff --git a/examples/periodic-payload.rs b/examples/periodic-payload.rs index bd6cf76303..3330f7f841 100644 --- a/examples/periodic-payload.rs +++ b/examples/periodic-payload.rs @@ -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 // diff --git a/examples/periodic-preemption-payload.rs b/examples/periodic-preemption-payload.rs index b92d474943..85d23ed65f 100644 --- a/examples/periodic-preemption-payload.rs +++ b/examples/periodic-preemption-payload.rs @@ -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 // diff --git a/examples/periodic-preemption.rs b/examples/periodic-preemption.rs index 1527864e3e..d042c19a91 100644 --- a/examples/periodic-preemption.rs +++ b/examples/periodic-preemption.rs @@ -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 // diff --git a/examples/periodic.rs b/examples/periodic.rs index 544b37612c..ae63afa0a9 100644 --- a/examples/periodic.rs +++ b/examples/periodic.rs @@ -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)] diff --git a/macros/src/trans.rs b/macros/src/trans.rs index 635855f060..822540f38b 100644 --- a/macros/src/trans.rs +++ b/macros/src/trans.rs @@ -364,7 +364,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { // XXX or take `self`? #[inline] pub fn post

( - &self, + &mut self, t: &mut #krate::Threshold

, payload: #ty, ) -> Result<(), #ty> @@ -412,7 +412,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { // XXX or take `self`? #[inline] pub fn post

( - &self, + &mut self, t: &mut #krate::Threshold

, payload: #ty, ) -> Result<(), #ty> diff --git a/src/resource.rs b/src/resource.rs index d03d684b29..67870cb7be 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -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

) -> &'cs Self::Data where P: IsGreaterOrEqual + 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

) -> &'cs mut Self::Data where P: IsGreaterOrEqual + Unsigned, @@ -49,6 +51,7 @@ pub unsafe trait Resource { unsafe { Self::get() } } + #[inline(always)] fn claim<'cs, R, F, P>(&self, _t: &mut Threshold

, f: F) -> R where F: FnOnce(&Self::Data, &mut Threshold>) -> R, @@ -71,6 +74,7 @@ pub unsafe trait Resource { } } + #[inline(always)] fn claim_mut<'cs, R, F, P>(&mut self, _t: &mut Threshold

, f: F) -> R where F: FnOnce(&mut Self::Data, &mut Threshold>) -> R, diff --git a/src/tq.rs b/src/tq.rs index 0a8e3ecd72..fc7420829c 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -34,15 +34,6 @@ impl PartialOrd for Message { } } -enum State -where - T: Copy, -{ - Payload { task: T, index: u8 }, - Baseline(Instant), - Done, -} - #[doc(hidden)] pub struct TimerQueue where @@ -67,12 +58,19 @@ where #[inline] pub unsafe fn enqueue(&mut self, m: Message) { + 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>, { 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; } } }