Shared-Resource Access Control (avionics/fsw/shared-resource-access-control)
Use when the fixed-priority periodic tasks of an avionics flight
software set share protected resources (buffers, registers, data
stores) and the schedulability analysis must include the blocking that
shared access can cause. Each task is a {name, C, T, priority} dict
with implicit deadline D = T; each lock is a {resource, task, cs}
dict. This leaf implements the priority ceiling protocol model in pure
Python stdlib: the ceiling of every resource, the worst-case blocking
each task can suffer from lower-priority tasks under the ceiling rule,
and the response-time analysis with the blocking term, ending in a
schedulability verdict. It pairs with avionics/fsw/real-time-scheduling
for the plain (C, T) feasibility of the same task set without shared
resources, and with avionics/fsw/cfs-architecture for the flight
software application context around the task set.
Domain quick reference
- Task model: a task is a dict {name, C, T, priority} with implicit
deadline D = T, C and T in one time unit; higher number means higher
priority. A lock is a dict {resource, task, cs} where cs is the
task's longest critical-section time on that resource, in the same
time unit as C.
- Priority ceiling of a resource: the highest priority among the tasks
that lock it. R1 locked by tasks of priority 3 and 1 has ceiling 3.
- Ceiling rule (paraphrased PCP bound): a task can be blocked by at
most one lower-priority task's critical section, and only on a
resource whose ceiling is at least the task's own priority. So the
worst-case blocking of task i is the longest cs of any single
lower-priority task over the resources whose ceiling clears
priority_i; everything else contributes nothing.
- Response time with blocking (fixed point): R_i = C_i + B_i +
sum over higher-priority tasks j of ceil(R_i / T_j) * C_j, iterated
from C_i + B_i until the value stops changing, capped at 100
iterations (MAX_RTA_ITERATIONS). The iteration is monotone
non-decreasing, so on an overloaded set the capped value grows far
past the period and the set reports infeasible.
- Feasibility: every converged response time must be at most its task
period (within 1e-9 relative slack).
- Empty lock list identity: with no shared resources every blocking
time is zero and the fixed point above is exactly the classic
response-time analysis of the same task set.
- Scope notes: plain feasibility mathematics without the blocking term
belongs to avionics/fsw/real-time-scheduling; WCET budgets are
inputs, not outputs; this leaf does not model message or bus
response windows.
Workflow
- Collect the task set and the lock set: tasks as a dict {name:
{C, T, priority}} or a list of task dicts, locks as a list of
{resource, task, cs} dicts, all in one time unit. Every C and T
must be positive with C <= T, every cs non-negative, task names
unique, and every lock must name a real task.
- Assign ceilings first: priority_ceiling(tasks, locks) returns the
per-resource ceiling map; resource_ceiling(tasks, locks, resource)
gives one resource. A ceiling is only defined for resources that
some task locks, so an empty lock list raises ValueError here.
- Compute the per-task blocking: blocking_times(tasks, locks) applies
the ceiling rule to every task, or worst_case_blocking(task, tasks,
locks) for a single task. Expect the lowest-priority task to come
out with zero blocking: nothing below it exists to block it.
- Run the response time of a single task with
response_time_with_blocking(task, tasks, locks): the fixed point
starts at C + B and adds the higher-priority load.
- Decide schedulability in one call:
rta_with_blocking_feasibility(tasks, locks) returns the dict with
keys blocking, response_times and feasible, where feasible is True
iff every response time is at most its period.
- Cross-check the resource-free baseline: the same call with an empty
lock list must give zero blocking and the plain response-time
values, the identity that separates the blocking effect from the
preemption load.
- Record the ceiling map, blocking times, response times and verdict
in the scheduling analysis artifact of the certification package;
re-run the contract test after any change to the task or lock set.
Worked example
Anchor set: T1 {C 1, T 5, priority 3}, T2 {C 2, T 10, priority 2},
T3 {C 3, T 20, priority 1}; locks R1 used by T1 (cs 0.5) and T3
(cs 0.6), R2 used by T2 (cs 0.8) and T3 (cs 0.7), times in ms.
- Ceilings: priority_ceiling returns R1 -> 3 (max of priorities 3 and
- and R2 -> 2 (max of priorities 2 and 1); resource_ceiling agrees
per resource.
- Blocking (module output): T1 0.6, T2 0.7, T3 0.0. T1 is blocked by
T3's 0.6 ms section on R1 (ceiling 3 clears priority 3); T3's 0.7
and T2's 0.8 on R2 do not qualify because ceiling 2 is below T1's
priority 3. T2 is blocked by T3's 0.7 on R2 (ceiling 2 clears
priority 2). T3 has no lower-priority task, so 0.0.
- Response times with blocking (module output): T1 1.6 = 1 + 0.6,
T2 3.7 = 2 + 0.7 + 1 preemption from T1, T3 7.0 = 3 + 2 + 2
preemptions from T1 and T2. Every value is at most its period, so
rta_with_blocking_feasibility returns feasible True.
- Empty lock list (module output): blocking all zero and the response
times collapse to the plain analysis T1 1.0, T2 3.0, T3 7.0. Note
the T3 fixed point visits 3, then 6, and converges at 7.0 in both
runs: with zero blocking the with-resource and resource-free
analyses are the same computation, and the identity holds on the
converged value.
Verification
- Confirm priority_ceiling on the anchor returns R1 3 and R2 2, and
that resource_ceiling matches per resource.
- Confirm the blocking truth table: worst_case_blocking gives T1 0.6,
T2 0.7, T3 0.0, and blocking_times agrees.
- Confirm the fixed-point response times converge to T1 1.6, T2 3.7,
T3 7.0 within 1e-9, all within their periods, feasible True.
- Confirm the empty-lock identity: blocking all zero, response times
equal the plain analysis (T1 1.0, T2 3.0, T3 7.0).
- Confirm the ceiling-rule boundary: a lower-priority task locking a
resource whose ceiling sits below the task's priority contributes no
blocking, and equal-priority tasks neither preempt nor block.
- Confirm that adding the blocking term never shrinks a response time
and can flip a feasible set infeasible.
- Confirm ValueError rejection of C <= 0, T <= 0, C > T, cs < 0,
duplicate task names, unknown task references, an empty task set,
and an empty lock list for the ceiling functions.
- Run the deterministic contract test offline: python3
scripts/test_shared_resource_access_control.py (35 tests).
Related leaves
- avionics/fsw/real-time-scheduling: the plain (C, T) feasibility of
the same periodic task set with no shared-resource blocking term;
run it on the resource-free baseline of this leaf's model.
- avionics/fsw/cfs-architecture: the flight software application
layout and inter-application messaging context that carries the task
and resource sets this leaf analyzes.
- avionics/fsw/fprime-component: the component-based flight software
architecture whose ports and queues become protected resources in a
task set model.
Pitfalls
- Reading a ceiling as a per-task quantity: the ceiling attaches to
the resource and equals the highest priority among every task that
locks it, so a resource used by a high-priority task keeps a high
ceiling even when a low-priority task is its only other user.
- Summing every lower-priority critical section: under the priority
ceiling protocol the task is blocked by at most one lower-priority
section, so blocking is a max over qualifying sections, not a sum -
adding T2's 0.8 and T3's sections together overstates T1's blocking
(0.6, not 1.5+).
- Applying the ceiling rule to the wrong resources: only sections on
resources whose ceiling is at least the task's priority count, which
is why T3's 0.7 on R2 (ceiling 2) never blocks T1 (priority 3)
despite T3 being lower priority.
- Dropping the blocking term from the fixed point: the iteration must
start from C + B and add B on every pass, so the response time with
blocking never dips below the resource-free value (T1 1.6 against
1.0).
- Reporting a first iterate as the converged response time: T3's plain
analysis visits 3, then 6, then converges at 7.0, and stopping at
the first crossing understates the response time and can hide a
deadline miss.
- Mixing priority direction or time units: higher number is higher
priority here (the opposite of the rate-monotonic convention in the
sibling leaf), and C, T and cs must share one time unit or every
ceil term corrupts the fixed point.
Behavior contract (gate 3)
Run the deterministic contract test (stdlib unittest, offline, no
network, exits 0):
python3 scripts/test_shared_resource_access_control.py
The test covers the anchor ceilings R1 3 / R2 2, the blocking truth
table 0.6 / 0.7 / 0.0 with the ceiling-rule boundary and the
equal-priority case, the fixed-point response times 1.6 / 3.7 / 7.0
within 1e-9, the empty-lock identity against the plain analysis, the
blocking-monotonicity property, blocking-driven infeasibility, the
exact result-dict keys, single-task closed forms, ValueError rejection
of every non-physical input (C <= 0, T <= 0, C > T, cs < 0, duplicate
task names, unknown task and resource references, empty task set,
empty lock list for the ceiling functions, malformed and boolean
entries), and run-to-run determinism.
Compliance
- Standards referenced, not reproduced: DO-178C (avionics software
lifecycle, including the scheduling and resource-sharing analysis of
the software task set) is listed reference-only per standards-map
yaml; the ceiling and blocking mathematics above is standard public
real-time systems methodology, summary-only.
- The inter-application messaging interfaces of the flight software
context belong to avionics/fsw/cfs-architecture, not to this leaf.
- compliance: STANDARDS-REF, gated: false.
1---2name: shared-resource-access-control3description: Use when you must account for shared-resource blocking in a fixed-priority avionics task set: assign each protected resource its priority ceiling from the tasks that lock it, compute the worst-case blocking time each task can suffer from lower-priority tasks under the priority ceiling protocol, and run the response-time analysis with the blocking term to decide schedulability. Produces the per-resource ceiling map, the per-task worst-case blocking times, the response times with blocking, and the schedulability verdict that gate an avionics task set design. Trigger: shared resource access control, priority ceiling protocol, priority inheritance, stack resource policy, worst case blocking, blocking time bound, schedulability with blocking.4license: Apache-2.05---67# Shared-Resource Access Control (avionics/fsw/shared-resource-access-control)89Use when the fixed-priority periodic tasks of an avionics flight10software set share protected resources (buffers, registers, data11stores) and the schedulability analysis must include the blocking that12shared access can cause. Each task is a {name, C, T, priority} dict13with implicit deadline D = T; each lock is a {resource, task, cs}14dict. This leaf implements the priority ceiling protocol model in pure15Python stdlib: the ceiling of every resource, the worst-case blocking16each task can suffer from lower-priority tasks under the ceiling rule,17and the response-time analysis with the blocking term, ending in a18schedulability verdict. It pairs with avionics/fsw/real-time-scheduling19for the plain (C, T) feasibility of the same task set without shared20resources, and with avionics/fsw/cfs-architecture for the flight21software application context around the task set.2223## Domain quick reference2425- Task model: a task is a dict {name, C, T, priority} with implicit26 deadline D = T, C and T in one time unit; higher number means higher27 priority. A lock is a dict {resource, task, cs} where cs is the28 task's longest critical-section time on that resource, in the same29 time unit as C.30- Priority ceiling of a resource: the highest priority among the tasks31 that lock it. R1 locked by tasks of priority 3 and 1 has ceiling 3.32- Ceiling rule (paraphrased PCP bound): a task can be blocked by at33 most one lower-priority task's critical section, and only on a34 resource whose ceiling is at least the task's own priority. So the35 worst-case blocking of task i is the longest cs of any single36 lower-priority task over the resources whose ceiling clears37 priority_i; everything else contributes nothing.38- Response time with blocking (fixed point): R_i = C_i + B_i +39 sum over higher-priority tasks j of ceil(R_i / T_j) * C_j, iterated40 from C_i + B_i until the value stops changing, capped at 10041 iterations (MAX_RTA_ITERATIONS). The iteration is monotone42 non-decreasing, so on an overloaded set the capped value grows far43 past the period and the set reports infeasible.44- Feasibility: every converged response time must be at most its task45 period (within 1e-9 relative slack).46- Empty lock list identity: with no shared resources every blocking47 time is zero and the fixed point above is exactly the classic48 response-time analysis of the same task set.49- Scope notes: plain feasibility mathematics without the blocking term50 belongs to avionics/fsw/real-time-scheduling; WCET budgets are51 inputs, not outputs; this leaf does not model message or bus52 response windows.5354## Workflow55561. Collect the task set and the lock set: tasks as a dict {name:57 {C, T, priority}} or a list of task dicts, locks as a list of58 {resource, task, cs} dicts, all in one time unit. Every C and T59 must be positive with C <= T, every cs non-negative, task names60 unique, and every lock must name a real task.612. Assign ceilings first: priority_ceiling(tasks, locks) returns the62 per-resource ceiling map; resource_ceiling(tasks, locks, resource)63 gives one resource. A ceiling is only defined for resources that64 some task locks, so an empty lock list raises ValueError here.653. Compute the per-task blocking: blocking_times(tasks, locks) applies66 the ceiling rule to every task, or worst_case_blocking(task, tasks,67 locks) for a single task. Expect the lowest-priority task to come68 out with zero blocking: nothing below it exists to block it.694. Run the response time of a single task with70 response_time_with_blocking(task, tasks, locks): the fixed point71 starts at C + B and adds the higher-priority load.725. Decide schedulability in one call:73 rta_with_blocking_feasibility(tasks, locks) returns the dict with74 keys blocking, response_times and feasible, where feasible is True75 iff every response time is at most its period.766. Cross-check the resource-free baseline: the same call with an empty77 lock list must give zero blocking and the plain response-time78 values, the identity that separates the blocking effect from the79 preemption load.807. Record the ceiling map, blocking times, response times and verdict81 in the scheduling analysis artifact of the certification package;82 re-run the contract test after any change to the task or lock set.8384## Worked example8586Anchor set: T1 {C 1, T 5, priority 3}, T2 {C 2, T 10, priority 2},87T3 {C 3, T 20, priority 1}; locks R1 used by T1 (cs 0.5) and T388(cs 0.6), R2 used by T2 (cs 0.8) and T3 (cs 0.7), times in ms.8990- Ceilings: priority_ceiling returns R1 -> 3 (max of priorities 3 and91 1) and R2 -> 2 (max of priorities 2 and 1); resource_ceiling agrees92 per resource.93- Blocking (module output): T1 0.6, T2 0.7, T3 0.0. T1 is blocked by94 T3's 0.6 ms section on R1 (ceiling 3 clears priority 3); T3's 0.795 and T2's 0.8 on R2 do not qualify because ceiling 2 is below T1's96 priority 3. T2 is blocked by T3's 0.7 on R2 (ceiling 2 clears97 priority 2). T3 has no lower-priority task, so 0.0.98- Response times with blocking (module output): T1 1.6 = 1 + 0.6,99 T2 3.7 = 2 + 0.7 + 1 preemption from T1, T3 7.0 = 3 + 2 + 2100 preemptions from T1 and T2. Every value is at most its period, so101 rta_with_blocking_feasibility returns feasible True.102- Empty lock list (module output): blocking all zero and the response103 times collapse to the plain analysis T1 1.0, T2 3.0, T3 7.0. Note104 the T3 fixed point visits 3, then 6, and converges at 7.0 in both105 runs: with zero blocking the with-resource and resource-free106 analyses are the same computation, and the identity holds on the107 converged value.108109## Verification110111- Confirm priority_ceiling on the anchor returns R1 3 and R2 2, and112 that resource_ceiling matches per resource.113- Confirm the blocking truth table: worst_case_blocking gives T1 0.6,114 T2 0.7, T3 0.0, and blocking_times agrees.115- Confirm the fixed-point response times converge to T1 1.6, T2 3.7,116 T3 7.0 within 1e-9, all within their periods, feasible True.117- Confirm the empty-lock identity: blocking all zero, response times118 equal the plain analysis (T1 1.0, T2 3.0, T3 7.0).119- Confirm the ceiling-rule boundary: a lower-priority task locking a120 resource whose ceiling sits below the task's priority contributes no121 blocking, and equal-priority tasks neither preempt nor block.122- Confirm that adding the blocking term never shrinks a response time123 and can flip a feasible set infeasible.124- Confirm ValueError rejection of C <= 0, T <= 0, C > T, cs < 0,125 duplicate task names, unknown task references, an empty task set,126 and an empty lock list for the ceiling functions.127- Run the deterministic contract test offline: python3128 scripts/test_shared_resource_access_control.py (35 tests).129130## Related leaves131132- avionics/fsw/real-time-scheduling: the plain (C, T) feasibility of133 the same periodic task set with no shared-resource blocking term;134 run it on the resource-free baseline of this leaf's model.135- avionics/fsw/cfs-architecture: the flight software application136 layout and inter-application messaging context that carries the task137 and resource sets this leaf analyzes.138- avionics/fsw/fprime-component: the component-based flight software139 architecture whose ports and queues become protected resources in a140 task set model.141142## Pitfalls143144- Reading a ceiling as a per-task quantity: the ceiling attaches to145 the resource and equals the highest priority among every task that146 locks it, so a resource used by a high-priority task keeps a high147 ceiling even when a low-priority task is its only other user.148- Summing every lower-priority critical section: under the priority149 ceiling protocol the task is blocked by at most one lower-priority150 section, so blocking is a max over qualifying sections, not a sum -151 adding T2's 0.8 and T3's sections together overstates T1's blocking152 (0.6, not 1.5+).153- Applying the ceiling rule to the wrong resources: only sections on154 resources whose ceiling is at least the task's priority count, which155 is why T3's 0.7 on R2 (ceiling 2) never blocks T1 (priority 3)156 despite T3 being lower priority.157- Dropping the blocking term from the fixed point: the iteration must158 start from C + B and add B on every pass, so the response time with159 blocking never dips below the resource-free value (T1 1.6 against160 1.0).161- Reporting a first iterate as the converged response time: T3's plain162 analysis visits 3, then 6, then converges at 7.0, and stopping at163 the first crossing understates the response time and can hide a164 deadline miss.165- Mixing priority direction or time units: higher number is higher166 priority here (the opposite of the rate-monotonic convention in the167 sibling leaf), and C, T and cs must share one time unit or every168 ceil term corrupts the fixed point.169170## Behavior contract (gate 3)171172Run the deterministic contract test (stdlib unittest, offline, no173network, exits 0):174175 python3 scripts/test_shared_resource_access_control.py176177The test covers the anchor ceilings R1 3 / R2 2, the blocking truth178table 0.6 / 0.7 / 0.0 with the ceiling-rule boundary and the179equal-priority case, the fixed-point response times 1.6 / 3.7 / 7.0180within 1e-9, the empty-lock identity against the plain analysis, the181blocking-monotonicity property, blocking-driven infeasibility, the182exact result-dict keys, single-task closed forms, ValueError rejection183of every non-physical input (C <= 0, T <= 0, C > T, cs < 0, duplicate184task names, unknown task and resource references, empty task set,185empty lock list for the ceiling functions, malformed and boolean186entries), and run-to-run determinism.187188## Compliance189190- Standards referenced, not reproduced: DO-178C (avionics software191 lifecycle, including the scheduling and resource-sharing analysis of192 the software task set) is listed reference-only per standards-map193 yaml; the ceiling and blocking mathematics above is standard public194 real-time systems methodology, summary-only.195- The inter-application messaging interfaces of the flight software196 context belong to avionics/fsw/cfs-architecture, not to this leaf.197- compliance: STANDARDS-REF, gated: false.