bump heapless dependency to v0.5.0; remove "nightly" feature

with the upcoming version of heapless we are able to initialize all internal
queues in const context removing the need for late initialization

this commit also removes the "nightly" feature because all the optimization
provided by it are now enabled by default
This commit is contained in:
Jorge Aparicio 2019-05-21 15:22:25 +02:00
parent eb528ef921
commit 30d6327001
5 changed files with 57 additions and 136 deletions

View file

@ -43,10 +43,7 @@ required-features = ["timer-queue"]
cortex-m = "0.5.8" cortex-m = "0.5.8"
cortex-m-rt = "0.6.7" cortex-m-rt = "0.6.7"
cortex-m-rtfm-macros = { path = "macros", version = "0.5.0-alpha.1" } cortex-m-rtfm-macros = { path = "macros", version = "0.5.0-alpha.1" }
heapless = "0.5.0-alpha.1"
[dependencies.heapless]
features = ["smaller-atomics", "min-const-fn"]
version = "0.4.3"
[dev-dependencies] [dev-dependencies]
cortex-m-semihosting = "0.3.2" cortex-m-semihosting = "0.3.2"
@ -58,7 +55,6 @@ features = ["exit"]
version = "0.5.1" version = "0.5.1"
[features] [features]
nightly = ["cortex-m-rtfm-macros/nightly", "heapless/const-fn"]
timer-queue = ["cortex-m-rtfm-macros/timer-queue"] timer-queue = ["cortex-m-rtfm-macros/timer-queue"]
[target.x86_64-unknown-linux-gnu.dev-dependencies] [target.x86_64-unknown-linux-gnu.dev-dependencies]

View file

