Liu–Layland bound: rate-monotonic scheduling meets every deadline if
OpenLiuLayland1973.rate_monotonic_utilization_boundThis is the Liu–Layland schedulability test for rate-monotonic scheduling of periodic tasks on one processor, stated in discrete time with integer parameters.
Consider periodic tasks . Task has an integer run time and an integer period . Its -th job () is released at time , needs units of processing, and has deadline , the release time of the next job of the same task. In particular all tasks release their first job at time (synchronous release). Time is divided into unit slots , ; in each slot the processor executes one unit of work of one task, or idles.
The rate-monotonic (RM) schedule is the preemptive fixed-priority schedule in which a task with a shorter period has higher priority, ties between equal periods being broken by the index of the task. In every slot the processor runs the highest-priority task that has released work not yet executed, and it idles only when no task has pending work; the jobs of one task are served in order of release. If the processor utilization of the task set satisfies
then every job of every task completes by its deadline under the RM schedule. Equivalently, for every task and every , task is executed in at least of the slots before time .
The bound equals for , about for , and decreases to as , so every periodic task set that uses at most of the processor is schedulable by the rate-monotonic rule, whatever its periods. It is the classical sufficient schedulability test of fixed-priority real-time scheduling. Liu and Layland also showed that the bound cannot be improved: for every there are task sets that miss a deadline under rate-monotonic scheduling and whose utilization is arbitrarily close to . That tightness statement is not part of this theorem.
Formalization Note Tasks are indexed by Fin n, that is by instead of , and the parameters are C T : Fin n → ℕ. The schedule is a function σ : ℕ → Option (Fin n), where σ t = some i means that task runs in slot and σ t = none means idling. The work of task released by time is times the number of with , its service by time is the number of slots with σ s = some i, and the task has pending work at when its service is below its released work. The hypothesis hσ states that σ t = some i exactly when task has pending work at and no task of higher priority (smaller period, or equal period and smaller index) does. This determines σ uniquely by recursion on , and such a schedule exists. Each task's work is served as one first-come-first-served backlog, which agrees with the job-by-job schedule up to the first missed deadline, so the conclusion is equivalent to the statement that no job misses its deadline. The utilization bound uses the real power (Real.rpow). With integer run times and periods, the continuous-time preemptive rate-monotonic schedule of Liu and Layland changes the running task only at integer times, so it coincides with the slot schedule above, and the theorem is the integer-parameter case of their result.
import Mathlib
namespace LiuLayland1973
/-- Liu–Layland utilization bound for rate-monotonic scheduling (Liu–Layland 1973, Theorem 5),
in discrete time with integer parameters.
Tasks are `Fin n`; task `i` has run time `C i` and period `T i`, and releases its `k`-th job
(`k = 0, 1, 2, …`) at time `k * T i` with deadline `(k + 1) * T i` (all tasks release their
first job at time `0`). Time is divided into unit slots `[t, t + 1)`, `t : ℕ`; `σ t = some i`
means task `i` runs in slot `t` and `σ t = none` means the processor idles.
* `(Finset.range t).filter (σ · = some i)` are the slots before `t` given to task `i`
(its cumulative service by time `t`);
* `(Finset.range (t + 1)).filter (fun k => k * T i ≤ t)` are the jobs of task `i` released by
time `t`, so `C i * card` is the work it has released by time `t`;
* task `i` has pending work at `t` iff its service is below its released work;
* task `j` has higher rate-monotonic priority than task `i` iff `T j < T i`, or `T j = T i`
and `j < i`.
`hσ` says that in every slot the processor runs the highest-priority task with pending work
(idling only if none has), which determines `σ` uniquely by recursion on `t`. Within a task,
work is served first-come first-served, so job `k` of task `i` is complete by its deadline iff
task `i` has received `(k + 1) * C i` units of service by time `(k + 1) * T i`. -/
theorem rate_monotonic_utilization_bound (n : ℕ) (C T : Fin n → ℕ)
(hC : ∀ i, 1 ≤ C i) (hCT : ∀ i, C i ≤ T i)
(hU : ∑ i, (C i : ℝ) / (T i : ℝ) ≤ (n : ℝ) * ((2 : ℝ) ^ ((1 : ℝ) / (n : ℝ)) - 1))
(σ : ℕ → Option (Fin n))
(hσ : ∀ (t : ℕ) (i : Fin n), σ t = some i ↔
(((Finset.range t).filter (fun s => σ s = some i)).card <
C i * ((Finset.range (t + 1)).filter (fun k => k * T i ≤ t)).card) ∧
∀ j : Fin n, (T j < T i ∨ (T j = T i ∧ j < i)) →
C j * ((Finset.range (t + 1)).filter (fun k => k * T j ≤ t)).card ≤
((Finset.range t).filter (fun s => σ s = some j)).card)
(i : Fin n) (k : ℕ) :
(k + 1) * C i ≤
((Finset.range ((k + 1) * T i)).filter (fun s => σ s = some i)).card := by
sorry
end LiuLayland1973