allow returns from checked::Resource.lock{,mut}

also add compiler barriers
This commit is contained in:
Jorge Aparicio 2017-04-07 18:14:48 -05:00
parent 8e1c72057c
commit f2bab47aa4
3 changed files with 28 additions and 7 deletions

View file

@ -1,7 +1,8 @@
[package] [package]
authors = ["Jorge Aparicio <japaricious@gmail.com>"]
build = "build.rs"
name = "cortex-m-srp" name = "cortex-m-srp"
version = "0.1.0" version = "0.1.0"
authors = ["Jorge Aparicio <japaricious@gmail.com>"]
[dependencies] [dependencies]
cortex-m = "0.2.0" cortex-m = "0.2.0"

View file

@ -51,27 +51,33 @@ where
/// Locks the resource, blocking tasks with priority equal or smaller than /// Locks the resource, blocking tasks with priority equal or smaller than
/// the ceiling `C` /// the ceiling `C`
pub fn lock<F>(&'static self, f: F) pub fn lock<R, F>(&'static self, f: F) -> R
where where
F: FnOnce(&T), F: FnOnce(&T) -> R,
{ {
unsafe { unsafe {
let old_basepri = acquire(&self.locked, C::ceiling()); let old_basepri = acquire(&self.locked, C::ceiling());
f(&*self.data.get()); ::compiler_barrier();
let ret = f(&*self.data.get());
::compiler_barrier();
release(&self.locked, old_basepri); release(&self.locked, old_basepri);
ret
} }
} }
/// Mutably locks the resource, blocking tasks with priority equal or /// Mutably locks the resource, blocking tasks with priority equal or
/// smaller than the ceiling `C` /// smaller than the ceiling `C`
pub fn lock_mut<F>(&'static self, f: F) pub fn lock_mut<R, F>(&'static self, f: F) -> R
where where
F: FnOnce(&mut T), F: FnOnce(&mut T) -> R,
{ {
unsafe { unsafe {
let old_basepri = acquire(&self.locked, C::ceiling()); let old_basepri = acquire(&self.locked, C::ceiling());
f(&mut *self.data.get()); ::compiler_barrier();
let ret = f(&mut *self.data.get());
::compiler_barrier();
release(&self.locked, old_basepri); release(&self.locked, old_basepri);
ret
} }
} }
} }

View file

@ -105,7 +105,9 @@ where
lock_check(ceiling); lock_check(ceiling);
let old_basepri = basepri::read(); let old_basepri = basepri::read();
basepri_max::write(ceiling); basepri_max::write(ceiling);
compiler_barrier();
let ret = f(&*res, ptr::read(0 as *const _)); let ret = f(&*res, ptr::read(0 as *const _));
compiler_barrier();
basepri::write(old_basepri); basepri::write(old_basepri);
ret ret
} }
@ -121,11 +123,23 @@ where
lock_check(ceiling); lock_check(ceiling);
let old_basepri = basepri::read(); let old_basepri = basepri::read();
basepri_max::write(ceiling); basepri_max::write(ceiling);
compiler_barrier();
let ret = f(&mut *res, ptr::read(0 as *const _)); let ret = f(&mut *res, ptr::read(0 as *const _));
compiler_barrier();
basepri::write(old_basepri); basepri::write(old_basepri);
ret ret
} }
fn compiler_barrier() {
unsafe {
asm!(""
:
:
: "memory"
: "volatile");
}
}
/// A peripheral as a resource /// A peripheral as a resource
pub struct ResourceP<P, Ceiling> pub struct ResourceP<P, Ceiling>
where where