diff --git a/Cargo.toml b/Cargo.toml index 4e3d6731fb..57432690c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,7 @@ required-features = ["timer-queue"] [dependencies] cortex-m = "0.4.0" cortex-m-rtfm-macros = { path = "macros", version = "0.3.1" } -heapless = "0.3.5" +heapless = "0.3.6" typenum = "1.10.0" [target.'cfg(target_arch = "x86_64")'.dev-dependencies] @@ -71,4 +71,4 @@ cm7-r0p1 = ["cortex-m/cm7-r0p1"] timer-queue = ["cortex-m-rtfm-macros/timer-queue"] [profile.release] -lto = true +lto = true \ No newline at end of file diff --git a/examples/async.rs b/examples/async.rs index f56e9a495b..03435caa76 100644 --- a/examples/async.rs +++ b/examples/async.rs @@ -1,3 +1,11 @@ +// # Pointers (old) +// +// ~40~ 32 bytes .bss +// +// # Indices (new) +// +// 12 bytes .bss + #![deny(unsafe_code)] #![deny(warnings)] #![feature(proc_macro)] diff --git a/examples/periodic-payload.rs b/examples/periodic-payload.rs index 24a203f9c7..bd6cf76303 100644 --- a/examples/periodic-payload.rs +++ b/examples/periodic-payload.rs @@ -1,16 +1,36 @@ -// 52 bytes .bss +// # Pointers (old) +// +// ~52~ 48 bytes .bss // // # -Os +// // init // a(bl=8000000, now=8000180, input=0) // a(bl=16000000, now=16000180, input=1) // a(bl=24000000, now=24000180, input=2) // // # -O3 +// // init // a(bl=8000000, now=8000168, input=0) // a(bl=16000000, now=16000168, input=1) // a(bl=24000000, now=24000168, input=2) +// +// # Indices (new) +// +// 32 bytes .bss +// +// ## -O3 +// +// init +// a(bl=8000000, now=8000170, input=0) +// a(bl=16000000, now=16000170, input=1) +// +// ## -Os +// +// init +// a(bl=8000000, now=8000179, input=0) +// a(bl=16000000, now=16000179, input=1) #![deny(unsafe_code)] #![deny(warnings)] diff --git a/examples/periodic-preemption-payload.rs b/examples/periodic-preemption-payload.rs index 5b1b143782..b92d474943 100644 --- a/examples/periodic-preemption-payload.rs +++ b/examples/periodic-preemption-payload.rs @@ -1,6 +1,9 @@ -// 104 bytes .bss +// # Pointers (old) +// +// ~104~ 88 bytes .bss +// +// ## -Os // -// # -Os // a(bl=16000000, now=16000248, input=0) // b(bl=24000000, now=24000251, input=0) // a(bl=32000000, now=32000248, input=1) @@ -11,8 +14,9 @@ // a(bl=80000000, now=80000248, input=4) // b(bl=96000000, now=96000283, input=3) // a(bl=96000000, now=96002427, input=5) - -// # -O3 +// +// ## -O3 +// // init // a(bl=16000000, now=16000231, input=0) // b(bl=24000000, now=24000230, input=0) @@ -24,6 +28,37 @@ // a(bl=80000000, now=80000231, input=4) // b(bl=96000000, now=96000259, input=3) // a(bl=96000000, now=96002397, input=5) +// +// # Indices (new) +// +// 56 bytes .bss +// +// ## -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) +// +// ## -Os +// +// init +// a(bl=16000000, now=16000257, input=0) +// b(bl=24000000, now=24000252, input=0) +// a(bl=32000000, now=32000257, input=1) +// b(bl=48000000, now=48000284, input=1) +// a(bl=48000000, now=48002326, input=2) +// a(bl=64000000, now=64000257, input=3) +// b(bl=72000000, now=72000252, input=2) +// a(bl=80000000, now=80000257, input=4) +// b(bl=96000000, now=96000284, input=3) +// a(bl=96000000, now=96002326, input=5) #![deny(unsafe_code)] #![deny(warnings)] diff --git a/examples/periodic-preemption.rs b/examples/periodic-preemption.rs index 968e8be72f..1527864e3e 100644 --- a/examples/periodic-preemption.rs +++ b/examples/periodic-preemption.rs @@ -1,6 +1,9 @@ -// 96 bytes .bss +// # Pointers (old) +// +// ~96~ 80 bytes .bss // // # -Os +// // init // a(bl=16000000, now=16000249) // b(bl=24000000, now=24000248) @@ -12,8 +15,9 @@ // a(bl=80000000, now=80000249) // b(bl=96000000, now=96000282) // a(bl=96000000, now=96001731) - +// // # -O3 +// // init // a(bl=16000000, now=16000228) // b(bl=24000000, now=24000231) @@ -25,6 +29,38 @@ // a(bl=80000000, now=80000228) // b(bl=96000000, now=96000257) // a(bl=96000000, now=96001705) +// +// # Indices (new) +// +// 48 bytes .bss +// +// ## -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) +// +// ## -Os +// +// init +// a(bl=16000000, now=16000253) +// b(bl=24000000, now=24000251) +// a(bl=32000000, now=32000253) +// b(bl=48000000, now=48000283) +// a(bl=48000000, now=48001681) +// a(bl=64000000, now=64000253) +// b(bl=72000000, now=72000251) +// a(bl=80000000, now=80000253) +// b(bl=96000000, now=96000283) +// a(bl=96000000, now=96001681) #![deny(unsafe_code)] #![deny(warnings)] diff --git a/examples/periodic.rs b/examples/periodic.rs index 2d8d43ecc3..544b37612c 100644 --- a/examples/periodic.rs +++ b/examples/periodic.rs @@ -1,13 +1,33 @@ -// 52 bytes .bss +// # Pointers (old) +// +// ~52~ 40 bytes .bss +// +// ## -Os // -// # -Os // init // a(bl=8000000, now=8000180) // a(bl=16000000, now=16000180) // -// # -O3 +// ## -O3 +// // a(bl=8000000, now=8000168) // a(bl=16000000, now=16000168) +// +// # Indices (new) +// +// 28 bytes .bss +// +// ## -Os +// +// init +// a(bl=8000000, now=8000176) +// a(bl=16000000, now=16000176) +// +// ## -O3 +// +// init +// a(bl=8000000, now=8000167) +// a(bl=16000000, now=16000167) #![deny(unsafe_code)] #![deny(warnings)] diff --git a/macros/src/trans.rs b/macros/src/trans.rs index ab74ee0878..635855f060 100644 --- a/macros/src/trans.rs +++ b/macros/src/trans.rs @@ -280,18 +280,19 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { }); } Either::Right(capacity) => { - let capacity = Ident::from(format!("U{}", capacity)); + let ucapacity = Ident::from(format!("U{}", capacity)); + let capacity = capacity as usize; root.push(quote! { #[allow(unsafe_code)] unsafe impl #hidden::#krate::Resource for #name::SQ { const NVIC_PRIO_BITS: u8 = ::#device::NVIC_PRIO_BITS; type Ceiling = #name::Ceiling; - type Data = #hidden::#krate::SlotQueue<#input, #hidden::#krate::#capacity>; + type Data = #hidden::#krate::SlotQueue<#hidden::#krate::#ucapacity>; unsafe fn get() -> &'static mut Self::Data { static mut SQ: - #hidden::#krate::SlotQueue<#input, #hidden::#krate::#capacity> = + #hidden::#krate::SlotQueue<#hidden::#krate::#ucapacity> = #hidden::#krate::SlotQueue::u8(); &mut SQ @@ -306,6 +307,10 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { .unwrap_or(0) )); mod_.push(quote! { + #[allow(unsafe_code)] + pub static mut BUFFER: [#krate::Node<#input>; #capacity] = + unsafe { #krate::uninitialized() }; + pub struct SQ { _0: () } #[allow(unsafe_code)] @@ -372,13 +377,15 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { { unsafe { let slot = ::#name::SQ::new().claim_mut(t, |sq, _| sq.dequeue()); - if let Some(slot) = slot { - let tp = slot - .write(self.baseline, payload) - .tag(::#__priority::Task::#name); + if let Some(index) = slot { + let task = ::#__priority::Task::#name; + core::ptr::write( + ::#name::BUFFER.get_unchecked_mut(index as usize), + #krate::Node { baseline: self.baseline, payload } + ); ::#__priority::Q::new().claim_mut(t, |q, _| { - q.split().0.enqueue_unchecked(tp); + q.split().0.enqueue_unchecked((task, index)); }); #krate::set_pending(#device::Interrupt::#interrupt); @@ -417,17 +424,19 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { #krate::Maximum
: #krate::Unsigned, { unsafe { - if let Some(slot) = + if let Some(index) = ::#name::SQ::new().claim_mut(t, |sq, _| sq.dequeue()) { - let tp = slot - .write(payload) - .tag(::#__priority::Task::#name); + let task = ::#__priority::Task::#name; + core::ptr::write( + ::#name::BUFFER.get_unchecked_mut(index as usize), + #krate::Node { payload } + ); ::#__priority::Q::new().claim_mut(t, |q, _| { - q.split().0.enqueue_unchecked(tp); + q.split().0.enqueue_unchecked((task, index)); }); - #krate::set_pending(#device::Interrupt::#interrupt); + #krate::set_pending(#device::Interrupt::#interrupt); Ok(()) } else { @@ -487,14 +496,21 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { #krate::Maximum
: #krate::Unsigned,
{
unsafe {
- if let Some(slot) =
+ if let Some(index) =
::#name::SQ::new().claim_mut(t, |sq, _| sq.dequeue()) {
let bl = self.baseline + after;
- let tp = slot
- .write(bl, payload)
- .tag(::__tq::Task::#name);
+ let task = ::__tq::Task::#name;
+ core::ptr::write(
+ ::#name::BUFFER.get_unchecked_mut(index as usize),
+ #krate::Node { baseline: bl, payload },
+ );
+ let m = #krate::Message {
+ baseline: bl,
+ index,
+ task,
+ };
- ::__tq::TQ::new().claim_mut(t, |tq, _| tq.enqueue(bl, tp));
+ ::__tq::TQ::new().claim_mut(t, |tq, _| tq.enqueue(m));
Ok(())
} else {
@@ -531,7 +547,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
quote! {
__tq::Task::#name => {
#__priority::Q::new().claim_mut(t, |q, _| {
- q.split().0.enqueue_unchecked(tp.retag(#__priority::Task::#name))
+ q.split().0.enqueue_unchecked((#__priority::Task::#name, index))
});
#hidden::#krate::set_pending(#device::Interrupt::#interrupt);
}
@@ -585,8 +601,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
#hidden::#krate::dispatch(
&mut #hidden::#krate::Threshold::<__tq::Priority>::new(),
&mut __tq::TQ::new(),
- |t, tp| {
- match tp.tag() {
+ |t, task, index| {
+ match task {
#(#arms,)*
}
})
@@ -644,20 +660,18 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
if cfg!(feature = "timer-queue") {
quote! {
#__priority::Task::#name => {
- let (bl, payload, slot) = payload.coerce().read();
- // priority
- #name::SQ::get().split().0.enqueue_unchecked(slot);
- #name::HANDLER(#name::Context::new(bl, payload));
+ let node = core::ptr::read(::#name::BUFFER.get_unchecked(index as usize));
+ #name::SQ::get().split().0.enqueue_unchecked(index);
+ #name::HANDLER(#name::Context::new(node.baseline, node.payload));
}
}
} else {
quote! {
#__priority::Task::#name => {
- let (payload, slot) = payload.coerce().read();
- // priority
- #name::SQ::get().split().0.enqueue_unchecked(slot);
- #name::HANDLER(#name::Context::new(payload));
+ let node = core::ptr::read(::#name::BUFFER.get_unchecked(index as usize));
+ #name::SQ::get().split().0.enqueue_unchecked(index);
+ #name::HANDLER(#name::Context::new(node.payload));
}
}
}
@@ -675,8 +689,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
use #hidden::#krate::Resource;
// NOTE(get) the dispatcher is the only consumer of this queue
- while let Some(payload) = #__priority::Q::get().split().1.dequeue() {
- match payload.tag() {
+ while let Some((task, index)) = #__priority::Q::get().split().1.dequeue() {
+ match task {
#(#arms,)*
}
}
@@ -691,16 +705,9 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
let input = &task.input;
if let Either::Right(capacity) = task.interrupt_or_capacity {
- let capacity = capacity as usize;
-
pre_init.push(quote! {
- {
- static mut N: [#hidden::#krate::Node<#input>; #capacity] =
- unsafe { #hidden::#krate::uninitialized() };
-
- for node in N.iter_mut() {
- #name::SQ::get().enqueue_unchecked(node.into());
- }
+ for i in 0..#capacity {
+ #name::SQ::get().enqueue_unchecked(i);
}
})
}
diff --git a/src/lib.rs b/src/lib.rs
index e60c915d21..67ae649dca 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -37,13 +37,12 @@ pub use typenum::{Max, Maximum, Unsigned};
pub use instant::Instant;
pub use node::Node;
-use node::{Slot, TaggedPayload};
pub use resource::{Resource, Threshold};
#[cfg(feature = "timer-queue")]
-pub use tq::{dispatch, TimerQueue};
+pub use tq::{dispatch, Message, TimerQueue};
-pub type PayloadQueue , tq: &mut TQ, mut f: F)
where
- F: FnMut(&mut Threshold , TaggedPayload , T, u8),
Maximum : Unsigned,
- N: 'static + ArrayLength