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 cortex_m;
|
||||||
extern crate typenum;
|
extern crate typenum;
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
use core::ops::Sub;
|
||||||
|
|
||||||
use cortex_m::interrupt::Nr;
|
use cortex_m::interrupt::Nr;
|
||||||
#[cfg(not(thumbv6m))]
|
#[cfg(not(thumbv6m))]
|
||||||
use cortex_m::register::{basepri, basepri_max};
|
use cortex_m::register::{basepri, basepri_max};
|
||||||
use typenum::{Cmp, Equal, Unsigned};
|
use typenum::{Cmp, Equal, Unsigned};
|
||||||
#[cfg(not(thumbv6m))]
|
#[cfg(not(thumbv6m))]
|
||||||
use typenum::{Greater, Less};
|
use typenum::{B1, Greater, Less, Sub1};
|
||||||
|
|
||||||
pub use cortex_m::ctxt::{Context, Local};
|
pub use cortex_m::ctxt::{Context, Local};
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -101,6 +102,10 @@ where
|
||||||
/// For the duration of the critical section, tasks whose priority level is
|
/// For the duration of the critical section, tasks whose priority level is
|
||||||
/// smaller than or equal to the resource `CEILING` will be prevented from
|
/// smaller than or equal to the resource `CEILING` will be prevented from
|
||||||
/// preempting the current task.
|
/// 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))]
|
#[cfg(not(thumbv6m))]
|
||||||
pub fn lock<R, PRIORITY, F>(
|
pub fn lock<R, PRIORITY, F>(
|
||||||
&'static self,
|
&'static self,
|
||||||
|
@ -130,6 +135,42 @@ where
|
||||||
ret
|
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>
|
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