-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] change the resource syntax #212
Comments
I approve this version. |
Hi, overall I'm positive but the RFC needs clarification on the following points for completeness:
On the extension, why would a |
It's unchanged. I'll add a note.
I would explain the resources API like this:
The Rust aliasing rule states that many shared ( The mechanism used to safely share data between tasks is the shared-exclusive lock which has the following API:
Tasks are given proxies to the shared data, AKA resources, that implement the above API based on what has been specified in the In the The DSL minimizes locks so, for example, the highest priority task that requires exclusive access to a resource directly gets an exclusive reference ( Using other terms like "immutable references" for
#[task(priority = 1, resources = [&x])]
fn a(cx: a::Context) {
cx.resources.x.lock_shared(|x: &Type| { /* .. */ });
}
#[task(priority = 2, resources = [x])]
fn b(cx: b::Context) { /* .. */ }
That is the intention: tasks At the end, whether a |
Thanks for the clarification! On the final note, I think there is something I am missing here. |
The actual behavior is similar to |
This is fine struct Pair {
x: AtomicU32,
y: u32,
}
struct Resources {
pair: Pair,
}
#[task(priority = 1, resources = [pair])]
fn low_prio(cx: low_prio::Context) {
// BASEPRI is NOT changed = may be preempted by `high_prio`
cx.resources.pair.lock_shared(|pair: &Pair| {
// NOTE `pair` is a shared reference (`&-`) to the data
// read operation = OK
let x: u32 = pair.x.load(Ordering::Relaxed);
// read operation = OK
let y: u32 = *pair.y;
// RMW operation = OK (because it has retry semantics)
// (shared mutability or "interior mutability")
pair.x.fetch_add(1, Ordering::Relaxed);
});
// BASEPRI IS changed = may NOT be preempted by `high_prio`
cx.resources.pair.lock_exclusive(|pair: &mut Pair| {
// NOTE `pair` is a mutable reference (`&mut-`) to the data
// write operation = OK (because we have exclusive access)
pair.x = 0;
// write operation = OK (because we have exclusive access)
let y: &mut u32 = pair.y.get_mut();
*y = 0;
});
}
#[task(priority = 2, resources = [&pair])]
fn high_prio(cx: high_prio::Context) {
// NOTE direct shared reference (`&-`) to the data
let pair: &Pair = cx.resources.pair;
// read operation = OK
let x: u32 = pair.x.load(Ordering::Relaxed);
// read operation = OK
let y: u32 = *pair.y;
// write operation = OK (because it's an atomic write)
// (shared mutability or "interior mutability")
pair.x.store(0, Ordering::Relaxed);
} |
Yes, it is fine to continue. I will ponder the extension a bit. |
OK for me. |
The FCP has passed; this RFC is now in the accepted state. Implementation is in PR #205. |
205: rtfm-syntax refactor + heterogeneous multi-core support r=japaric a=japaric this PR implements RFCs #178, #198, #199, #200, #201, #203 (only the refactor part), #204, #207, #211 and #212. most cfail tests have been removed because the test suite of `rtfm-syntax` already tests what was being tested here. The `rtfm-syntax` crate also has tests for the analysis pass which we didn't have here -- that test suite contains a regression test for #183. the remaining cfail tests have been upgraded into UI test so we can more thoroughly check / test the error message presented to the end user. the cpass tests have been converted into plain examples EDIT: I forgot, there are some examples of the multi-core API for the LPC541xx in [this repository](https://github.com/japaric/lpcxpresso54114) people that would like to try out this API but have no hardware can try out the x86_64 [Linux port] which also has multi-core support. [Linux port]: https://github.com/japaric/linux-rtfm closes #178 #198 #199 #200 #201 #203 #204 #207 #211 #212 closes #163 cc #209 (documents how to deal with errors) Co-authored-by: Jorge Aparicio <jorge@japaric.io>
205: rtfm-syntax refactor + heterogeneous multi-core support r=japaric a=japaric this PR implements RFCs #178, #198, #199, #200, #201, #203 (only the refactor part), #204, #207, #211 and #212. most cfail tests have been removed because the test suite of `rtfm-syntax` already tests what was being tested here. The `rtfm-syntax` crate also has tests for the analysis pass which we didn't have here -- that test suite contains a regression test for #183. the remaining cfail tests have been upgraded into UI test so we can more thoroughly check / test the error message presented to the end user. the cpass tests have been converted into plain examples EDIT: I forgot, there are some examples of the multi-core API for the LPC541xx in [this repository](https://github.com/japaric/lpcxpresso54114) people that would like to try out this API but have no hardware can try out the x86_64 [Linux port] which also has multi-core support. [Linux port]: https://github.com/japaric/linux-rtfm closes #178 #198 #199 #200 #201 #203 #204 #207 #211 #212 closes #163 cc #209 (documents how to deal with errors) Co-authored-by: Jorge Aparicio <jorge@japaric.io>
Done in PR #205 |
205: Stop using randomized symbol names r=therealprof a=jonas-schievink It isn't possible to do this by incrementing a global counter, since the expansion order of macros isn't guaranteed and might change between compiler invocations. Fixes rtic-rs#212 Closes rust-embedded/cortex-m-rt#196 Closes rust-embedded/cortex-m-rt#195 Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
Let's try this again.
Summary
Change the declaration syntax of resources from static variables to fields of a
struct.
Current behavior
Today resources are represented in the DSL as static variables. There's a
distinction between
static
andstatic mut
resources. For the former type onecan only get a shared reference (
&-
) to the underlying data. For the lattertype one can get a mutable reference(
&mut-
) to the data but may need to use acritical section (
lock
API).There's also distinction between compile time initialized resources (early
resources) and runtime initialized resources (late resources). The distinction
appears in the declaration syntax: late resources have an initial value of
()
(the unit value) in their declaration.
The following snippet shows the 4 possible types of resources.
Access to resources is controlled using
resources
lists. Each context declaresthe resources it can access in this list.
Below the continuation of the previous snippet that shows the
resources
lists.Proposal
Declaration
A structure named
Resources
declared within the#[app]
module will be usedto declare all the resources in the application. Each field of this
struct
is a resource. There is no longer a
static
/static mut
difference atdeclaration site.
The
#[init]
attribute can be used to give an initial (compile-time) value to aresource. Resources that are not given an initial value are considered late
resources and will be initialized to the values returned by the
#[init]
function before interrupts (tasks) are re-enabled.
Example from the previous section ported to the new syntax.
Access lists
The syntax of
resources
lists is extended to include shared access:&x
.The current "by value" syntax will now have the meaning of exclusive access.
Resources with only shared access will inherit the properties, requirements
(
Sync
bound) and API of today'sstatic
resources. Resources with onlyexclusive access will inherit the properties, requirements and API (
lock
) oftoday's
static mut
resources.Continuation of the example ported to the new syntax:
LateResources
The
LateResources
syntax / API is unchanged. Both examples initialize their late resources with the same code, which is shown below:Restrictions
A single resource cannot appear in the same list twice under different access
modes:
A single resource cannot be accessed in different ways (shared and exclusive)
from different tasks.
Motivation
The current late resource syntax is strange as it would not normally pass the
type checker in normal Rust.
The syntax difference between
static
andstatic mut
resources isartificial, for all resources are lowered down to
static mut
variables.Expressing shared access vs exclusive access in the
resources
list feelsmore natural and lends itself to API extensions like exclusive-shared locks.
Extensions
These are not part of the main proposal and can be discussed as separated RFCs
but are listed here to show the possibilities.
exclusive-shared locks
This syntax lends itself to implementing exclusive-shared locks (AKA
readers-writer locks) as proposed in RFC #129. The required changes would
involve (a) lifting the second restriction so that shared and exclusive access
to a single resource can be mixed, and (b) adding traits for the two new kinds
of locks:
Example:
The text was updated successfully, but these errors were encountered: