mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +01:00
wip tests do pass, MutexStruct based
This commit is contained in:
parent
20602bd77c
commit
b138cc1631
8 changed files with 76 additions and 40 deletions
|
@ -143,22 +143,15 @@ pub fn codegen(
|
|||
);
|
||||
let ident_mut = util::shared_resources_ident_mut(ctxt, app);
|
||||
|
||||
let item = quote!(
|
||||
let mut items = vec![];
|
||||
items.push(quote!(
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[doc = #doc]
|
||||
pub struct #ident<#lt> {
|
||||
#(#fields,)*
|
||||
}
|
||||
|
||||
// Used by the lock-all API
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[doc = #doc_mut]
|
||||
pub struct #ident_mut<#lt> {
|
||||
#(#fields_mut,)*
|
||||
}
|
||||
);
|
||||
));
|
||||
|
||||
let arg = if ctxt.is_init() {
|
||||
None
|
||||
|
@ -166,7 +159,16 @@ pub fn codegen(
|
|||
Some(quote!(priority: &#lt rtic::export::Priority))
|
||||
};
|
||||
|
||||
let (lock_all, get_prio) = if let Some(name) = field_get_prio {
|
||||
let (lock_all, new_struct, get_prio) = if let Some(name) = field_get_prio {
|
||||
items.push(quote!(
|
||||
// Used by the lock-all API
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[doc = #doc_mut]
|
||||
pub struct #ident_mut<#lt> {
|
||||
#(#fields_mut,)*
|
||||
}
|
||||
));
|
||||
(
|
||||
util::impl_mutex_struct(
|
||||
extra,
|
||||
|
@ -177,6 +179,17 @@ pub fn codegen(
|
|||
quote!(self.priority()),
|
||||
quote!(|| { #ident_mut::new() }),
|
||||
),
|
||||
quote!(
|
||||
// Used by the lock-all API
|
||||
impl<#lt> #ident_mut<#lt> {
|
||||
#[inline(always)]
|
||||
pub unsafe fn new() -> Self {
|
||||
#ident_mut {
|
||||
#(#values_mut,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
),
|
||||
quote!(
|
||||
// Used by the lock-all API
|
||||
#[inline(always)]
|
||||
|
@ -186,7 +199,14 @@ pub fn codegen(
|
|||
),
|
||||
)
|
||||
} else {
|
||||
(quote!(), quote!())
|
||||
items.push(quote!(
|
||||
// Used by the lock-all API
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[doc = #doc_mut]
|
||||
pub struct #ident_mut {}
|
||||
));
|
||||
(quote!(), quote!(), quote!())
|
||||
};
|
||||
|
||||
let implementations = quote!(
|
||||
|
@ -201,18 +221,10 @@ pub fn codegen(
|
|||
#get_prio
|
||||
}
|
||||
|
||||
// Used by the lock-all API
|
||||
impl<#lt> #ident_mut<#lt> {
|
||||
#[inline(always)]
|
||||
pub unsafe fn new() -> Self {
|
||||
#ident_mut {
|
||||
#(#values_mut,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
#new_struct
|
||||
|
||||
#lock_all
|
||||
);
|
||||
|
||||
(item, implementations)
|
||||
(quote!(#(#items)*), implementations)
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ pub fn impl_mutex_struct(
|
|||
type T = #ty;
|
||||
|
||||
#[inline(always)]
|
||||
fn lock<RTIC_INTERNAL_R>(&mut self, f: impl FnOnce(#ty) -> RTIC_INTERNAL_R) -> RTIC_INTERNAL_R {
|
||||
fn lock<RTIC_INTERNAL_R>(&mut self, f: impl FnOnce(&mut #ty) -> RTIC_INTERNAL_R) -> RTIC_INTERNAL_R {
|
||||
/// Priority ceiling
|
||||
const CEILING: u8 = #ceiling;
|
||||
|
||||
|
|
|
@ -175,26 +175,27 @@ pub unsafe fn lock_struct<T, R>(
|
|||
priority: &Priority,
|
||||
ceiling: u8,
|
||||
nvic_prio_bits: u8,
|
||||
f: impl FnOnce(T) -> R,
|
||||
f: impl FnOnce(&mut T) -> R,
|
||||
) -> R {
|
||||
let current = priority.get();
|
||||
|
||||
if current < ceiling {
|
||||
if ceiling == (1 << nvic_prio_bits) {
|
||||
priority.set(u8::max_value());
|
||||
let r = interrupt::free(|_| f(ptr()));
|
||||
let r = interrupt::free(|_| f(&mut ptr()));
|
||||
priority.set(current);
|
||||
r
|
||||
} else {
|
||||
priority.set(ceiling);
|
||||
basepri::write(logical2hw(ceiling, nvic_prio_bits));
|
||||
let r = f(ptr()); // inside of lock
|
||||
let r = f(&mut ptr()); // inside of lock
|
||||
cortex_m::asm::nop();
|
||||
basepri::write(logical2hw(current, nvic_prio_bits));
|
||||
priority.set(current);
|
||||
r
|
||||
}
|
||||
} else {
|
||||
f(ptr())
|
||||
f(&mut ptr())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,6 +227,34 @@ pub unsafe fn lock<T, R>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Lock the resource proxy by setting the PRIMASK
|
||||
/// and running the closure with interrupt::free
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Writing to the PRIMASK
|
||||
/// Dereferencing a raw pointer
|
||||
#[cfg(not(armv7m))]
|
||||
#[inline(always)]
|
||||
pub unsafe fn lock_struct<T, R>(
|
||||
ptr: impl Fn() -> T,
|
||||
priority: &Priority,
|
||||
ceiling: u8,
|
||||
_nvic_prio_bits: u8,
|
||||
f: impl FnOnce(&mut T) -> R,
|
||||
) -> R {
|
||||
let current = priority.get();
|
||||
|
||||
if current < ceiling {
|
||||
priority.set(u8::max_value());
|
||||
let r = interrupt::free(|_| f(&mut ptr()));
|
||||
priority.set(current);
|
||||
r
|
||||
} else {
|
||||
f(&mut ptr())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 {
|
||||
((1 << nvic_prio_bits) - logical) << (8 - nvic_prio_bits)
|
||||
|
|
|
@ -111,5 +111,5 @@ pub trait MutexStruct {
|
|||
type T;
|
||||
|
||||
/// Creates a critical section and grants temporary access to the protected data
|
||||
fn lock<R>(&mut self, f: impl FnOnce(Self::T) -> R) -> R;
|
||||
fn lock<R>(&mut self, f: impl FnOnce(&mut Self::T) -> R) -> R;
|
||||
}
|
||||
|
|
|
@ -4,5 +4,5 @@ error: lifetime may not live long enough
|
|||
20 | let _ = c.shared.lock(|s| s); // lifetime
|
||||
| -- ^ returning this value requires that `'1` must outlive `'2`
|
||||
| ||
|
||||
| |return type of closure is &'2 mut __rtic_internal_fooShared
|
||||
| has type `&'1 mut __rtic_internal_fooShared`
|
||||
| |return type of closure is &'2 mut __rtic_internal_fooShared<'_>
|
||||
| has type `&'1 mut __rtic_internal_fooShared<'_>`
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
//! examples/lockall_soundness.rs
|
||||
|
||||
#![deny(unsafe_code)]
|
||||
#![deny(warnings)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use panic_semihosting as _;
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
error: lifetime may not live long enough
|
||||
--> ui/lockall_lifetime_destruct_field.rs:28:13
|
||||
--> ui/lockall_lifetime_destruct_field.rs:23:13
|
||||
|
|
||||
27 | let _ = c.shared.lock(|foo::Shared { a }| {
|
||||
22 | let _ = c.shared.lock(|foo::Shared { a }| {
|
||||
| ------------------ return type of closure is &'2 mut &mut u32
|
||||
| |
|
||||
| has type `&'1 mut __rtic_internal_fooShared`
|
||||
28 | a // lifetime
|
||||
| has type `&'1 mut __rtic_internal_fooShared<'_>`
|
||||
23 | a // lifetime
|
||||
| ^ returning this value requires that `'1` must outlive `'2`
|
||||
|
|
|
@ -5,4 +5,4 @@ error: lifetime may not live long enough
|
|||
| -- ^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
|
||||
| ||
|
||||
| |return type of closure is &'2 mut u32
|
||||
| has type `&'1 mut __rtic_internal_fooShared`
|
||||
| has type `&'1 mut __rtic_internal_fooShared<'_>`
|
||||
|
|
Loading…
Reference in a new issue