aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Aparicio <japaricious@gmail.com>2017-04-07 18:14:48 -0500
committerJorge Aparicio <japaricious@gmail.com>2017-04-07 18:14:48 -0500
commitf2bab47aa4bdd04f79e608debe64e3ddcea07702 (patch)
tree5626aba835b65a100fbefdb6f1f33a27bcfe81ce
parent8e1c72057c6fdd09ad14e9b69596e17fcfd9335f (diff)
allow returns from checked::Resource.lock{,mut}
also add compiler barriers
-rw-r--r--Cargo.toml3
-rw-r--r--src/checked.rs18
-rw-r--r--src/lib.rs14
3 files changed, 28 insertions, 7 deletions
diff --git a/Cargo.toml b/Cargo.toml
index f3d9926..1ca881e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,8 @@
[package]
+authors = ["Jorge Aparicio <japaricious@gmail.com>"]
+build = "build.rs"
name = "cortex-m-srp"
version = "0.1.0"
-authors = ["Jorge Aparicio <japaricious@gmail.com>"]
[dependencies]
cortex-m = "0.2.0"
diff --git a/src/checked.rs b/src/checked.rs
index fbdf692..4c91c05 100644
--- a/src/checked.rs
+++ b/src/checked.rs
@@ -51,27 +51,33 @@ where
/// Locks the resource, blocking tasks with priority equal or smaller than
/// the ceiling `C`
- pub fn lock<F>(&'static self, f: F)
+ pub fn lock<R, F>(&'static self, f: F) -> R
where
- F: FnOnce(&T),
+ F: FnOnce(&T) -> R,
{
unsafe {
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);
+ ret
}
}
/// Mutably locks the resource, blocking tasks with priority equal or
/// 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
- F: FnOnce(&mut T),
+ F: FnOnce(&mut T) -> R,
{
unsafe {
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);
+ ret
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 95aa8ba..7cd0ff6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -105,7 +105,9 @@ where
lock_check(ceiling);
let old_basepri = basepri::read();
basepri_max::write(ceiling);
+ compiler_barrier();
let ret = f(&*res, ptr::read(0 as *const _));
+ compiler_barrier();
basepri::write(old_basepri);
ret
}
@@ -121,11 +123,23 @@ where
lock_check(ceiling);
let old_basepri = basepri::read();
basepri_max::write(ceiling);
+ compiler_barrier();
let ret = f(&mut *res, ptr::read(0 as *const _));
+ compiler_barrier();
basepri::write(old_basepri);
ret
}
+fn compiler_barrier() {
+ unsafe {
+ asm!(""
+ :
+ :
+ : "memory"
+ : "volatile");
+ }
+}
+
/// A peripheral as a resource
pub struct ResourceP<P, Ceiling>
where