don't let the ceiling token escape the critical section

This commit is contained in:
Jorge Aparicio 2017-04-19 14:12:11 -05:00
parent 70f573a6c4
commit aee1d785a9
2 changed files with 19 additions and 4 deletions

View file

@ -110,7 +110,7 @@ impl<T, CEILING> Resource<T, C<CEILING>> {
/// [Resource.borrow](struct.Resource.html#method.borrow). /// [Resource.borrow](struct.Resource.html#method.borrow).
#[cfg(not(thumbv6m))] #[cfg(not(thumbv6m))]
pub fn lock<R, PRIORITY, F>(&'static self, _priority: &P<PRIORITY>, f: F) -> R pub fn lock<R, PRIORITY, F>(&'static self, _priority: &P<PRIORITY>, f: F) -> R
where F: FnOnce(Ref<T>, C<CEILING>) -> R, where F: FnOnce(Ref<T>, &C<CEILING>) -> R,
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less> + Level CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less> + Level
{ {
unsafe { unsafe {
@ -118,7 +118,7 @@ impl<T, CEILING> Resource<T, C<CEILING>> {
basepri_max::write(<CEILING>::hw()); basepri_max::write(<CEILING>::hw());
barrier!(); barrier!();
let ret = let ret =
f(Ref::new(&*self.data.get()), C { _marker: PhantomData }); f(Ref::new(&*self.data.get()), &C { _marker: PhantomData });
barrier!(); barrier!();
basepri::write(old_basepri); basepri::write(old_basepri);
ret ret
@ -209,7 +209,7 @@ impl<Periph, CEILING> Peripheral<Periph, C<CEILING>> {
/// See [Resource.lock](./struct.Resource.html#method.lock) /// See [Resource.lock](./struct.Resource.html#method.lock)
#[cfg(not(thumbv6m))] #[cfg(not(thumbv6m))]
pub fn lock<R, PRIORITY, F>(&'static self, _priority: &P<PRIORITY>, f: F) -> R pub fn lock<R, PRIORITY, F>(&'static self, _priority: &P<PRIORITY>, f: F) -> R
where F: FnOnce(Ref<Periph>, C<CEILING>) -> R, where F: FnOnce(Ref<Periph>, &C<CEILING>) -> R,
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less> + Level CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less> + Level
{ {
unsafe { unsafe {
@ -218,7 +218,7 @@ impl<Periph, CEILING> Peripheral<Periph, C<CEILING>> {
barrier!(); barrier!();
let ret = f( let ret = f(
Ref::new(&*self.peripheral.get()), Ref::new(&*self.peripheral.get()),
C { _marker: PhantomData }, &C { _marker: PhantomData },
); );
barrier!(); barrier!();
basepri::write(old_basepri); basepri::write(old_basepri);

15
tests/cfail/ceiling.rs Normal file
View file

@ -0,0 +1,15 @@
extern crate cortex_m_srp;
use cortex_m_srp::{C3, P2, Resource};
static R1: Resource<(), C3> = Resource::new(());
fn j1(prio: P2) {
let c3 = R1.lock(&prio, |r1, c3| {
// forbidden: ceiling token can't outlive critical section
c3 //~ error
});
// Would be bad: lockless access to a resource with ceiling = 3
let r2 = R1.borrow(&prio, c3);
}