mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-29 15:04:32 +01:00
add mutable variants of borrow and claim
This commit is contained in:
parent
7604400fd0
commit
4cfbf57799
1 changed files with 118 additions and 23 deletions
141
src/lib.rs
141
src/lib.rs
|
@ -24,7 +24,8 @@ const PRIORITY_BITS: u8 = 4;
|
||||||
// XXX Do we need memory / instruction / compiler barriers here?
|
// XXX Do we need memory / instruction / compiler barriers here?
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn claim<T, R, F>(f: F, res: *const T, ceiling: u8) -> R
|
unsafe fn claim<T, R, F>(f: F, res: *const T, ceiling: u8) -> R
|
||||||
where F: FnOnce(&T) -> R
|
where
|
||||||
|
F: FnOnce(&T) -> R,
|
||||||
{
|
{
|
||||||
let old_basepri = basepri::read();
|
let old_basepri = basepri::read();
|
||||||
basepri_max::write(ceiling);
|
basepri_max::write(ceiling);
|
||||||
|
@ -33,16 +34,31 @@ unsafe fn claim<T, R, F>(f: F, res: *const T, ceiling: u8) -> R
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX Do we need memory / instruction / compiler barriers here?
|
||||||
|
#[inline(always)]
|
||||||
|
unsafe fn claim_mut<T, R, F>(f: F, res: *mut T, ceiling: u8) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut T) -> R,
|
||||||
|
{
|
||||||
|
let old_basepri = basepri::read();
|
||||||
|
basepri_max::write(ceiling);
|
||||||
|
let ret = f(&mut *res);
|
||||||
|
basepri::write(old_basepri);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
/// A peripheral as a resource
|
/// A peripheral as a resource
|
||||||
pub struct ResourceP<P, Ceiling>
|
pub struct ResourceP<P, Ceiling>
|
||||||
where P: 'static
|
where
|
||||||
|
P: 'static,
|
||||||
{
|
{
|
||||||
_marker: PhantomData<Ceiling>,
|
_marker: PhantomData<Ceiling>,
|
||||||
peripheral: Peripheral<P>,
|
peripheral: Peripheral<P>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, C> ResourceP<P, C>
|
impl<P, C> ResourceP<P, C>
|
||||||
where C: CeilingLike
|
where
|
||||||
|
C: CeilingLike,
|
||||||
{
|
{
|
||||||
/// Wraps a `peripheral` into a `Resource`
|
/// Wraps a `peripheral` into a `Resource`
|
||||||
///
|
///
|
||||||
|
@ -60,34 +76,73 @@ impl<P, C> ResourceP<P, C>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, C> ResourceP<P, C>
|
impl<P, C> ResourceP<P, C>
|
||||||
where C: Ceiling
|
where
|
||||||
|
C: Ceiling,
|
||||||
{
|
{
|
||||||
/// Borrows the resource without locking
|
/// Borrows the resource without locking
|
||||||
// TODO document unsafety
|
// TODO document unsafety
|
||||||
pub unsafe fn borrow<'ctxt, Ctxt>(&'static self,
|
pub unsafe fn borrow<'ctxt, Ctxt>(
|
||||||
_ctxt: &'ctxt Ctxt)
|
&'static self,
|
||||||
-> &'ctxt P
|
_ctxt: &'ctxt Ctxt,
|
||||||
where Ctxt: Context
|
) -> &'ctxt P
|
||||||
|
where
|
||||||
|
Ctxt: Context,
|
||||||
{
|
{
|
||||||
&*self.peripheral.get()
|
&*self.peripheral.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Locks the resource, blocking tasks with priority lower than `Ceiling`
|
/// Mutably borrows the resource without locking
|
||||||
pub fn lock<R, F>(&'static self, f: F) -> R
|
// TODO document unsafety
|
||||||
where F: FnOnce(&P) -> R,
|
pub unsafe fn borrow_mut<'ctxt, Ctxt>(
|
||||||
C: Ceiling
|
&'static self,
|
||||||
|
_ctxt: &'ctxt mut Ctxt,
|
||||||
|
) -> &'ctxt mut P
|
||||||
|
where
|
||||||
|
Ctxt: Context,
|
||||||
|
{
|
||||||
|
&mut *self.peripheral.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Locks the resource, preventing tasks with priority lower than `Ceiling`
|
||||||
|
/// from preempting the current task
|
||||||
|
pub fn lock<R, F, Ctxt>(&'static self, _ctxt: &Ctxt, f: F) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(&P) -> R,
|
||||||
|
Ctxt: Context,
|
||||||
{
|
{
|
||||||
unsafe { claim(f, self.peripheral.get(), C::ceiling()) }
|
unsafe { claim(f, self.peripheral.get(), C::ceiling()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mutably locks the resource, preventing tasks with priority lower than
|
||||||
|
/// `Ceiling` from preempting the current task
|
||||||
|
pub fn lock_mut<R, F, Ctxt>(&'static self, _ctxt: &mut Ctxt, f: F) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut P) -> R,
|
||||||
|
Ctxt: Context,
|
||||||
|
{
|
||||||
|
unsafe { claim_mut(f, self.peripheral.get(), C::ceiling()) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> ResourceP<P, C0> {
|
impl<P> ResourceP<P, C0> {
|
||||||
/// Borrows the resource without locking
|
/// Borrows the resource without locking
|
||||||
pub fn borrow<'ctxt, Ctxt>(&'static self, _ctxt: &'ctxt Ctxt) -> &'ctxt P
|
pub fn borrow<'ctxt, Ctxt>(&'static self, _ctxt: &'ctxt Ctxt) -> &'ctxt P
|
||||||
where Ctxt: Context
|
where
|
||||||
|
Ctxt: Context,
|
||||||
{
|
{
|
||||||
unsafe { &*self.peripheral.get() }
|
unsafe { &*self.peripheral.get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mutably borrows the resource without locking
|
||||||
|
pub fn borrow_mut<'ctxt, Ctxt>(
|
||||||
|
&'static self,
|
||||||
|
_ctxt: &'ctxt mut Ctxt,
|
||||||
|
) -> &'ctxt mut P
|
||||||
|
where
|
||||||
|
Ctxt: Context,
|
||||||
|
{
|
||||||
|
unsafe { &mut *self.peripheral.get() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<P, C> Sync for ResourceP<P, C> {}
|
unsafe impl<P, C> Sync for ResourceP<P, C> {}
|
||||||
|
@ -106,7 +161,8 @@ impl<T, C> Resource<T, C> {
|
||||||
/// - The ceiling, `C`, must be picked to prevent two or more tasks from
|
/// - The ceiling, `C`, must be picked to prevent two or more tasks from
|
||||||
/// concurrently accessing the resource through preemption
|
/// concurrently accessing the resource through preemption
|
||||||
pub const unsafe fn new(data: T) -> Self
|
pub const unsafe fn new(data: T) -> Self
|
||||||
where C: CeilingLike
|
where
|
||||||
|
C: CeilingLike,
|
||||||
{
|
{
|
||||||
Resource {
|
Resource {
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
|
@ -116,32 +172,71 @@ impl<T, C> Resource<T, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, C> Resource<T, C>
|
impl<T, C> Resource<T, C>
|
||||||
where C: Ceiling
|
where
|
||||||
|
C: Ceiling,
|
||||||
{
|
{
|
||||||
/// Locks the resource, blocking tasks with priority lower than `ceiling`
|
/// Locks the resource, preventing tasks with priority lower than `Ceiling`
|
||||||
pub fn lock<F, R>(&'static self, f: F) -> R
|
/// from preempting the current task
|
||||||
where F: FnOnce(&T) -> R
|
pub fn lock<F, R, Ctxt>(&'static self, _ctxt: &Ctxt, f: F) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(&T) -> R,
|
||||||
|
Ctxt: Context,
|
||||||
{
|
{
|
||||||
unsafe { claim(f, self.data.get(), C::ceiling()) }
|
unsafe { claim(f, self.data.get(), C::ceiling()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mutably locks the resource, preventing tasks with priority lower than
|
||||||
|
/// `Ceiling` from preempting the current task
|
||||||
|
pub fn lock_mut<F, R, Ctxt>(&'static self, _ctxt: &mut Ctxt, f: F) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut T) -> R,
|
||||||
|
Ctxt: Context,
|
||||||
|
{
|
||||||
|
unsafe { claim_mut(f, self.data.get(), C::ceiling()) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Borrows the resource, without locking
|
/// Borrows the resource, without locking
|
||||||
pub unsafe fn borrow<'ctxt, Ctxt>(&'static self,
|
pub unsafe fn borrow<'ctxt, Ctxt>(
|
||||||
_ctxt: &'ctxt Ctxt)
|
&'static self,
|
||||||
-> &'ctxt T
|
_ctxt: &'ctxt Ctxt,
|
||||||
where Ctxt: Context
|
) -> &'ctxt T
|
||||||
|
where
|
||||||
|
Ctxt: Context,
|
||||||
{
|
{
|
||||||
&*self.data.get()
|
&*self.data.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mutably borrows the resource, without locking
|
||||||
|
pub unsafe fn borrow_mut<'ctxt, Ctxt>(
|
||||||
|
&'static self,
|
||||||
|
_ctxt: &'ctxt mut Ctxt,
|
||||||
|
) -> &'ctxt mut T
|
||||||
|
where
|
||||||
|
Ctxt: Context,
|
||||||
|
{
|
||||||
|
&mut *self.data.get()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Resource<T, C0> {
|
impl<T> Resource<T, C0> {
|
||||||
/// Borrows the resource without locking
|
/// Borrows the resource without locking
|
||||||
pub fn borrow<'ctxt, Ctxt>(&'static self, _ctxt: &'ctxt Ctxt) -> &'ctxt T
|
pub fn borrow<'ctxt, Ctxt>(&'static self, _ctxt: &'ctxt Ctxt) -> &'ctxt T
|
||||||
where Ctxt: Context
|
where
|
||||||
|
Ctxt: Context,
|
||||||
{
|
{
|
||||||
unsafe { &*self.data.get() }
|
unsafe { &*self.data.get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mutably borrows the resource without locking
|
||||||
|
pub fn borrow_mut<'ctxt, Ctxt>(
|
||||||
|
&'static self,
|
||||||
|
_ctxt: &'ctxt mut Ctxt,
|
||||||
|
) -> &'ctxt mut T
|
||||||
|
where
|
||||||
|
Ctxt: Context,
|
||||||
|
{
|
||||||
|
unsafe { &mut *self.data.get() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T, Ceiling> Sync for Resource<T, Ceiling> {}
|
unsafe impl<T, Ceiling> Sync for Resource<T, Ceiling> {}
|
||||||
|
|
Loading…
Reference in a new issue