mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +01:00
implement lock_mut
This commit is contained in:
parent
fb20b51528
commit
f62af15cfd
2 changed files with 59 additions and 2 deletions
45
src/lib.rs
45
src/lib.rs
|
@ -6,15 +6,16 @@
|
|||
extern crate cortex_m;
|
||||
extern crate typenum;
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::cell::UnsafeCell;
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::Sub;
|
||||
|
||||
use cortex_m::interrupt::Nr;
|
||||
#[cfg(not(thumbv6m))]
|
||||
use cortex_m::register::{basepri, basepri_max};
|
||||
use typenum::{Cmp, Equal, Unsigned};
|
||||
#[cfg(not(thumbv6m))]
|
||||
use typenum::{Greater, Less};
|
||||
use typenum::{B1, Greater, Less, Sub1};
|
||||
|
||||
pub use cortex_m::ctxt::{Context, Local};
|
||||
#[doc(hidden)]
|
||||
|
@ -101,6 +102,10 @@ where
|
|||
/// For the duration of the critical section, tasks whose priority level is
|
||||
/// smaller than or equal to the resource `CEILING` will be prevented from
|
||||
/// preempting the current task.
|
||||
///
|
||||
/// Within this critical section, resources with ceiling equal to or smaller
|
||||
/// than `CEILING` can be borrowed at zero cost. See
|
||||
/// [Resource.borrow](struct.Resource.html#method.borrow).
|
||||
#[cfg(not(thumbv6m))]
|
||||
pub fn lock<R, PRIORITY, F>(
|
||||
&'static self,
|
||||
|
@ -130,6 +135,42 @@ where
|
|||
ret
|
||||
}
|
||||
}
|
||||
|
||||
/// Like [Resource.lock](struct.Resource.html#method.lock) but returns a
|
||||
/// `&mut-` reference
|
||||
///
|
||||
/// This method has additional an additional constraint: you can't borrow a
|
||||
/// resource that has ceiling equal `CEILING`. This constraint is required
|
||||
/// to preserve Rust aliasing rules.
|
||||
pub fn lock_mut<R, PRIORITY, F>(
|
||||
&'static self,
|
||||
_priority: &mut P<PRIORITY>,
|
||||
f: F,
|
||||
) -> R
|
||||
where
|
||||
F: FnOnce(&mut T, C<Sub1<CEILING>>) -> R,
|
||||
C<CEILING>: Ceiling,
|
||||
CEILING: Sub<B1>,
|
||||
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less>
|
||||
+ Level,
|
||||
P<PRIORITY>: Priority,
|
||||
{
|
||||
unsafe {
|
||||
let old_basepri = basepri::read();
|
||||
basepri_max::write(<CEILING>::hw());
|
||||
barrier!();
|
||||
let ret = f(
|
||||
&mut *self.data.get(),
|
||||
C {
|
||||
_0: (),
|
||||
_marker: PhantomData,
|
||||
},
|
||||
);
|
||||
barrier!();
|
||||
basepri::write(old_basepri);
|
||||
ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T, CEILING> Sync for Resource<T, CEILING>
|
||||
|
|
16
tests/cfail/lock_mut.rs
Normal file
16
tests/cfail/lock_mut.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
extern crate cortex_m_srp;
|
||||
|
||||
use cortex_m_srp::{C3, C4, P2, Resource};
|
||||
|
||||
static R1: Resource<i32, C4> = Resource::new(0);
|
||||
static R2: Resource<i32, C3> = Resource::new(0);
|
||||
|
||||
fn j1(mut prio: P2) {
|
||||
R1.lock_mut(
|
||||
&mut prio, |r1: &mut i32, c3| {
|
||||
let r2 = R2.borrow(&c3);
|
||||
let another_r1: &i32 = R1.borrow(&c3);
|
||||
//~^ error
|
||||
}
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue