From 6007fc4361e7bd3e40638d20b3dcaaf0c4970b45 Mon Sep 17 00:00:00 2001 From: Per Date: Wed, 4 Mar 2020 14:55:22 +0100 Subject: [PATCH] task_local and lock_free resources --- Cargo.toml | 2 +- examples/local.rs | 60 ++++++++++++++++++++++++++++++++++++++ src/ast.rs | 12 ++++++++ src/parse/late_resource.rs | 13 ++++++++- src/parse/util.rs | 19 ++++++++++++ 5 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 examples/local.rs diff --git a/Cargo.toml b/Cargo.toml index 7f487af..7794d69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ keywords = [] license = "MIT OR Apache-2.0" name = "rtfm-syntax" repository = "https://github.com/rtfm-rs/rtfm-syntax" -version = "0.4.0" +version = "0.4.1" [dependencies] indexmap = "1.0.2" diff --git a/examples/local.rs b/examples/local.rs new file mode 100644 index 0000000..d089257 --- /dev/null +++ b/examples/local.rs @@ -0,0 +1,60 @@ +//! Full syntax for single core + +#[mock::app] +const APP: () = { + struct Resources { + a: u32, + b: u32, + #[init(0)] + c: u32, + #[init(0)] + d: u32, + #[task_local] + m: u32, + #[lock_free] + e: u32u, + } + + #[init( + resources = [c], + spawn = [foo], + )] + fn init(_: init::Context) -> init::LateResources { + #[cfg(debug_assertions)] + static mut X: u32 = 0; + + init::LateResources { a: 0, b: 0 } + } + + #[idle( + resources = [&a, d, e], + spawn = [foo], + )] + fn idle(_: idle::Context) -> ! { + static mut X: u32 = 0; + + loop {} + } + + #[task( + resources = [b, &c], + spawn = [bar], + )] + fn foo(_: foo::Context) { + static mut X: u32 = 0; + + *X += 1; + } + + #[task( + capacity = 2, + priority = 2, + resources = [d], + spawn = [foo], + )] + fn bar(_: bar::Context, _: u32) { + static mut X: u32 = 0; + + *X += 1; + } +}; diff --git a/src/ast.rs b/src/ast.rs index f04ce02..6533eed 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -163,6 +163,15 @@ pub struct IdleArgs { pub(crate) _extensible: (), } +/// Resource properties +#[derive(Debug)] +pub struct ResourceProperties { + /// a task local resource + pub task_local: bool, + /// a lock free (exclusive resource) + pub lock_free: bool, +} + /// An early (compile time initialized) resource #[derive(Debug)] pub struct Resource { @@ -196,6 +205,9 @@ pub struct LateResource { /// The type of this resource pub ty: Box, + /// Resource properties + pub properties: ResourceProperties, + pub(crate) _extensible: (), } diff --git a/src/parse/late_resource.rs b/src/parse/late_resource.rs index 90e7e62..7c4f892 100644 --- a/src/parse/late_resource.rs +++ b/src/parse/late_resource.rs @@ -1,7 +1,10 @@ use proc_macro2::Span; use syn::{parse, Field, Visibility}; -use crate::{ast::LateResource, parse::util}; +use crate::{ + ast::{LateResource, ResourceProperties}, + parse::util, +}; impl LateResource { pub(crate) fn parse(item: &Field, span: Span, cores: u8) -> parse::Result { @@ -16,11 +19,19 @@ impl LateResource { let shared = util::extract_shared(&mut attrs, cores)?; + let task_local = util::extract_task_local(&mut attrs)?; + + let lock_free = util::extract_lock_free(&mut attrs)?; + Ok(LateResource { cfgs, attrs, shared, ty: Box::new(item.ty.clone()), + properties: ResourceProperties { + task_local, + lock_free, + }, _extensible: (), }) } diff --git a/src/parse/util.rs b/src/parse/util.rs index 3c0e7e0..22860b2 100644 --- a/src/parse/util.rs +++ b/src/parse/util.rs @@ -174,6 +174,25 @@ pub fn extract_shared(attrs: &mut Vec, cores: u8) -> parse::Result) -> parse::Result { + if let Some(pos) = attrs.iter().position(|attr| attr_eq(attr, "task_local")) { + attrs.remove(pos); + + Ok(true) + } else { + Ok(false) + } +} + +pub fn extract_lock_free(attrs: &mut Vec) -> parse::Result { + if let Some(pos) = attrs.iter().position(|attr| attr_eq(attr, "lock_free")) { + attrs.remove(pos); + Ok(true) + } else { + Ok(false) + } +} + pub fn parse_core(lit: LitInt, cores: u8) -> parse::Result { if !lit.suffix().is_empty() { return Err(parse::Error::new(