From a94de6bafcd95c0313e638138643f87c3b0e6aa0 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 14 Apr 2017 09:45:50 -0500 Subject: [PATCH] wrap references to resources in static-ref's Ref/RefMut to assert that they point to `static` data --- Cargo.toml | 1 + src/lib.rs | 38 ++++++++++++++++++++++---------------- tests/cfail/claim_mut.rs | 14 +++++++------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3bc0347d21..3304796921 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ syn = "0.11.10" [dependencies] cortex-m = "0.2.2" typenum = "1.7.0" +static-ref = { git = "https://github.com/japaric/static-ref" } [dev-dependencies] compiletest_rs = "0.2.5" diff --git a/src/lib.rs b/src/lib.rs index bec006dbdb..ba5e0dc7c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ #![no_std] extern crate cortex_m; +extern crate static_ref; extern crate typenum; use core::cell::UnsafeCell; @@ -16,6 +17,7 @@ use cortex_m::ctxt::Context; use cortex_m::interrupt::Nr; #[cfg(not(thumbv6m))] use cortex_m::register::{basepri, basepri_max}; +use static_ref::{Ref, RefMut}; use typenum::{Cmp, Equal, Unsigned}; #[cfg(not(thumbv6m))] use typenum::{Greater, Less}; @@ -64,12 +66,12 @@ impl Resource> { &'static self, _priority: &P, _system_ceiling: &'cs C, - ) -> &'cs T + ) -> Ref<'cs, T> where SCEILING: GreaterThanOrEqual, CEILING: GreaterThanOrEqual, { - unsafe { &*self.data.get() } + unsafe { Ref::new(&*self.data.get()) } } /// Claims the resource at the task with highest priority @@ -78,11 +80,11 @@ impl Resource> { pub fn claim<'task, PRIORITY>( &'static self, _priority: &'task P, - ) -> &'task T + ) -> Ref<'task, T> where CEILING: Cmp, { - unsafe { &*self.data.get() } + unsafe { Ref::new(&*self.data.get()) } } /// Like [Resource.claim](struct.Resource.html#method.claim) but returns a @@ -90,11 +92,11 @@ impl Resource> { pub fn claim_mut<'task, PRIORITY>( &'static self, _priority: &'task mut P, - ) -> &'task mut T + ) -> RefMut<'task, T> where CEILING: Cmp, { - unsafe { &mut *self.data.get() } + unsafe { RefMut::new(&mut *self.data.get()) } } /// Locks the resource for the duration of the critical section `f` @@ -113,7 +115,7 @@ impl Resource> { f: F, ) -> R where - F: FnOnce(&T, C) -> R, + F: FnOnce(Ref, C) -> R, CEILING: Cmp + Cmp + Level, { @@ -121,7 +123,8 @@ impl Resource> { let old_basepri = basepri::read(); basepri_max::write(::hw()); barrier!(); - let ret = f(&*self.data.get(), C { _marker: PhantomData }); + let ret = + f(Ref::new(&*self.data.get()), C { _marker: PhantomData }); barrier!(); basepri::write(old_basepri); ret @@ -141,7 +144,7 @@ impl Resource> { f: F, ) -> R where - F: FnOnce(&mut T) -> R, + F: FnOnce(RefMut) -> R, CEILING: Cmp + Cmp + Level, { @@ -149,7 +152,7 @@ impl Resource> { let old_basepri = basepri::read(); basepri_max::write(::hw()); barrier!(); - let ret = f(&mut *self.data.get()); + let ret = f(RefMut::new(&mut *self.data.get())); barrier!(); basepri::write(old_basepri); ret @@ -196,23 +199,23 @@ impl Peripheral> { &'static self, _priority: &P, _system_ceiling: &'cs C, - ) -> &'cs Periph + ) -> Ref<'cs, Periph> where SCEILING: GreaterThanOrEqual, CEILING: GreaterThanOrEqual, { - unsafe { &*self.peripheral.get() } + unsafe { Ref::new(&*self.peripheral.get()) } } /// See [Resource.claim](./struct.Resource.html#method.claim) pub fn claim<'task, PRIORITY>( &'static self, _priority: &'task P, - ) -> &'task Periph + ) -> Ref<'task, Periph> where CEILING: Cmp, { - unsafe { &*self.peripheral.get() } + unsafe { Ref::new(&*self.peripheral.get()) } } /// See [Resource.lock](./struct.Resource.html#method.lock) @@ -223,7 +226,7 @@ impl Peripheral> { f: F, ) -> R where - F: FnOnce(&Periph, C) -> R, + F: FnOnce(Ref, C) -> R, CEILING: Cmp + Cmp + Level, { @@ -231,7 +234,10 @@ impl Peripheral> { let old_basepri = basepri::read(); basepri_max::write(::hw()); barrier!(); - let ret = f(&*self.peripheral.get(), C { _marker: PhantomData }); + let ret = f( + Ref::new(&*self.peripheral.get()), + C { _marker: PhantomData }, + ); barrier!(); basepri::write(old_basepri); ret diff --git a/tests/cfail/claim_mut.rs b/tests/cfail/claim_mut.rs index 0d1dffd5aa..50da4a61f2 100644 --- a/tests/cfail/claim_mut.rs +++ b/tests/cfail/claim_mut.rs @@ -8,26 +8,26 @@ static R1: Resource = Resource::new(0); fn j1(mut prio: P2) { // OK only one `&mut-` reference to the data - let r1: &mut i32 = R1.claim_mut(&mut prio); + let r1 = R1.claim_mut(&mut prio); } fn j2(prio: P2) { // OK two `&-` references to the same data - let r1: &i32 = R1.claim(&prio); - let another_r1: &i32 = R1.claim(&prio); + let r1 = R1.claim(&prio); + let another_r1 = R1.claim(&prio); } fn j3(mut prio: P2) { // CAN'T have a `&-` reference and a `&mut-` reference to the same data - let r1: &i32 = R1.claim(&prio); - let another_r1: &mut i32 = R1.claim_mut(&mut prio); + let r1 = R1.claim(&prio); + let another_r1 = R1.claim_mut(&mut prio); //~^ error } fn j4(mut prio: P2) { // CAN'T have two `&mut-` references to the same data - let r1: &mut i32 = R1.claim_mut(&mut prio); - let another_r1: &mut i32 = R1.claim_mut(&mut prio); + let r1 = R1.claim_mut(&mut prio); + let another_r1 = R1.claim_mut(&mut prio); //~^ error }