Library prosa.results.periodic.simulation.interval
Simulation Interval for Periodic Schedulers
DOI: 10.1016/j.sysarc.2026.103939
Require Export prosa.analysis.facts.busy_interval.carry_in.
Require Export prosa.analysis.facts.hyperperiod.
Require Export prosa.analysis.facts.model.ideal.schedule.
Require Export prosa.analysis.facts.priority.jlfp.
Require Export prosa.analysis.facts.readiness.basic.
Require Export prosa.analysis.definitions.infinite_jobs.
Require Export prosa.analysis.definitions.schedulability.
Require Export prosa.model.processor.ideal.
Require Export prosa.model.preemption.fully_preemptive.
Require Export prosa.model.schedule.work_conserving.
Require Export prosa.model.task.absolute_deadline.
Section SimulationInterval.
Require Export prosa.analysis.facts.hyperperiod.
Require Export prosa.analysis.facts.model.ideal.schedule.
Require Export prosa.analysis.facts.priority.jlfp.
Require Export prosa.analysis.facts.readiness.basic.
Require Export prosa.analysis.definitions.infinite_jobs.
Require Export prosa.analysis.definitions.schedulability.
Require Export prosa.model.processor.ideal.
Require Export prosa.model.preemption.fully_preemptive.
Require Export prosa.model.schedule.work_conserving.
Require Export prosa.model.task.absolute_deadline.
Section SimulationInterval.
System Model
Context {Task : TaskType} `{TaskOffset Task} `{PeriodicModel Task}
`{TaskCost Task} `{TaskDeadline Task}.
`{TaskCost Task} `{TaskDeadline Task}.
Jobs of these tasks have arrival times and execution requirements. Each
job's absolute is derived from its task's relative deadline via
job_deadline_from_task_deadline.
The considered workload is a finite set of periodic tasks ...
... generating a valid infinite arrival sequence ...
Variable arr_seq : arrival_sequence Job.
Hypothesis H_valid_arrival_sequence : valid_arrival_sequence arr_seq.
Hypothesis H_all_jobs_from_taskset : all_jobs_from_taskset arr_seq ts.
Hypothesis H_infinite_jobs : tasks_have_infinite_arrivals arr_seq ts.
Hypothesis H_valid_arrival_sequence : valid_arrival_sequence arr_seq.
Hypothesis H_all_jobs_from_taskset : all_jobs_from_taskset arr_seq ts.
Hypothesis H_infinite_jobs : tasks_have_infinite_arrivals arr_seq ts.
... in which each task's first job arrives at its offset ...
... and consecutive jobs of each task are separated by exactly one period.
Simulation uses the task WCET for every job, ensuring that execution
requirements repeat.
We assume that the system is not overloaded: the work arriving per
hyperperiod fits in one hyperperiod of service. This is the integer
formulation of the paper's utilization bound U ≤ 1, and permits both
zero work and full utilization.
We use the basic Liu-and-Layland-style job readiness model, where every
pending job is always ready to execute, including jobs whose deadlines
have passed.
Context {job_ready_model : JobReady Job (ideal.processor_state Job)}.
Hypothesis H_basic_readiness : basic_readiness job_ready_model.
Hypothesis H_basic_readiness : basic_readiness job_ready_model.
In the following, we analyze a given well-formed, work-conserving
schedule of the workload on an ideal uniprocessor.
#[local] Existing Instance ideal.processor_state.
Variable sched : schedule (ideal.processor_state Job).
Hypothesis H_valid_schedule : valid_schedule sched arr_seq.
Hypothesis H_work_conserving : work_conserving arr_seq sched.
Variable sched : schedule (ideal.processor_state Job).
Hypothesis H_valid_schedule : valid_schedule sched arr_seq.
Hypothesis H_work_conserving : work_conserving arr_seq sched.
Importantly, we make no assumption on which scheduling policy was used to
obtain sched and do not assume any particular preemption model.
We now identify the part of the schedule that a finite simulation must
cover. The following definitions translate the paper's time conventions to
Prosa's discrete time model and specify where to look for a no-carry-in
instant that bounds a complete repeating hyperperiod.
Following Definition 4.1 in the paper, the "onset of global periodicity"
is the maximum of task_offset tsk + 1 - task_period tsk, with saturating
subtraction and an empty maximum of zero. This translates the paper's
strict inequality t > O - T; in particular, O = T requires t ≥ 1.
Simulation Time Boundaries
Definition arrival_periodicity_start :=
max0 [seq task_offset tsk + 1 - task_period tsk | tsk <- ts].
max0 [seq task_offset tsk + 1 - task_period tsk | tsk <- ts].
When every task's offset is strictly less than its period, i.e., when all
tasks have constrained offsets, then this bound reduces to zero, yielding
the horizon specialization of Corollary 4.1.
The search for a no-carry-in instant starts one hyperperiod after the arrival
boundary. This is the first integer strictly after the paper's
t0 + H, interpreting 0^- as the predecessor of zero.
The simulation horizon is the main bound of interest: the main claim
established below is that a simulation must cover only the jobs that
arrive prior to this horizon to establish schedulability for all jobs
(up to infinity). It accounts for the initial transient through the
no-carry-in search boundary as well as for the total amount of work
carried out by the tasks in one hyperperiod.
The paper's "idle points" are exactly Prosa's no_carry_in times: every
job arriving strictly before the instant has completed. This gives the
scheduler an empty backlog before processing new arrivals. New jobs may
arrive and execute at the idle point itself.
The first no-carry-in instant at or after the search start identifies
the earliest eligible boundary for the simulation.
Definition first_no_carry_in_instant (t : instant) :=
no_carry_in_search_start ≤ t
∧ no_carry_in arr_seq sched t
∧ ∀ t',
no_carry_in_search_start ≤ t' →
t' < t →
exists_carry_in arr_seq sched t'.
no_carry_in_search_start ≤ t
∧ no_carry_in arr_seq sched t
∧ ∀ t',
no_carry_in_search_start ≤ t' →
t' < t →
exists_carry_in arr_seq sched t'.
Existence of a No-Carry-In Instant
Local Lemma first_no_carry_in_instant_within_horizon :
exists2 t,
first_no_carry_in_instant t
& t ≤ simulation_horizon.
exists2 t,
first_no_carry_in_instant t
& t ≤ simulation_horizon.
We next establish some auxiliary lemmas that we require for the subsequent
proofs.
To relate "matching" jobs across hyperperiods, we use Prosa's next_hyperperiod_job
and prev_hyperperiod_job definitions. We establish some useful facts
about these definitions in our specific context.
As a stepping stone, we observe that jobs that arrive after the starting
threshold for the no-carry-in instant search have indeed a predecessor
that arrives exactly one hyperperiod earlier.
Matching Jobs Across Hyperperiods
Local Lemma late_arrival_job_index :
∀ j,
arrives_in arr_seq j →
no_carry_in_search_start ≤ job_arrival j →
jobs_per_hyperperiod ts (job_task j) ≤ job_index arr_seq j.
∀ j,
arrives_in arr_seq j →
no_carry_in_search_start ≤ job_arrival j →
jobs_per_hyperperiod ts (job_task j) ≤ job_index arr_seq j.
A job's "matching successor" indeed arrives during the next hyperperiod.
Local Lemma next_hyperperiod_job_in_next_interval :
∀ start j,
j \in arrivals_between arr_seq start (start + hyperperiod ts) →
next_hyperperiod_job ts arr_seq j \in
arrivals_between arr_seq
(start + hyperperiod ts)
(start + 2 × hyperperiod ts).
∀ start j,
j \in arrivals_between arr_seq start (start + hyperperiod ts) →
next_hyperperiod_job ts arr_seq j \in
arrivals_between arr_seq
(start + hyperperiod ts)
(start + 2 × hyperperiod ts).
From the arrival boundary onward, there is a "matching predecessor" in the
preceding hyperperiod for every later release.
Local Lemma prev_hyperperiod_job_in_prev_interval :
∀ start j,
arrival_periodicity_start ≤ start →
j \in arrivals_between arr_seq
(start + hyperperiod ts)
(start + 2 × hyperperiod ts) →
prev_hyperperiod_job ts arr_seq j \in
arrivals_between arr_seq start (start + hyperperiod ts).
∀ start j,
arrival_periodicity_start ≤ start →
j \in arrivals_between arr_seq
(start + hyperperiod ts)
(start + 2 × hyperperiod ts) →
prev_hyperperiod_job ts arr_seq j \in
arrivals_between arr_seq start (start + hyperperiod ts).
For jobs that arrive after the start of periodicity, the "matching
successor" and "matching predecessor" relationships cancel out.
Local Lemma next_prev_hyperperiod_job_in_interval :
∀ start j,
arrival_periodicity_start ≤ start →
j \in arrivals_between arr_seq
(start + hyperperiod ts)
(start + 2 × hyperperiod ts) →
next_hyperperiod_job ts arr_seq (prev_hyperperiod_job ts arr_seq j)
= j.
∀ start j,
arrival_periodicity_start ≤ start →
j \in arrivals_between arr_seq
(start + hyperperiod ts)
(start + 2 × hyperperiod ts) →
next_hyperperiod_job ts arr_seq (prev_hyperperiod_job ts arr_seq j)
= j.
Next, we establish two helper lemmas on the workload in intervals exactly
one hyperperiod apart.
The total workload in a given interval is never less than the total
workload in an interval of the same length exactly one hyperperiod
later. This holds even during the initial transient.
Relating Workload Across Hyperperiods
Lemma workload_nondecreasing_after_hyperperiod_shift :
∀ start stop,
total_workload_between arr_seq start stop
≤ total_workload_between arr_seq
(start + hyperperiod ts)
(stop + hyperperiod ts).
∀ start stop,
total_workload_between arr_seq start stop
≤ total_workload_between arr_seq
(start + hyperperiod ts)
(stop + hyperperiod ts).
Once arrivals repeat, the workload comparison becomes an equality.
Lemma workload_equal_across_hyperperiods :
∀ start,
arrival_periodicity_start ≤ start →
total_workload_between arr_seq
start
(start + hyperperiod ts)
= total_workload_between arr_seq
(start + hyperperiod ts)
(start + 2 × hyperperiod ts).
∀ start,
arrival_periodicity_start ≤ start →
total_workload_between arr_seq
start
(start + hyperperiod ts)
= total_workload_between arr_seq
(start + hyperperiod ts)
(start + 2 × hyperperiod ts).
Resettable Deterministic Schedulers
Definition self_contained_hyperperiod (start : instant) :=
no_carry_in arr_seq sched start
∧ no_carry_in arr_seq sched (start + hyperperiod ts).
no_carry_in arr_seq sched start
∧ no_carry_in arr_seq sched (start + hyperperiod ts).
We say that execution repeats at time t in schedule sched
(w.r.t. the workload's hyperperiod) if the "matching successor" job given
by next_hyperperiod_job (if any) is scheduled at time t + hyperperiod
ts. Similarly, if no job is scheduled at time t, then t + hyperperiod
ts must also be idle.
Definition execution_repeats_at (t : instant) :=
if sched t is Some j
then sched (t + hyperperiod ts) = Some (next_hyperperiod_job ts arr_seq j)
else sched (t + hyperperiod ts) = None.
if sched t is Some j
then sched (t + hyperperiod ts) = Some (next_hyperperiod_job ts arr_seq j)
else sched (t + hyperperiod ts) = None.
No-carry-in instants give the scheduler matching reset states. This
contract captures the consequence of resettable determinism needed here:
corresponding arrivals produce matching execution over the following
hyperperiod. This lets us propagate no-carry-in boundaries and establish
indefinite repetition by induction over successive hyperperiods.
We show further below in lemma jlfp_respects_hyperperiod_reset that JLFP
policies satisfy this requirement under mild assumptions (antisymmetric
job prioritization that agrees across hyperperiods).
Definition respects_hyperperiod_reset :=
∀ reset_time,
arrival_periodicity_start ≤ reset_time →
self_contained_hyperperiod reset_time →
∀ elapsed,
elapsed < hyperperiod ts →
execution_repeats_at (reset_time + elapsed).
∀ reset_time,
arrival_periodicity_start ≤ reset_time →
self_contained_hyperperiod reset_time →
∀ elapsed,
elapsed < hyperperiod ts →
execution_repeats_at (reset_time + elapsed).
The consequence of the RDS contract is that execution repeats forever
after the initial transient, which we define here and establish below.
Self-Contained Hyperperiod Propagation
Lemma service_repeats_in_hyperperiod :
∀ start elapsed j,
j \in arrivals_between arr_seq start (start + hyperperiod ts) →
(∀ delta,
delta < elapsed →
execution_repeats_at (start + delta)) →
service sched
(next_hyperperiod_job ts arr_seq j)
(start + hyperperiod ts + elapsed)
= service sched j (start + elapsed).
∀ start elapsed j,
j \in arrivals_between arr_seq start (start + hyperperiod ts) →
(∀ delta,
delta < elapsed →
execution_repeats_at (start + delta)) →
service sched
(next_hyperperiod_job ts arr_seq j)
(start + hyperperiod ts + elapsed)
= service sched j (start + elapsed).
... which trivially extends to the pending predicate.
Corollary pending_repeats_in_hyperperiod :
∀ start elapsed j,
j \in arrivals_between arr_seq start (start + hyperperiod ts) →
(∀ delta, delta < elapsed → execution_repeats_at (start + delta)) →
pending sched
(next_hyperperiod_job ts arr_seq j)
(start + hyperperiod ts + elapsed)
= pending sched j (start + elapsed).
∀ start elapsed j,
j \in arrivals_between arr_seq start (start + hyperperiod ts) →
(∀ delta, delta < elapsed → execution_repeats_at (start + delta)) →
pending sched
(next_hyperperiod_job ts arr_seq j)
(start + hyperperiod ts + elapsed)
= pending sched j (start + elapsed).
We obtain the induction step for repeating self-contained hyperperiods.
Lemma self_contained_hyperperiod_propagates :
∀ start,
arrival_periodicity_start ≤ start →
self_contained_hyperperiod start →
(∀ elapsed,
elapsed < hyperperiod ts →
execution_repeats_at (start + elapsed)) →
self_contained_hyperperiod (start + hyperperiod ts).
∀ start,
arrival_periodicity_start ≤ start →
self_contained_hyperperiod start →
(∀ elapsed,
elapsed < hyperperiod ts →
execution_repeats_at (start + elapsed)) →
self_contained_hyperperiod (start + hyperperiod ts).
Repeating Schedule
Lemma no_carry_in_previous_hyperperiod :
∀ t,
no_carry_in arr_seq sched (t + hyperperiod ts) →
no_carry_in arr_seq sched t.
∀ t,
no_carry_in arr_seq sched (t + hyperperiod ts) →
no_carry_in arr_seq sched t.
With a self-contained hyperperiod in hand, we can now follow the
schedule forward. The RDS contract gives us matching execution in
the next hyperperiod, and the propagation lemma above tells us that
this next hyperperiod is self-contained too. We can therefore apply
the same reasoning again, carrying the repeating pattern forward.
Lemma self_contained_hyperperiod_repeats_forever :
respects_hyperperiod_reset →
∀ start,
arrival_periodicity_start ≤ start →
self_contained_hyperperiod start →
repeats_forever_from start.
respects_hyperperiod_reset →
∀ start,
arrival_periodicity_start ≤ start →
self_contained_hyperperiod start →
repeats_forever_from start.
Minimal Simulation Interval
Theorem minimal_simulation_interval :
respects_hyperperiod_reset →
∃ no_carry_in_instant,
first_no_carry_in_instant no_carry_in_instant
∧ no_carry_in_instant ≤ simulation_horizon
∧ repeats_forever_from (no_carry_in_instant - hyperperiod ts).
respects_hyperperiod_reset →
∃ no_carry_in_instant,
first_no_carry_in_instant no_carry_in_instant
∧ no_carry_in_instant ≤ simulation_horizon
∧ repeats_forever_from (no_carry_in_instant - hyperperiod ts).
Finite Deadline Check
Definition deadlines_checked_through (horizon : instant) :=
all (job_meets_deadline sched) (arrivals_up_to arr_seq horizon).
all (job_meets_deadline sched) (arrivals_up_to arr_seq horizon).
The repeating pattern explains why these representatives suffice.
Theorem 1 places a complete repeating hyperperiod within our simulation
horizon. Every later job has a matching predecessor one hyperperiod
earlier, with the same execution requirement and relative deadline.
Since matching jobs receive the same service at corresponding times,
they also share the same deadline outcome. Stepping backward through
these predecessors eventually brings us to a job covered by the finite
check. This gives us the guarantee for the entire schedule, as stated
in Lemma 4.7.
Theorem finite_deadline_check :
respects_hyperperiod_reset →
deadlines_checked_through simulation_horizon →
all_deadlines_of_arrivals_met arr_seq sched.
respects_hyperperiod_reset →
deadlines_checked_through simulation_horizon →
all_deadlines_of_arrivals_met arr_seq sched.
We follow the chain of matching predecessors by induction on arrival
time, until we reach a job whose deadline has already been checked.
We can now compare the job with its predecessor: the repeating
execution pattern gives them matching service through their
respective deadlines.
RDS Contract for JLFP Priority Policies
We begin with a JLFP policy, whose priority relation between jobs
stays fixed as time passes. We include the scheduler's way of
breaking priority ties in this relation too.
We consider fully preemptive jobs, so the scheduler can enforce the
priority order at every instant, ...
... and assume that the schedule indeed complies with job priorities at
all times.
To make the choice of job deterministic, we also ask that the order
resolve priority ties uniquely among arriving jobs. This is the role of
antisymmetry: together with policy compliance, it ensures that the
same pending jobs force the same choice.
Finally, the priority order must agree across hyperperiods. When we
replace jobs by their matching successors, their relative order,
including the way ties are broken, stays the same. This lets us carry a
scheduling decision from one hyperperiod to the next.
Let us first look at a single scheduling decision. Suppose execution
has already matched up to this point in the two hyperperiods. The
service and pending-job results above tell us that the chosen job's
matching successor is pending too. The preserved priority order
then puts this successor ahead of every competing choice.
Prosa's jlfp_pending_highest_priority_job_is_scheduled lemma lets
us conclude that the successor is indeed the job that runs. This
gives us the next matching decision.
Local Lemma jlfp_scheduled_job_repeats :
∀ start elapsed j,
arrival_periodicity_start ≤ start →
self_contained_hyperperiod start →
elapsed < hyperperiod ts →
(∀ delta, delta < elapsed → execution_repeats_at (start + delta)) →
scheduled_at sched j (start + elapsed) →
scheduled_at sched
(next_hyperperiod_job ts arr_seq j)
(start + hyperperiod ts + elapsed).
∀ start elapsed j,
arrival_periodicity_start ≤ start →
self_contained_hyperperiod start →
elapsed < hyperperiod ts →
(∀ delta, delta < elapsed → execution_repeats_at (start + delta)) →
scheduled_at sched j (start + elapsed) →
scheduled_at sched
(next_hyperperiod_job ts arr_seq j)
(start + hyperperiod ts + elapsed).
We can now build the matching execution of an entire hyperperiod,
one decision at a time. Whenever a job runs, the lemma above gives
us its matching successor in the next hyperperiod. Idle instants
match as well: corresponding jobs have the same pending status,
and work conservation makes the processor run whenever work is
ready. Induction carries these two observations through the
hyperperiod, establishing the reset contract.
With the reset contract established, we can apply the finite
deadline check from the preceding section to our JLFP schedule.
The jobs arriving up to and including the simulation horizon
serve as representatives whose deadline guarantees extend to
every later arrival.
Corollary jlfp_finite_deadline_check :
deadlines_checked_through simulation_horizon →
all_deadlines_of_arrivals_met arr_seq sched.
deadlines_checked_through simulation_horizon →
all_deadlines_of_arrivals_met arr_seq sched.
Finally, we can express the same guarantee from the tasks' point of
view. Since every arriving job meets its deadline, every task's releases
meet their deadlines too. This connects our finite check to the usual
notion of task-set schedulability.
Corollary jlfp_taskset_schedulable :
deadlines_checked_through simulation_horizon →
taskset_schedulable arr_seq sched ts.
End JLFP_RDS.
End SimulationInterval.
deadlines_checked_through simulation_horizon →
taskset_schedulable arr_seq sched ts.
End JLFP_RDS.
End SimulationInterval.
Applicability to EDF, FP, FIFO, GEL, and ELF
- The specialization tiebreaking_edf_finite_deadline_check in
prosa.results.periodic.simulation.edf applies directly to EDF with
task-ID and job-ID tie-breaking under valid_task_ids and
valid_job_ids.
- Similarly, tiebreaking_fp_finite_deadline_check in
prosa.results.periodic.simulation.fp applies to any task-level FP policy
with task-ID and job-ID tie-breaking under valid_task_ids,
valid_job_ids, and monotonic_job_ids. The latter constraint makes ties
between jobs of the same task follow arrival order, preserving priorities
across hyperperiods.
- The specialization tiebreaking_fifo_finite_deadline_check in
prosa.results.periodic.simulation.fifo likewise applies directly to FIFO
with task-ID and job-ID tie-breaking under the same ID validity
constraints as required by EDF.
- Under the same assumptions, the specialization
tiebreaking_gel_finite_deadline_check in
prosa.results.periodic.simulation.gel also applies to GEL with
task-derived priority points.
- Finally, tiebreaking_elf_finite_deadline_check in
prosa.results.periodic.simulation.elf applies to ELF over any task-level
FP policy with task-derived priority points, again with tie-breaking based
on task and job IDs.