Library prosa.classic.analysis.uni.susp.dynamic.jitter.taskset_membership
Require Import prosa.classic.util.all.
Require Import prosa.classic.model.priority prosa.classic.model.suspension.
Require Import prosa.classic.model.arrival.basic.task prosa.classic.model.arrival.basic.job
prosa.classic.model.arrival.basic.arrival_sequence.
Require Import prosa.classic.model.arrival.jitter.job.
Require Import prosa.classic.model.schedule.uni.response_time.
Require Import prosa.classic.model.schedule.uni.susp.schedule
prosa.classic.model.schedule.uni.susp.platform
prosa.classic.model.schedule.uni.susp.valid_schedule.
Require Import prosa.classic.analysis.uni.susp.dynamic.jitter.jitter_schedule
prosa.classic.analysis.uni.susp.dynamic.jitter.jitter_taskset_generation.
Require Import prosa.classic.analysis.uni.susp.sustainability.singlecost.reduction
prosa.classic.analysis.uni.susp.sustainability.singlecost.reduction_properties.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq fintype bigop.
Module TaskSetMembership.
Import SporadicTaskset Suspension Priority ValidSuspensionAwareSchedule
ScheduleWithSuspensions ResponseTime PlatformWithSuspensions.
Module reduction := JitterScheduleConstruction.
Module ts_gen := JitterTaskSetGeneration.
Module sust := SustainabilitySingleCost.
Module sust_prop := SustainabilitySingleCostProperties.
Module valid_sched := ValidSuspensionAwareSchedule.
Module job_susp := Job.
Module job_jitter := JobWithJitter.
Section ProvingMembership.
Context {Task: eqType}.
Variable task_period: Task → time.
Variable task_deadline: Task → time.
Context {Job: eqType}.
Variable job_arrival: Job → time.
Variable job_deadline: Job → time.
Variable job_task: Job → Task.
Require Import prosa.classic.model.priority prosa.classic.model.suspension.
Require Import prosa.classic.model.arrival.basic.task prosa.classic.model.arrival.basic.job
prosa.classic.model.arrival.basic.arrival_sequence.
Require Import prosa.classic.model.arrival.jitter.job.
Require Import prosa.classic.model.schedule.uni.response_time.
Require Import prosa.classic.model.schedule.uni.susp.schedule
prosa.classic.model.schedule.uni.susp.platform
prosa.classic.model.schedule.uni.susp.valid_schedule.
Require Import prosa.classic.analysis.uni.susp.dynamic.jitter.jitter_schedule
prosa.classic.analysis.uni.susp.dynamic.jitter.jitter_taskset_generation.
Require Import prosa.classic.analysis.uni.susp.sustainability.singlecost.reduction
prosa.classic.analysis.uni.susp.sustainability.singlecost.reduction_properties.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq fintype bigop.
Module TaskSetMembership.
Import SporadicTaskset Suspension Priority ValidSuspensionAwareSchedule
ScheduleWithSuspensions ResponseTime PlatformWithSuspensions.
Module reduction := JitterScheduleConstruction.
Module ts_gen := JitterTaskSetGeneration.
Module sust := SustainabilitySingleCost.
Module sust_prop := SustainabilitySingleCostProperties.
Module valid_sched := ValidSuspensionAwareSchedule.
Module job_susp := Job.
Module job_jitter := JobWithJitter.
Section ProvingMembership.
Context {Task: eqType}.
Variable task_period: Task → time.
Variable task_deadline: Task → time.
Context {Job: eqType}.
Variable job_arrival: Job → time.
Variable job_deadline: Job → time.
Variable job_task: Job → Task.
Basic Setup & Setting
Variable ts: seq Task.
Variable arr_seq: arrival_sequence Job.
Hypothesis H_arrival_times_are_consistent:
arrival_times_are_consistent job_arrival arr_seq.
Hypothesis H_arrival_sequence_is_a_set: arrival_sequence_is_a_set arr_seq.
Hypothesis H_jobs_come_from_taskset:
∀ j, arrives_in arr_seq j → job_task j \in ts.
Variable job_cost: Job → time.
Variable task_cost: Task → time.
Variable job_suspension_duration: job_suspension Job.
Variable task_suspension_bound: Task → time.
Variable higher_eq_priority: FP_policy Task.
Hypothesis H_priority_is_reflexive: FP_is_reflexive higher_eq_priority.
Hypothesis H_priority_is_transitive: FP_is_transitive higher_eq_priority.
Hypothesis H_priority_is_total: FP_is_total_over_task_set higher_eq_priority ts.
Let job_higher_eq_priority := FP_to_JLDP job_task higher_eq_priority.
Let is_valid_suspension_aware_schedule :=
valid_suspension_aware_schedule job_arrival arr_seq job_higher_eq_priority
job_suspension_duration.
Variable sched_susp: schedule Job.
Hypothesis H_valid_schedule:
valid_suspension_aware_schedule job_arrival arr_seq job_higher_eq_priority
job_suspension_duration job_cost sched_susp.
Let task_response_time_in_sched_susp_bounded_by :=
is_response_time_bound_of_task job_arrival job_cost job_task arr_seq sched_susp.
Let job_response_time_in_sched_susp_bounded_by :=
is_response_time_bound_of_job job_arrival job_cost sched_susp.
Analysis Setup
Variable tsk_i: Task.
Hypothesis H_tsk_in_ts: tsk_i \in ts.
Variable j: Job.
Hypothesis H_j_arrives: arrives_in arr_seq j.
Hypothesis H_job_of_tsk_i: job_task j = tsk_i.
Let is_task_response_time_bound_with job_cost sched :=
is_response_time_bound_of_task job_arrival job_cost job_task arr_seq sched.
Let other_hep_task tsk_other := higher_eq_priority tsk_other tsk_i && (tsk_other != tsk_i).
Variable R: Task → time.
Hypothesis H_valid_response_time_bound_of_hp_tasks_in_all_schedules:
∀ job_cost sched,
is_valid_suspension_aware_schedule job_cost sched →
∀ tsk_hp,
tsk_hp \in ts →
other_hep_task tsk_hp →
is_task_response_time_bound_with job_cost sched tsk_hp (R tsk_hp).
Definition actual_response_time (j_hp: Job) : time :=
[pick-min r ≤ R (job_task j_hp) |
job_response_time_in_sched_susp_bounded_by j_hp r].
Corollary actual_response_time_is_valid:
∀ j_hp,
arrives_in arr_seq j_hp →
other_hep_task (job_task j_hp) →
job_response_time_in_sched_susp_bounded_by j_hp (actual_response_time j_hp).
Proof.
rename H_valid_response_time_bound_of_hp_tasks_in_all_schedules into RESPhp,
H_jobs_come_from_taskset into FROM.
intros j_hp ARRhp HP.
rewrite /actual_response_time.
apply pick_min_holds; last by done.
∃ (R (job_task j_hp)); split; first by done.
by apply RESPhp; try (by done); first by apply FROM.
Qed.
Corollary actual_response_time_is_minimum:
∀ j_hp r_hp,
arrives_in arr_seq j_hp →
other_hep_task (job_task j_hp) →
job_response_time_in_sched_susp_bounded_by j_hp r_hp →
actual_response_time j_hp ≤ r_hp.
Proof.
rename H_valid_response_time_bound_of_hp_tasks_in_all_schedules into RESPhp,
H_jobs_come_from_taskset into FROM.
intros j_hp r_hp ARRhp HP RESP.
case (leqP r_hp (R (job_task j_hp))) ⇒ [LT | GE].
{
rewrite /actual_response_time.
apply pick_min_holds;
last by intros x RESPx _ MINx; rewrite -ltnS in LT; apply (MINx (Ordinal LT)).
∃ (R (job_task j_hp)); split; first by done.
by apply RESPhp; try (by done); first by apply FROM.
}
{
apply leq_trans with (n := (R (job_task j_hp))); last by apply ltnW.
rewrite -ltnS /actual_response_time.
apply pick_min_ltn.
∃ (R (job_task j_hp)); split; first by done.
by apply RESPhp; try (by done); first by apply FROM.
}
Qed.
Instantiation of the Reduction
Let inflated_job_cost := reduction.inflated_job_cost job_cost job_suspension_duration j.
Let job_jitter := reduction.job_jitter job_arrival job_task higher_eq_priority job_cost j
actual_response_time.
Let inflated_task_cost := ts_gen.inflated_task_cost task_cost task_suspension_bound tsk_i.
Let task_jitter := ts_gen.task_jitter task_cost higher_eq_priority tsk_i R.
Proof of Task Set Membership
Hypothesis H_positive_costs:
∀ j, arrives_in arr_seq j → job_cost j > 0.
Hypothesis H_job_cost_le_task_cost:
∀ j,
arrives_in arr_seq j →
job_cost j ≤ task_cost (job_task j).
Hypothesis H_dynamic_suspensions:
dynamic_suspension_model job_cost job_task job_suspension_duration task_suspension_bound.
Section JobCostPositive.
Lemma ts_membership_inflated_job_cost_positive:
∀ j, arrives_in arr_seq j → inflated_job_cost j > 0.
Proof.
intros j0 ARR0.
apply leq_trans with (n := job_cost j0); first by apply H_positive_costs.
rewrite /inflated_job_cost /reduction.inflated_job_cost.
by case: ifP ⇒ _; first by apply leq_addr.
Qed.
End JobCostPositive.
Section JobCostBoundedByTaskCost.
Lemma ts_membership_inflated_job_cost_le_inflated_task_cost:
∀ j,
arrives_in arr_seq j →
inflated_job_cost j ≤ inflated_task_cost (job_task j).
Proof.
intros j' ARR'.
rewrite /inflated_job_cost /inflated_task_cost /reduction.inflated_job_cost
/ts_gen.inflated_task_cost.
case: ifP ⇒ [/eqP SAME | NEQ]; subst.
{
rewrite eq_refl; apply leq_add; last by apply H_dynamic_suspensions.
by apply H_job_cost_le_task_cost.
}
case: ifP ⇒ [SAMEtsk | DIFFtsk]; last by apply H_job_cost_le_task_cost.
apply leq_trans with (n := task_cost (job_task j')); last by apply leq_addr.
by apply H_job_cost_le_task_cost.
Qed.
End JobCostBoundedByTaskCost.
Section JobJitterBoundedByTaskJitter.
Variable any_j: Job.
Hypothesis H_any_j_arrives: arrives_in arr_seq any_j.
Section JitterOfHigherPriorityJobs.
Hypothesis H_higher_priority: higher_eq_priority (job_task any_j) tsk_i.
Hypothesis H_different_task: job_task any_j != tsk_i.
Let higher_cost_wcet j' :=
if j' == any_j then task_cost (job_task any_j) else job_cost j'.
Let sched_susp_highercost :=
sust.sched_susp_highercost job_arrival arr_seq job_higher_eq_priority
sched_susp job_suspension_duration higher_cost_wcet.
Let task_response_time_in_sched_susp_highercost_bounded_by :=
is_response_time_bound_of_task job_arrival higher_cost_wcet job_task arr_seq
sched_susp_highercost.
Remark response_time_bound_in_sched_susp_highercost:
∀ tsk_hp,
tsk_hp \in ts →
other_hep_task tsk_hp →
task_response_time_in_sched_susp_highercost_bounded_by tsk_hp (R tsk_hp).
Proof.
rename H_valid_response_time_bound_of_hp_tasks_in_all_schedules into RESPhp,
H_jobs_come_from_taskset into FROM, H_valid_schedule into VALID.
split_conj VALID.
feed (RESPhp higher_cost_wcet sched_susp_highercost).
{
repeat split.
- by apply sust_prop.sched_susp_highercost_jobs_come_from_arrival_sequence.
- by apply sust_prop.sched_susp_highercost_jobs_must_arrive_to_execute.
- by apply sust_prop.sched_susp_highercost_completed_jobs_dont_execute.
- by apply sust_prop.sched_susp_highercost_work_conserving.
- apply sust_prop.sched_susp_highercost_respects_policy; try (by done).
-- by intros t j1 j2 j3; apply H_priority_is_transitive.
-- by intros j1 j2 t ARR1 ARR2; apply/orP; apply H_priority_is_total; apply FROM.
- by apply sust_prop.sched_susp_highercost_respects_self_suspensions.
}
by intros tsk_hp IN Ohp; by apply RESPhp.
Qed.
Lemma ts_membership_difference_in_response_times:
actual_response_time any_j - job_cost any_j ≤
R (job_task any_j) - task_cost (job_task any_j).
Proof.
have VALIDr := actual_response_time_is_valid.
have MINr := actual_response_time_is_minimum.
have RESPhp := response_time_bound_in_sched_susp_highercost.
rename H_jobs_come_from_taskset into FROM, H_valid_schedule into VALIDSCHED.
split_conj VALIDSCHED.
apply leq_trans with (n := R (job_task any_j) - higher_cost_wcet any_j);
last by apply leq_sub2l; rewrite /higher_cost_wcet eq_refl.
try ( apply sust_prop.sched_susp_highercost_incurs_more_interference with
(job_arrival0 := job_arrival) (arr_seq0 := arr_seq) (sched_susp0 := sched_susp)
(higher_eq_priority0:=job_higher_eq_priority)
(job_suspension_duration0 := job_suspension_duration); try (by done) ) ||
apply sust_prop.sched_susp_highercost_incurs_more_interference with
(job_arrival := job_arrival) (arr_seq := arr_seq) (sched_susp := sched_susp)
(higher_eq_priority:=job_higher_eq_priority)
(job_suspension_duration := job_suspension_duration); try (by done).
- by intros t j1; apply H_priority_is_reflexive.
- by rewrite /higher_cost_wcet eq_refl; apply H_job_cost_le_task_cost.
- by move ⇒ j' NEQ; apply negbTE in NEQ; rewrite /higher_cost_wcet NEQ.
- by apply H_positive_costs.
- by apply VALIDr; try (by done); apply/andP; split.
- by intros r' RESP; apply MINr; try (by done); first by apply/andP; split.
- by apply RESPhp; try (by done); [apply FROM | apply/andP; split].
Qed.
End JitterOfHigherPriorityJobs.
Lemma ts_membership_job_jitter_le_task_jitter:
job_jitter any_j ≤ task_jitter (job_task any_j).
Proof.
have DIFF := ts_membership_difference_in_response_times.
rewrite /job_jitter /task_jitter /reduction.job_jitter /ts_gen.task_jitter H_job_of_tsk_i.
case: ifP ⇒ // /andP [HP' NEQ].
rewrite /minn; case: ifP ⇒ [LTdist | GEdist]; last by apply DIFF.
case (leqP (job_arrival j) (job_arrival any_j)) ⇒ [AFTER | BEFORE];
first by apply leq_trans with (n := 0); first rewrite leqn0 subn_eq0.
apply leq_trans with (n := actual_response_time any_j - job_cost any_j); first by apply ltnW.
by apply DIFF.
Qed.
End JobJitterBoundedByTaskJitter.
End ProvingMembership.
End TaskSetMembership.