drop rtfm::Cell

This commit is contained in:
Jorge Aparicio 2017-07-23 20:51:37 -05:00
parent 03f373fb24
commit f3b397f460
2 changed files with 40 additions and 56 deletions

View file

@ -11,6 +11,7 @@ pub fn app(app: &App, ownerships: &Ownerships) -> Tokens {
let mut root = vec![]; let mut root = vec![];
let mut main = vec![]; let mut main = vec![];
::trans::check(app, &mut main);
::trans::init(app, &mut main, &mut root); ::trans::init(app, &mut main, &mut root);
::trans::idle(app, ownerships, &mut main, &mut root); ::trans::idle(app, ownerships, &mut main, &mut root);
::trans::resources(app, ownerships, &mut root); ::trans::resources(app, ownerships, &mut root);
@ -26,6 +27,22 @@ pub fn app(app: &App, ownerships: &Ownerships) -> Tokens {
quote!(#(#root)*) quote!(#(#root)*)
} }
fn check(app: &App, main: &mut Vec<Tokens>) {
if !app.resources.is_empty() {
main.push(quote! {
fn is_send<T>() where T: Send {}
});
}
for resource in app.resources.values() {
let ty = &resource.ty;
main.push(quote! {
is_send::<#ty>();
});
}
}
fn idle( fn idle(
app: &App, app: &App,
ownerships: &Ownerships, ownerships: &Ownerships,
@ -79,7 +96,7 @@ fn idle(
rexprs.push(quote! { rexprs.push(quote! {
#name: #krate::Static::ref_mut( #name: #krate::Static::ref_mut(
&mut *#super_::#name.get(), &mut #super_::#name,
), ),
}); });
} else { } else {
@ -180,7 +197,7 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
}); });
rexprs.push(quote! { rexprs.push(quote! {
#name: ::#krate::Static::ref_mut(&mut *super::#name.get()), #name: ::#krate::Static::ref_mut(&mut super::#name),
}); });
} }
@ -288,14 +305,12 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
match *ownership { match *ownership {
Ownership::Owned { .. } => { Ownership::Owned { .. } => {
if let Some(resource) = app.resources.get(name) { if let Some(resource) = app.resources.get(name) {
// For owned resources we don't need claim() or borrow(), // For owned resources we don't need claim() or borrow()
// just get()
let expr = &resource.expr; let expr = &resource.expr;
let ty = &resource.ty; let ty = &resource.ty;
root.push(quote! { root.push(quote! {
static #name: #krate::Cell<#ty> = static mut #name: #ty = #expr;
#krate::Cell::new(#expr);
}); });
} else { } else {
// Peripheral // Peripheral
@ -308,8 +323,7 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
let ty = &resource.ty; let ty = &resource.ty;
root.push(quote! { root.push(quote! {
static #name: #krate::Cell<#ty> = static mut #name: #ty = #expr;
#krate::Cell::new(#expr);
}); });
impl_items.push(quote! { impl_items.push(quote! {
@ -319,7 +333,7 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
&'cs self, &'cs self,
_cs: &'cs #krate::CriticalSection, _cs: &'cs #krate::CriticalSection,
) -> &'cs #krate::Static<#ty> { ) -> &'cs #krate::Static<#ty> {
unsafe { #krate::Static::ref_(&*#name.get()) } unsafe { #krate::Static::ref_(&#name) }
} }
fn borrow_mut<'cs>( fn borrow_mut<'cs>(
@ -327,7 +341,7 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
_cs: &'cs #krate::CriticalSection, _cs: &'cs #krate::CriticalSection,
) -> &'cs mut #krate::Static<#ty> { ) -> &'cs mut #krate::Static<#ty> {
unsafe { unsafe {
#krate::Static::ref_mut(&mut *#name.get()) #krate::Static::ref_mut(&mut #name)
} }
} }
@ -343,12 +357,11 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
{ {
unsafe { unsafe {
#krate::claim( #krate::claim(
#name.get(), #krate::Static::ref_(&#name),
#ceiling, #ceiling,
#device::NVIC_PRIO_BITS, #device::NVIC_PRIO_BITS,
t, t,
f, f,
|data| #krate::Static::ref_(&*data),
) )
} }
} }
@ -365,12 +378,11 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
{ {
unsafe { unsafe {
#krate::claim( #krate::claim(
#name.get(), #krate::Static::ref_mut(&mut #name),
#ceiling, #ceiling,
#device::NVIC_PRIO_BITS, #device::NVIC_PRIO_BITS,
t, t,
f, f,
|data| #krate::Static::ref_mut(&mut *data),
) )
} }
} }
@ -411,12 +423,13 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
{ {
unsafe { unsafe {
#krate::claim( #krate::claim(
#device::#name.get(), #krate::Static::ref_(
&*#device::#name.get(),
),
#ceiling, #ceiling,
#device::NVIC_PRIO_BITS, #device::NVIC_PRIO_BITS,
t, t,
f, f,
|data| #krate::Static::ref_(&*data),
) )
} }
} }
@ -433,12 +446,13 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
{ {
unsafe { unsafe {
#krate::claim( #krate::claim(
#device::#name.get(), #krate::Static::ref_mut(
&mut *#device::#name.get(),
),
#ceiling, #ceiling,
#device::NVIC_PRIO_BITS, #device::NVIC_PRIO_BITS,
t, t,
f, f,
|data| #krate::Static::ref_mut(&mut *data),
) )
} }
} }
@ -512,9 +526,7 @@ fn tasks(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
}); });
exprs.push(quote! { exprs.push(quote! {
#name: ::#krate::Static::ref_mut( #name: ::#krate::Static::ref_mut(&mut super::#name),
&mut *super::#name.get(),
),
}); });
} else { } else {
fields.push(quote! { fields.push(quote! {

View file

@ -63,8 +63,6 @@ extern crate cortex_m;
extern crate cortex_m_rtfm_macros; extern crate cortex_m_rtfm_macros;
extern crate static_ref; extern crate static_ref;
use core::cell::UnsafeCell;
pub use cortex_m::asm::{bkpt, wfi}; pub use cortex_m::asm::{bkpt, wfi};
pub use cortex_m::interrupt::CriticalSection; pub use cortex_m::interrupt::CriticalSection;
pub use cortex_m::interrupt::free as atomic; pub use cortex_m::interrupt::free as atomic;
@ -137,68 +135,42 @@ impl<T> Resource for Static<T> {
} }
#[doc(hidden)] #[doc(hidden)]
pub unsafe fn claim<T, U, R, F, G>( pub unsafe fn claim<T, R, F>(
data: *mut T, data: T,
ceiling: u8, ceiling: u8,
nvic_prio_bits: u8, nvic_prio_bits: u8,
t: &mut Threshold, t: &mut Threshold,
f: F, f: F,
g: G,
) -> R ) -> R
where where
F: FnOnce(U, &mut Threshold) -> R, F: FnOnce(T, &mut Threshold) -> R,
G: FnOnce(*mut T) -> U,
{ {
let max_priority = 1 << nvic_prio_bits; let max_priority = 1 << nvic_prio_bits;
if ceiling > t.value { if ceiling > t.value {
match () { match () {
#[cfg(armv6m)] #[cfg(armv6m)]
() => { () => {
atomic(|_| f(g(data), &mut Threshold::new(max_priority))) atomic(|_| f(data, &mut Threshold::new(max_priority)))
} }
#[cfg(not(armv6m))] #[cfg(not(armv6m))]
() => { () => {
if ceiling == max_priority { if ceiling == max_priority {
atomic(|_| f(g(data), &mut Threshold::new(max_priority))) atomic(|_| f(data, &mut Threshold::new(max_priority)))
} else { } else {
let old = basepri::read(); let old = basepri::read();
let hw = (max_priority - ceiling) << (8 - nvic_prio_bits); let hw = (max_priority - ceiling) << (8 - nvic_prio_bits);
basepri_max::write(hw); basepri_max::write(hw);
let ret = f(g(data), &mut Threshold::new(ceiling)); let ret = f(data, &mut Threshold::new(ceiling));
basepri::write(old); basepri::write(old);
ret ret
} }
} }
} }
} else { } else {
f(g(data), t) f(data, t)
} }
} }
#[doc(hidden)]
pub struct Cell<T> {
data: UnsafeCell<T>,
}
#[doc(hidden)]
impl<T> Cell<T> {
pub const fn new(data: T) -> Self {
Cell {
data: UnsafeCell::new(data),
}
}
pub fn get(&self) -> *mut T {
self.data.get()
}
}
unsafe impl<T> Sync for Cell<T>
where
T: Send,
{
}
/// Preemption threshold token /// Preemption threshold token
/// ///
/// The preemption threshold indicates the priority a task must have to preempt /// The preemption threshold indicates the priority a task must have to preempt