Library prosa.analysis.facts.busy_interval.service_inversion
Require Export prosa.analysis.definitions.service_inversion.busy_prefix.
Require Export prosa.analysis.facts.busy_interval.pi.
Require Export prosa.analysis.facts.busy_interval.pi.
Consider any type of jobs.
Consider any kind of fully supply-consuming uniprocessor state model.
Context `{PState : ProcessorState Job}.
Hypothesis H_uniprocessor_proc_model : uniprocessor_model PState.
Hypothesis H_consumed_supply_proc_model : fully_consuming_proc_model PState.
Hypothesis H_uniprocessor_proc_model : uniprocessor_model PState.
Hypothesis H_consumed_supply_proc_model : fully_consuming_proc_model PState.
Consider any arrival sequence with consistent, non-duplicate arrivals ...
Variable arr_seq : arrival_sequence Job.
Hypothesis H_valid_arrival_sequence : valid_arrival_sequence arr_seq.
Hypothesis H_valid_arrival_sequence : valid_arrival_sequence arr_seq.
... and any uni-processor schedule of this arrival sequence...
Variable sched : schedule PState.
Hypothesis H_jobs_come_from_arrival_sequence :
jobs_come_from_arrival_sequence sched arr_seq.
Hypothesis H_jobs_come_from_arrival_sequence :
jobs_come_from_arrival_sequence sched arr_seq.
... where jobs do not execute before their arrival or after
completion.
Hypothesis H_jobs_must_arrive_to_execute : jobs_must_arrive_to_execute sched.
Hypothesis H_completed_jobs_dont_execute : completed_jobs_dont_execute sched.
Hypothesis H_completed_jobs_dont_execute : completed_jobs_dont_execute sched.
In this section, we prove a few basic lemmas about priority inversion.
Consider an JLDP policy that indicates a higher-or-equal
priority relation, and assume that the relation is
reflexive.
First, we show that a blackout at a time instant t implies
that there is no service inversion at time t.
Lemma blackout_implies_no_service_inversion :
∀ (j : Job) (t : instant),
is_blackout sched t →
~~ service_inversion arr_seq sched j t.
∀ (j : Job) (t : instant),
is_blackout sched t →
~~ service_inversion arr_seq sched j t.
Similarly, there is no service inversion at an idle time instant.
Lemma idle_implies_no_service_inversion :
∀ (j : Job) (t : instant),
is_idle arr_seq sched t →
~~ service_inversion arr_seq sched j t.
∀ (j : Job) (t : instant),
is_idle arr_seq sched t →
~~ service_inversion arr_seq sched j t.
Next, we prove that if a job j receives service at time t,
job j does not incur service inversion at time t.
Lemma receives_service_implies_no_service_inversion :
∀ (j : Job) (t : instant),
receives_service_at sched j t →
~~ service_inversion arr_seq sched j t.
∀ (j : Job) (t : instant),
receives_service_at sched j t →
~~ service_inversion arr_seq sched j t.
We show that cumulative service inversion received during an
interval
[t1, t2)
can be split into the sum of cumulative
service inversion [t1, t)
and [t, t2)
for any t2 \in
t1, t3>>.
Lemma service_inversion_cat :
∀ (j : Job) (t1 t2 t : instant),
t1 ≤ t →
t ≤ t2 →
cumulative_service_inversion arr_seq sched j t1 t2
= cumulative_service_inversion arr_seq sched j t1 t
+ cumulative_service_inversion arr_seq sched j t t2.
∀ (j : Job) (t1 t2 t : instant),
t1 ≤ t →
t ≤ t2 →
cumulative_service_inversion arr_seq sched j t1 t2
= cumulative_service_inversion arr_seq sched j t1 t
+ cumulative_service_inversion arr_seq sched j t t2.
Next, we show that cumulative service inversion on an interval
[al, ar)
is bounded by the cumulative service inversion on
an interval [bl,br)
if [al,ar)
⊆ [bl,br)
.
Lemma service_inversion_widen :
∀ (j : Job) (al ar bl br : instant),
bl ≤ al →
ar ≤ br →
cumulative_service_inversion arr_seq sched j al ar
≤ cumulative_service_inversion arr_seq sched j bl br.
End BasicLemmas.
∀ (j : Job) (al ar bl br : instant),
bl ≤ al →
ar ≤ br →
cumulative_service_inversion arr_seq sched j al ar
≤ cumulative_service_inversion arr_seq sched j bl br.
End BasicLemmas.
In the following section, we prove one rewrite rule about
service inversion.
Consider a reflexive JLDP policy.
Consider a time instant t ...
... and assume that there is supply at t.
Then the predicate "is there service inversion for job j' at
time t?" is equal to the predicate "is job j has lower
priority than job j'?"
Lemma service_inversion_supply_sched :
service_inversion arr_seq sched j' t = ~~ hep_job_at t j j'.
End ServiceInversionRewrite.
service_inversion arr_seq sched j' t = ~~ hep_job_at t j j'.
End ServiceInversionRewrite.
In the last section, we prove that cumulative service inversion
is bounded by cumulative priority inversion.
Consider a reflexive JLFP policy.
Note that, unlike the other sections, this section assumes a
JLFP policy. This is due to the fact that priority inversion
is defined in terms of JLFP policies. This is not a
fundamental assumption and may be relaxed in the future.
Context {JLFP : JLFP_policy Job}.
Hypothesis H_priority_is_reflexive : reflexive_job_priorities JLFP.
Hypothesis H_priority_is_reflexive : reflexive_job_priorities JLFP.
We prove that service inversion implies priority inversion ...
Lemma service_inv_implies_priority_inv :
∀ (j : Job) (t : instant),
service_inversion arr_seq sched j t →
priority_inversion arr_seq sched j t.
∀ (j : Job) (t : instant),
service_inversion arr_seq sched j t →
priority_inversion arr_seq sched j t.
... and, as a corollary, it is easy to see that cumulative
service inversion is bounded by cumulative priority
inversion.
Corollary cumul_service_inv_le_cumul_priority_inv :
∀ (j : Job) (t1 t2 : instant),
cumulative_service_inversion arr_seq sched j t1 t2
≤ cumulative_priority_inversion arr_seq sched j t1 t2.
End PriorityInversion.
End ServiceInversion.
∀ (j : Job) (t1 t2 : instant),
cumulative_service_inversion arr_seq sched j t1 t2
≤ cumulative_priority_inversion arr_seq sched j t1 t2.
End PriorityInversion.
End ServiceInversion.
In the following, we prove that the cumulative service inversion
in a busy interval prefix is bounded.
Consider any type of tasks ...
... and any type of jobs associated with these tasks.
Context {Job : JobType}.
Context `{JobTask Job Task}.
Context `{JobArrival Job}.
Context `{JobCost Job}.
Context `{JobTask Job Task}.
Context `{JobArrival Job}.
Context `{JobCost Job}.
Consider any kind of fully supply-consuming unit-supply
uniprocessor state model.
Context `{PState : ProcessorState Job}.
Hypothesis H_uniprocessor_proc_model : uniprocessor_model PState.
Hypothesis H_unit_supply_proc_model : unit_supply_proc_model PState.
Hypothesis H_consumed_supply_proc_model : fully_consuming_proc_model PState.
Hypothesis H_uniprocessor_proc_model : uniprocessor_model PState.
Hypothesis H_unit_supply_proc_model : unit_supply_proc_model PState.
Hypothesis H_consumed_supply_proc_model : fully_consuming_proc_model PState.
Consider an JLFP policy that indicates a higher-or-equal priority
relation, and assume that the relation is reflexive and
transitive.
Context {JLFP : JLFP_policy Job}.
Hypothesis H_priority_is_reflexive : reflexive_job_priorities JLFP.
Hypothesis H_priority_is_transitive : transitive_job_priorities JLFP.
Hypothesis H_priority_is_reflexive : reflexive_job_priorities JLFP.
Hypothesis H_priority_is_transitive : transitive_job_priorities JLFP.
Consider any arrival sequence with consistent, non-duplicate arrivals ...
Variable arr_seq : arrival_sequence Job.
Hypothesis H_valid_arrival_sequence : valid_arrival_sequence arr_seq.
Hypothesis H_valid_arrival_sequence : valid_arrival_sequence arr_seq.
... and any uni-processor schedule of this arrival sequence.
Next, allow for any work-bearing notion of job readiness ...
... and assume that the schedule is valid.
In addition, we assume the existence of a function mapping jobs
to their preemption points ...
... and assume that it defines a valid preemption model with
bounded non-preemptive segments.
Hypothesis H_valid_preemption_model : valid_preemption_model arr_seq sched.
Hypothesis H_valid_model_with_bounded_nonpreemptive_segments :
valid_model_with_bounded_nonpreemptive_segments arr_seq sched.
Hypothesis H_valid_model_with_bounded_nonpreemptive_segments :
valid_model_with_bounded_nonpreemptive_segments arr_seq sched.
Next, we assume that the schedule respects the scheduling policy.
In the following section, we prove that cumulative service
inversion in a busy-interval prefix is necessarily caused by one
lower-priority job.
Consider any job j with a positive job cost.
Variable j : Job.
Hypothesis H_j_arrives : arrives_in arr_seq j.
Hypothesis H_job_cost_positive : job_cost_positive j.
Hypothesis H_j_arrives : arrives_in arr_seq j.
Hypothesis H_job_cost_positive : job_cost_positive j.
... the cumulative service inversion is positive in
[t1, t)
.
First, note that there is a lower-priority job that receives
service at some time during the time interval
[t1, t)
.
Local Lemma lower_priority_job_receives_service :
∃ (jlp : Job) (to : instant),
t1 ≤ to < t
∧ ~~ hep_job jlp j
∧ receives_service_at sched jlp to.
∃ (jlp : Job) (to : instant),
t1 ≤ to < t
∧ ~~ hep_job jlp j
∧ receives_service_at sched jlp to.
Then we prove that the service inversion incurred by job j
can only be caused by one lower priority job.
Lemma cumulative_service_inversion_from_one_job :
∃ (jlp : Job),
job_arrival jlp < t1
∧ ~~ hep_job jlp j
∧ cumulative_service_inversion arr_seq sched j t1 t = service_during sched jlp t1 t.
End CumulativeServiceInversionFromOneJob.
∃ (jlp : Job),
job_arrival jlp < t1
∧ ~~ hep_job jlp j
∧ cumulative_service_inversion arr_seq sched j t1 t = service_during sched jlp t1 t.
End CumulativeServiceInversionFromOneJob.
In this section, we prove that, given a job j with a busy
interval prefix
[t1, t2)
and a lower-priority job jlp, the
service of jlp within the busy interval prefix is bounded by
the maximum non-preemptive segment of job jlp.
Consider an arbitrary job j with positive cost ...
Variable j : Job.
Hypothesis H_j_arrives : arrives_in arr_seq j.
Hypothesis H_j_job_cost_positive : job_cost_positive j.
Hypothesis H_j_arrives : arrives_in arr_seq j.
Hypothesis H_j_job_cost_positive : job_cost_positive j.
... and a lower-priority job jlp.
Variable jlp : Job.
Hypothesis H_jlp_arrives : arrives_in arr_seq jlp.
Hypothesis H_jlp_lp : ~~ hep_job jlp j.
Hypothesis H_jlp_arrives : arrives_in arr_seq jlp.
Hypothesis H_jlp_lp : ~~ hep_job jlp j.
Let
[t1, t2)
be a busy interval prefix of job j.
First, we consider a scenario when there is no preemption time
inside of the busy interval prefix but there is a time
instant where jlp is scheduled. In this case, the cumulative
service inversion of job j in the time interval
[t1, t2)
is bounded by the total service of job jlp received in the
interval [t1, t2)
.
Local Lemma no_preemption_impl_service_inv_bounded :
(∀ t, t1 ≤ t < t2 → ~~ preemption_time arr_seq sched t) →
(∃ t, t1 ≤ t < t2 ∧ scheduled_at sched jlp t) →
cumulative_service_inversion arr_seq sched j t1 t2 ≤ service_during sched jlp t1 t2.
(∀ t, t1 ≤ t < t2 → ~~ preemption_time arr_seq sched t) →
(∃ t, t1 ≤ t < t2 ∧ scheduled_at sched jlp t) →
cumulative_service_inversion arr_seq sched j t1 t2 ≤ service_during sched jlp t1 t2.
In this section, we assume that jlp is scheduled inside of
the busy interval prefix and prove that its service is bounded
by jlp's maximum non-preemptive segment.
Variable st : instant.
Hypothesis H_t1_le_st_lt_t : t1 ≤ st < t.
Hypothesis H_jlp_sched : scheduled_at sched jlp st.
Hypothesis H_t1_le_st_lt_t : t1 ≤ st < t.
Hypothesis H_jlp_sched : scheduled_at sched jlp st.
Consider a preemption point σ of job jlp such that ...
... σ is greater than or equal to the service of jlp at
time t1 but exceeds the service by at most
job_max_nonpreemptive_segment jlp - ε.
Hypothesis H_σ_constrained :
service sched jlp t1
≤ σ
≤ service sched jlp t1 + (job_max_nonpreemptive_segment jlp - ε).
service sched jlp t1
≤ σ
≤ service sched jlp t1 + (job_max_nonpreemptive_segment jlp - ε).
Next, we perform case analysis on whether job jlp has
reached σ units of service by time t.
First, assume that the service of jlp at time t is
smaller than σ. In this case, it is easy to see from the
hypothesis H_σ_constrained that the service received by
jlp within time interval
[t1, t)
is bounded by
job_max_nonpreemptive_segment jlp - ε.
Local Lemma small_service_implies_bounded_service :
service sched jlp t < σ →
service_during sched jlp t1 t ≤ job_max_nonpreemptive_segment jlp - ε.
service sched jlp t < σ →
service_during sched jlp t1 t ≤ job_max_nonpreemptive_segment jlp - ε.
Next, assume that σ ≤ service sched jlp t. In this case,
we can show that jlp is preempted after it reaches σ
units of service and hence, again, the service during
[t1,
t)>> is bounded by job_max_nonpreemptive_segment jlp - ε.
Local Lemma big_service_implies_bounded_service :
σ ≤ service sched jlp t →
service_during sched jlp t1 t ≤ job_max_nonpreemptive_segment jlp - ε.
σ ≤ service sched jlp t →
service_during sched jlp t1 t ≤ job_max_nonpreemptive_segment jlp - ε.
Either way, the service of job jlp during the time
interval
[t1, t)
is bounded by
job_max_nonpreemptive_segment jlp - ε.
Local Lemma lp_job_bounded_service_aux :
service_during sched jlp t1 t ≤ job_max_nonpreemptive_segment jlp - ε.
End ServiceOfLPJobIsBounded.
service_during sched jlp t1 t ≤ job_max_nonpreemptive_segment jlp - ε.
End ServiceOfLPJobIsBounded.
Note that the preemption point σ assumed in the previous
section always exists.
Local Remark preemption_point_of_jlp_exists :
∃ σ,
service sched jlp t1 ≤ σ ≤ service sched jlp t1 + (job_max_nonpreemptive_segment jlp - ε)
∧ job_preemptable jlp σ.
∃ σ,
service sched jlp t1 ≤ σ ≤ service sched jlp t1 + (job_max_nonpreemptive_segment jlp - ε)
∧ job_preemptable jlp σ.
We strengthen the lemma lp_job_bounded_service_aux by
removing the assumption that jlp is scheduled somewhere in
the busy interval prefix.
Lemma lp_job_bounded_service :
∀ t,
t ≤ t2 →
service_during sched jlp t1 t ≤ job_max_nonpreemptive_segment jlp - ε.
∀ t,
t ≤ t2 →
service_during sched jlp t1 t ≤ job_max_nonpreemptive_segment jlp - ε.
Finally, we remove jlp from the RHS of the inequality by
taking the maximum over all jobs that arrive before time t1.
Lemma lp_job_bounded_service_max :
∀ t,
t ≤ t2 →
service_during sched jlp t1 t ≤ max_lp_nonpreemptive_segment arr_seq j t1.
End ServiceOfLowPriorityJobIsBounded.
∀ t,
t ≤ t2 →
service_during sched jlp t1 t ≤ max_lp_nonpreemptive_segment arr_seq j t1.
End ServiceOfLowPriorityJobIsBounded.
Let tsk be any task to be analyzed.
Let blocking_bound be a bound on the maximum length of a
nonpreemptive segment of a lower-priority job.
We show that, if the maximum length of a nonpreemptive segment
is bounded by the blocking bound, ...
Hypothesis H_priority_inversion_is_bounded_by_blocking :
∀ j t1 t2,
arrives_in arr_seq j →
job_of_task tsk j →
busy_interval_prefix arr_seq sched j t1 t2 →
max_lp_nonpreemptive_segment arr_seq j t1 ≤ blocking_bound (job_arrival j - t1).
∀ j t1 t2,
arrives_in arr_seq j →
job_of_task tsk j →
busy_interval_prefix arr_seq sched j t1 t2 →
max_lp_nonpreemptive_segment arr_seq j t1 ≤ blocking_bound (job_arrival j - t1).
... then the service inversion incurred by any job is bounded by
the blocking bound.