@ -33,25 +33,18 @@ arm_example() {
main() { main() {
local T=$TARGET local T=$TARGET
local nightly=""
if [ $TRAVIS_RUST_VERSION = nightly ]; then
nightly="nightly"
fi
mkdir -p ci/builds mkdir -p ci/builds
if [ $T = x86_64-unknown-linux-gnu ]; then if [ $T = x86_64-unknown-linux-gnu ]; then
# compile-fail and compile-pass tests # compile-fail and compile-pass tests
case $TRAVIS_RUST_VERSION in
nightly*) # TODO how to run a subset of these tests when timer-queue is disabled?
# TODO how to run a subset of these tests when timer-queue is disabled? cargo test --features "timer-queue" --test compiletest --target $T
cargo test --features "$nightly,timer-queue" --test compiletest --target $T
esac
cargo check --target $T cargo check --target $T
if [ $TARGET != thumbv6m-none-eabi ]; then if [ $TARGET != thumbv6m-none-eabi ]; then
cargo check --features "$nightly,timer-queue" --target $T cargo check --features "timer-queue" --target $T
fi fi
if [ $TRAVIS_RUST_VERSION != nightly ]; then if [ $TRAVIS_RUST_VERSION != nightly ]; then
@ -81,9 +74,9 @@ main() {
return return
fi fi
cargo check --features "$nightly" --target $T --examples cargo check --target $T --examples
if [ $TARGET != thumbv6m-none-eabi ]; then if [ $TARGET != thumbv6m-none-eabi ]; then
cargo check --features "$nightly,timer-queue" --target $T --examples cargo check --features "timer-queue" --target $T --examples
fi fi
# run-pass tests # run-pass tests
@ -124,7 +117,7 @@ main() {
if [ $TARGET != thumbv6m-none-eabi ]; then if [ $TARGET != thumbv6m-none-eabi ]; then
local td=$(mktemp -d) local td=$(mktemp -d)
local features="$nightly,timer-queue" local features="timer-queue"
cargo run --example $ex --target $TARGET --features $features >\ cargo run --example $ex --target $TARGET --features $features >\
$td/pool.run $td/pool.run
grep 'foo(0x2' $td/pool.run grep 'foo(0x2' $td/pool.run
@ -146,13 +139,13 @@ main() {
fi fi
if [ $ex != types ]; then if [ $ex != types ]; then
arm_example "run" $ex "debug" "$nightly" "1" arm_example "run" $ex "debug" "" "1"
arm_example "run" $ex "release" "$nightly" "1" arm_example "run" $ex "release" "" "1"
fi fi
if [ $TARGET != thumbv6m-none-eabi ]; then if [ $TARGET != thumbv6m-none-eabi ]; then
arm_example "run" $ex "debug" "$nightly,timer-queue" "1" arm_example "run" $ex "debug" "timer-queue" "1"
arm_example "run" $ex "release" "$nightly,timer-queue" "1" arm_example "run" $ex "release" "timer-queue" "1"
fi fi
done done
@ -165,23 +158,23 @@ main() {
fi fi
if [ $ex != types ] && [ $ex != pool ]; then if [ $ex != types ] && [ $ex != pool ]; then
arm_example "build" $ex "debug" "$nightly" "2" arm_example "build" $ex "debug" "" "2"
cmp ci/builds/${ex}_${nightly/nightly/nightly_}debug_1.hex \ cmp ci/builds/${ex}_debug_1.hex \
ci/builds/${ex}_${nightly/nightly/nightly_}debug_2.hex ci/builds/${ex}_debug_2.hex
arm_example "build" $ex "release" "$nightly" "2" arm_example "build" $ex "release" "" "2"
cmp ci/builds/${ex}_${nightly/nightly/nightly_}release_1.hex \ cmp ci/builds/${ex}_release_1.hex \
ci/builds/${ex}_${nightly/nightly/nightly_}release_2.hex ci/builds/${ex}_release_2.hex
built+=( $ex ) built+=( $ex )
fi fi
if [ $TARGET != thumbv6m-none-eabi ]; then if [ $TARGET != thumbv6m-none-eabi ]; then
arm_example "build" $ex "debug" "$nightly,timer-queue" "2" arm_example "build" $ex "debug" "timer-queue" "2"
cmp ci/builds/${ex}_${nightly}_timer-queue_debug_1.hex \ cmp ci/builds/${ex}_timer-queue_debug_1.hex \
ci/builds/${ex}_${nightly}_timer-queue_debug_2.hex ci/builds/${ex}_timer-queue_debug_2.hex
arm_example "build" $ex "release" "$nightly,timer-queue" "2" arm_example "build" $ex "release" "timer-queue" "2"
cmp ci/builds/${ex}_${nightly}_timer-queue_release_1.hex \ cmp ci/builds/${ex}_timer-queue_release_1.hex \
ci/builds/${ex}_${nightly}_timer-queue_release_2.hex ci/builds/${ex}_timer-queue_release_2.hex
fi fi
done done

View file

@ -23,5 +23,4 @@ features = ["extra-traits", "full"]
version = "0.15.23" version = "0.15.23"
[features] [features]
timer-queue = [] timer-queue = []
nightly = []

View file

@ -600,24 +600,13 @@ fn tasks(
let doc = "Queue version of a free-list that keeps track of empty slots in the previous buffer(s)"; let doc = "Queue version of a free-list that keeps track of empty slots in the previous buffer(s)";
let fq_ty = quote!(rtfm::export::FreeQueue<#cap_ty>); let fq_ty = quote!(rtfm::export::FreeQueue<#cap_ty>);
let ptr = if cfg!(feature = "nightly") { const_app.push(quote!(
const_app.push(quote!( #[doc = #doc]
#[doc = #doc] static mut #task_fq: #fq_ty = unsafe {
static mut #task_fq: #fq_ty = unsafe { rtfm::export::Queue(rtfm::export::i::Queue::u8_sc())
rtfm::export::FreeQueue::u8_sc() };
}; ));
)); let ptr = quote!(&mut #task_fq);
quote!(&mut #task_fq)
} else {
const_app.push(quote!(
#[doc = #doc]
static mut #task_fq: core::mem::MaybeUninit<#fq_ty> =
core::mem::MaybeUninit::uninit();
));
quote!(#task_fq.as_mut_ptr())
};
if let Some(ceiling) = analysis.free_queues.get(name) { if let Some(ceiling) = analysis.free_queues.get(name) {
const_app.push(quote!(struct #task_fq<'a> { const_app.push(quote!(struct #task_fq<'a> {
@ -705,24 +694,13 @@ fn dispatchers(app: &App, analysis: &Analysis) -> Vec<proc_macro2::TokenStream>
level level
); );
let rq_ty = quote!(rtfm::export::ReadyQueue<#t, #cap>); let rq_ty = quote!(rtfm::export::ReadyQueue<#t, #cap>);
let ptr = if cfg!(feature = "nightly") { items.push(quote!(
items.push(quote!( #[doc = #doc]
#[doc = #doc] static mut #rq: #rq_ty = unsafe {
static mut #rq: #rq_ty = unsafe { rtfm::export::Queue(rtfm::export::i::Queue::u8_sc())
rtfm::export::ReadyQueue::u8_sc() };
}; ));
)); let ptr = quote!(&mut #rq);
quote!(&mut #rq)
} else {
items.push(quote!(
#[doc = #doc]
static mut #rq: core::mem::MaybeUninit<#rq_ty> =
core::mem::MaybeUninit::uninit();
));
quote!(#rq.as_mut_ptr())
};
if let Some(ceiling) = analysis.ready_queues.get(&level) { if let Some(ceiling) = analysis.ready_queues.get(&level) {
items.push(quote!( items.push(quote!(
@ -772,11 +750,7 @@ fn dispatchers(app: &App, analysis: &Analysis) -> Vec<proc_macro2::TokenStream>
let fq = mk_fq_ident(name); let fq = mk_fq_ident(name);
let input = quote!(#inputs.get_unchecked(usize::from(index)).as_ptr().read()); let input = quote!(#inputs.get_unchecked(usize::from(index)).as_ptr().read());
let fq = if cfg!(feature = "nightly") { let fq = quote!(#fq);
quote!(#fq)
} else {
quote!((*#fq.as_mut_ptr()))
};
let (let_instant, _instant) = if cfg!(feature = "timer-queue") { let (let_instant, _instant) = if cfg!(feature = "timer-queue") {
let instants = mk_instants_ident(name); let instants = mk_instants_ident(name);
@ -822,11 +796,7 @@ fn dispatchers(app: &App, analysis: &Analysis) -> Vec<proc_macro2::TokenStream>
); );
let attrs = &dispatcher.attrs; let attrs = &dispatcher.attrs;
let interrupt = &dispatcher.interrupt; let interrupt = &dispatcher.interrupt;
let rq = if cfg!(feature = "nightly") { let rq = quote!((&mut #rq));
quote!((&mut #rq))
} else {
quote!((*#rq.as_mut_ptr()))
};
items.push(quote!( items.push(quote!(
#[doc = #doc] #[doc = #doc]
#(#attrs)* #(#attrs)*
@ -1174,42 +1144,16 @@ fn pre_init(app: &App, analysis: &Analysis) -> Vec<proc_macro2::TokenStream> {
stmts.push(quote!(rtfm::export::interrupt::disable();)); stmts.push(quote!(rtfm::export::interrupt::disable();));
// these won't be required once we have better `const fn` on stable (or const generics) // populate the `FreeQueue`s
if !cfg!(feature = "nightly") { for name in app.tasks.keys() {
// initialize `MaybeUninit` `ReadyQueue`s let fq = mk_fq_ident(name);
for level in analysis.dispatchers.keys() { let cap = analysis.capacities[name];
let rq = mk_rq_ident(*level);
stmts.push(quote!(#rq.as_mut_ptr().write(rtfm::export::ReadyQueue::u8_sc());))
}
// initialize `MaybeUninit` `FreeQueue`s stmts.push(quote!(
for name in app.tasks.keys() { for i in 0..#cap {
let fq = mk_fq_ident(name); #fq.enqueue_unchecked(i);
}
stmts.push(quote!( ));
let fq = #fq.as_mut_ptr().write(rtfm::export::FreeQueue::u8_sc());
));
// populate the `FreeQueue`s
let cap = analysis.capacities[name];
stmts.push(quote!(
for i in 0..#cap {
fq.enqueue_unchecked(i);
}
));
}
} else {
// populate the `FreeQueue`s
for name in app.tasks.keys() {
let fq = mk_fq_ident(name);
let cap = analysis.capacities[name];
stmts.push(quote!(
for i in 0..#cap {
#fq.enqueue_unchecked(i);
}
));
}
} }
stmts.push(quote!( stmts.push(quote!(
@ -2262,17 +2206,10 @@ fn mk_spawn_body<'a>(
let (dequeue, enqueue) = if spawner_is_init { let (dequeue, enqueue) = if spawner_is_init {
// `init` has exclusive access to these queues so we can bypass the resources AND // `init` has exclusive access to these queues so we can bypass the resources AND
// the consumer / producer split // the consumer / producer split
if cfg!(feature = "nightly") { (
( quote!(#fq.dequeue()),
quote!(#fq.dequeue()), quote!(#rq.enqueue_unchecked((#t::#name, index));),
quote!(#rq.enqueue_unchecked((#t::#name, index));), )
)
} else {
(
quote!((*#fq.as_mut_ptr()).dequeue()),
quote!((*#rq.as_mut_ptr()).enqueue_unchecked((#t::#name, index));),
)
}
} else { } else {
( (
quote!((#fq { priority }).lock(|fq| fq.split().1.dequeue())), quote!((#fq { priority }).lock(|fq| fq.split().1.dequeue())),
@ -2319,11 +2256,7 @@ fn mk_schedule_body<'a>(scheduler: &Ident, name: &Ident, app: &'a App) -> proc_m
let (dequeue, enqueue) = if scheduler_is_init { let (dequeue, enqueue) = if scheduler_is_init {
// `init` has exclusive access to these queues so we can bypass the resources AND // `init` has exclusive access to these queues so we can bypass the resources AND
// the consumer / producer split // the consumer / producer split
let dequeue = if cfg!(feature = "nightly") { let dequeue = quote!(#fq.dequeue());
quote!(#fq.dequeue())
} else {
quote!((*#fq.as_mut_ptr()).dequeue())
};
(dequeue, quote!((*TQ.as_mut_ptr()).enqueue_unchecked(nr);)) (dequeue, quote!((*TQ.as_mut_ptr()).enqueue_unchecked(nr);))
} else { } else {

View file

@ -8,8 +8,8 @@ pub use cortex_m::{
asm::wfi, interrupt, peripheral::scb::SystemHandler, peripheral::syst::SystClkSource, asm::wfi, interrupt, peripheral::scb::SystemHandler, peripheral::syst::SystClkSource,
peripheral::Peripherals, peripheral::Peripherals,
}; };
pub use heapless::consts; use heapless::spsc::SingleCore;
use heapless::spsc::{Queue, SingleCore}; pub use heapless::{consts, i, spsc::Queue};
#[cfg(feature = "timer-queue")] #[cfg(feature = "timer-queue")]
pub use crate::tq::{NotReady, TimerQueue}; pub use crate::tq::{NotReady, TimerQueue};