tasks / idle have exclusive access to Threshold, but do not own the token

This commit is contained in:
Jorge Aparicio 2017-07-18 20:03:22 -05:00
parent a2b0c9e0d0
commit 97a7e38db7
10 changed files with 61 additions and 17 deletions

View file

@ -50,8 +50,8 @@ fn idle(
.iter() .iter()
.all(|resource| ownerships[resource].is_owned()) .all(|resource| ownerships[resource].is_owned())
{ {
tys.push(quote!(#krate::Threshold)); tys.push(quote!(&mut #krate::Threshold));
exprs.push(quote!(unsafe { #krate::Threshold::new(0) })); exprs.push(quote!(unsafe { &mut #krate::Threshold::new(0) }));
} }
if !app.idle.locals.is_empty() { if !app.idle.locals.is_empty() {

View file

@ -221,10 +221,10 @@ macro_rules! task {
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn $NAME() { pub unsafe extern "C" fn $NAME() {
let f: fn($crate::Threshold, ::$NAME::Resources) = $body; let f: fn(&mut $crate::Threshold, ::$NAME::Resources) = $body;
f( f(
$crate::Threshold::new(::$NAME::$NAME), &mut $crate::Threshold::new(::$NAME::$NAME),
::$NAME::Resources::new(), ::$NAME::Resources::new(),
); );
} }
@ -240,7 +240,7 @@ macro_rules! task {
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn $NAME() { pub unsafe extern "C" fn $NAME() {
let f: fn( let f: fn(
$crate::Threshold, &mut $crate::Threshold,
&mut $local, &mut $local,
::$NAME::Resources, ::$NAME::Resources,
) = $body; ) = $body;
@ -250,7 +250,7 @@ macro_rules! task {
}; };
f( f(
$crate::Threshold::new(::$NAME::$NAME), &mut $crate::Threshold::new(::$NAME::$NAME),
&mut LOCAL, &mut LOCAL,
::$NAME::Resources::new(), ::$NAME::Resources::new(),
); );

View file

@ -28,8 +28,8 @@ fn idle() -> ! {
task!(EXTI0, exti0); task!(EXTI0, exti0);
fn exti0(_t: Threshold, _r: EXTI0::Resources) {} fn exti0(_t: &mut Threshold, _r: EXTI0::Resources) {}
task!(EXTI0, exti1); task!(EXTI0, exti1);
fn exti1(_t: Threshold, _r: EXTI0::Resources) {} fn exti1(_t: &mut Threshold, _r: EXTI0::Resources) {}

View file

@ -0,0 +1,44 @@
#![deny(warnings)]
#![feature(const_fn)]
#![feature(proc_macro)]
#[macro_use(task)]
extern crate cortex_m_rtfm as rtfm;
extern crate stm32f103xx;
use rtfm::{app, Threshold};
app! {
device: stm32f103xx,
tasks: {
EXTI0: {
enabled: true,
priority: 1,
},
}
}
fn init(_p: init::Peripherals) {}
fn idle() -> ! {
loop {}
}
task!(EXTI0, exti0, Old {
token: Option<Threshold> = None;
});
fn exti0(nt: &mut Threshold, old: &mut Old, _r: EXTI0::Resources) {
if let Some(ot) = old.token.take() {
let _: (Threshold, Threshold) = (*nt, ot);
//~^ error cannot move out of borrowed content
return
}
// ERROR can't store a threshold token in a local variable, otherwise you
// would end up with two threshold tokens in a task (see `if let` above)
old.token = Some(*nt);
//~^ error cannot move out of borrowed content
}

View file

@ -45,7 +45,7 @@ fn idle() -> ! {
task!(EXTI0, exti0); task!(EXTI0, exti0);
fn exti0(mut t: Threshold, r: EXTI0::Resources) { fn exti0(mut t: &mut Threshold, r: EXTI0::Resources) {
// OK need to lock to access the resource // OK need to lock to access the resource
if r.STATE.claim(&mut t, |state, _| **state) {} if r.STATE.claim(&mut t, |state, _| **state) {}
@ -55,7 +55,7 @@ fn exti0(mut t: Threshold, r: EXTI0::Resources) {
task!(EXTI1, exti1); task!(EXTI1, exti1);
fn exti1(mut t: Threshold, r: EXTI1::Resources) { fn exti1(mut t: &mut Threshold, r: EXTI1::Resources) {
// ERROR no need to lock. Has direct access because priority == ceiling // ERROR no need to lock. Has direct access because priority == ceiling
if r.STATE.claim(&mut t, |state, _| **state) { if r.STATE.claim(&mut t, |state, _| **state) {
//~^ error no method named `claim` found for type //~^ error no method named `claim` found for type

View file

@ -26,4 +26,4 @@ fn idle() -> ! {
task!(SYS_TICK, sys_tick); task!(SYS_TICK, sys_tick);
fn sys_tick(_: Threshold, _: SYS_TICK::Resources) {} fn sys_tick(_: &mut Threshold, _: SYS_TICK::Resources) {}

View file

@ -26,4 +26,4 @@ fn idle() -> ! {
task!(SYS_TICK, sys_tick); task!(SYS_TICK, sys_tick);
fn sys_tick(_: Threshold, _: SYS_TICK::Resources) {} fn sys_tick(_: &mut Threshold, _: SYS_TICK::Resources) {}

View file

@ -38,7 +38,7 @@ fn idle() -> ! {
task!(EXTI0, exti0); task!(EXTI0, exti0);
fn exti0(mut t: Threshold, r: EXTI0::Resources) { fn exti0(mut t: &mut Threshold, r: EXTI0::Resources) {
// ERROR token should not outlive the critical section // ERROR token should not outlive the critical section
let t = r.STATE.claim(&mut t, |_state, t| t); let t = r.STATE.claim(&mut t, |_state, t| t);
//~^ error cannot infer an appropriate lifetime //~^ error cannot infer an appropriate lifetime
@ -46,4 +46,4 @@ fn exti0(mut t: Threshold, r: EXTI0::Resources) {
task!(EXTI1, exti1); task!(EXTI1, exti1);
fn exti1(_t: Threshold, _r: EXTI1::Resources) {} fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {}

View file

@ -32,4 +32,4 @@ fn idle() -> ! {
task!(EXTI0, exti0); task!(EXTI0, exti0);
fn exti0(_t: Threshold, _r: EXTI0::Resources) {} fn exti0(_t: &mut Threshold, _r: EXTI0::Resources) {}

View file

@ -39,7 +39,7 @@ fn idle() -> ! {
task!(EXTI0, exti0); task!(EXTI0, exti0);
fn exti0(mut ot: Threshold, r: EXTI0::Resources) { fn exti0(mut ot: &mut Threshold, r: EXTI0::Resources) {
r.A.claim(&mut ot, |_a, mut _it| { r.A.claim(&mut ot, |_a, mut _it| {
//~^ error cannot borrow `ot` as mutable more than once at a time //~^ error cannot borrow `ot` as mutable more than once at a time
//~| error cannot borrow `ot` as mutable more than once at a time //~| error cannot borrow `ot` as mutable more than once at a time
@ -50,4 +50,4 @@ fn exti0(mut ot: Threshold, r: EXTI0::Resources) {
task!(EXTI1, exti1); task!(EXTI1, exti1);
fn exti1(_t: Threshold, r: EXTI1::Resources) {} fn exti1(_t: &mut Threshold, r: EXTI1::Resources) {}