aboutsummaryrefslogtreecommitdiff
path: root/macros/src/analyze.rs
diff options
context:
space:
mode:
authorGravatar Jorge Aparicio <jorge@japaric.io> 2019-04-21 20:02:59 +0200
committerGravatar Jorge Aparicio <jorge@japaric.io> 2019-05-01 20:49:25 +0200
commita452700628e352e6ac01da9e16223a47752ca860 (patch)
treec04a58222ba95e59d6b6013b5d2314068de6b1d0 /macros/src/analyze.rs
parente6fb2f216fccc09d8e996525dcef3ffb2004f1ec (diff)
downloadrtic-a452700628e352e6ac01da9e16223a47752ca860.tar.gz
rtic-a452700628e352e6ac01da9e16223a47752ca860.tar.zst
rtic-a452700628e352e6ac01da9e16223a47752ca860.zip
implement RFCs 147 and 155, etc.
This commit: - Implements RFC 147: "all functions must be safe" - Implements RFC 155: "explicit Context parameter" - Implements the pending breaking change #141: reject assign syntax in `init` (which was used to initialize late resources) - Refactors code generation to make it more readable -- there are no more random identifiers in the output -- and align it with the book description of RTFM internals. - Makes the framework hard depend on `core::mem::MaybeUninit` and thus will require nightly until that API is stabilized. - Fixes a ceiling analysis bug where the priority of the system timer was not considered in the analysis. - Shrinks the size of all the internal queues by turning `AtomicUsize` indices into `AtomicU8`s. - Removes the integration with `owned_singleton`.
Diffstat (limited to 'macros/src/analyze.rs')
-rw-r--r--macros/src/analyze.rs28
1 files changed, 18 insertions, 10 deletions
diff --git a/macros/src/analyze.rs b/macros/src/analyze.rs
index cfd8ebc9..a47be779 100644
--- a/macros/src/analyze.rs
+++ b/macros/src/analyze.rs
@@ -190,19 +190,20 @@ pub fn app(app: &App) -> Analysis {
}
// Ceiling analysis of free queues (consumer end point) -- first pass
- // Ceiling analysis of ready queues (producer end point)
+ // Ceiling analysis of ready queues (producer end point) -- first pass
// Also compute more Send-ness requirements
- let mut free_queues: HashMap<_, _> = app.tasks.keys().map(|task| (task.clone(), 0)).collect();
- let mut ready_queues: HashMap<_, _> = dispatchers.keys().map(|level| (*level, 0)).collect();
+ let mut free_queues = HashMap::new();
+ let mut ready_queues = HashMap::new();
for (priority, task) in app.spawn_calls() {
if let Some(priority) = priority {
- // Users of `spawn` contend for the to-be-spawned task FREE_QUEUE
- let c = free_queues.get_mut(task).expect("BUG: free_queue.get_mut");
+ // Users of `spawn` contend for the spawnee FREE_QUEUE
+ let c = free_queues.entry(task.clone()).or_default();
*c = cmp::max(*c, priority);
+ // Users of `spawn` contend for the spawnee's dispatcher READY_QUEUE
let c = ready_queues
- .get_mut(&app.tasks[task].args.priority)
- .expect("BUG: ready_queues.get_mut");
+ .entry(app.tasks[task].args.priority)
+ .or_default();
*c = cmp::max(*c, priority);
// Send is required when sending messages from a task whose priority doesn't match the
@@ -215,16 +216,23 @@ pub fn app(app: &App) -> Analysis {
}
}
+ // Ceiling analysis of ready queues (producer end point) -- second pass
// Ceiling analysis of free queues (consumer end point) -- second pass
// Ceiling analysis of the timer queue
let mut tq_ceiling = tq_priority;
for (priority, task) in app.schedule_calls() {
+ // the system timer handler contends for the spawnee's dispatcher READY_QUEUE
+ let c = ready_queues
+ .entry(app.tasks[task].args.priority)
+ .or_default();
+ *c = cmp::max(*c, tq_priority);
+
if let Some(priority) = priority {
- // Users of `schedule` contend for the to-be-spawned task FREE_QUEUE (consumer end point)
- let c = free_queues.get_mut(task).expect("BUG: free_queue.get_mut");
+ // Users of `schedule` contend for the spawnee task FREE_QUEUE
+ let c = free_queues.entry(task.clone()).or_default();
*c = cmp::max(*c, priority);
- // Users of `schedule` contend for the timer queu
+ // Users of `schedule` contend for the timer queue
tq_ceiling = cmp::max(tq_ceiling, priority);
} else {
// spawns from `init` are excluded from the ceiling analysis