From 9cc286c23e7d6f641c796552614cecd0bcec6033 Mon Sep 17 00:00:00 2001 From: Sergei Bozhko <sbozhko@mpi-sws.org> Date: Wed, 6 Oct 2021 16:16:15 +0200 Subject: [PATCH] move lemma [early_hep_job_is_scheduled] to separate file --- analysis/definitions/always_higher_priority.v | 20 ++++ analysis/facts/{ => priority}/edf.v | 64 +++---------- analysis/facts/priority/sequential.v | 94 +++++++++++++++++++ results/edf/rta/bounded_pi.v | 2 +- 4 files changed, 127 insertions(+), 53 deletions(-) create mode 100644 analysis/definitions/always_higher_priority.v rename analysis/facts/{ => priority}/edf.v (59%) create mode 100644 analysis/facts/priority/sequential.v diff --git a/analysis/definitions/always_higher_priority.v b/analysis/definitions/always_higher_priority.v new file mode 100644 index 000000000..34aa16969 --- /dev/null +++ b/analysis/definitions/always_higher_priority.v @@ -0,0 +1,20 @@ +Require Export prosa.model.priority.classes. + +(** * Always Higher Priority *) +(** In this section, we define what it means for a job to always have + a higher priority than another job. *) +Section AlwaysHigherPriority. + + (** Consider any type of jobs ... *) + Context {Job : JobType}. + + (** ... and any JLDP policy. *) + Context `{JLDP_policy Job}. + + (** We say that a job [j1] always has higher priority than job [j2] + if, at any time [t], the priority of job [j1] is strictly higher than + the priority of job [j2]. *) + Definition always_higher_priority (j1 j2 : Job) := + forall t, hep_job_at t j1 j2 && ~~ hep_job_at t j2 j1. + +End AlwaysHigherPriority. diff --git a/analysis/facts/edf.v b/analysis/facts/priority/edf.v similarity index 59% rename from analysis/facts/edf.v rename to analysis/facts/priority/edf.v index 95d1d7c38..340dc68e8 100644 --- a/analysis/facts/edf.v +++ b/analysis/facts/priority/edf.v @@ -36,6 +36,7 @@ Global Hint Resolve EDF_respects_sequential_tasks : basic_facts. Require Export prosa.model.task.sequentiality. Require Export prosa.analysis.facts.busy_interval.priority_inversion. +Require Export prosa.analysis.facts.priority.sequential. (** In this section, we prove that EDF priority policy implies that tasks are sequential. *) @@ -81,64 +82,23 @@ Section SequentialEDF. valid_model_with_bounded_nonpreemptive_segments arr_seq sched. (** Next, we assume that the schedule respects the policy defined by - the [job_preemptable] function (i.e., jobs have bounded - non-preemptive segments). *) + the [job_preemptable] function (i.e., jobs have bounded + non-preemptive segments). *) Hypothesis H_respects_policy : respects_policy_at_preemption_point arr_seq sched. - - (** We say that a job [j1] always has higher priority than job [j2] - if, at any time [t], the priority of job [j1] is strictly higher than - priority of job [j2]. - - NB: this definition and the following lemma are general facts about - priority policies on uniprocessors that depend on neither EDF nor the ideal uniprocessor assumption. Generalizing to any priority policy and processor - model left to future work. - (https://gitlab.mpi-sws.org/RT-PROOFS/rt-proofs/-/issues/78). *) - Definition always_higher_priority j1 j2 := - forall t, hep_job_at t j1 j2 && ~~ hep_job_at t j2 j1. - - (** First, we show that, given two jobs [j1] and [j2], if job [j1] - arrives earlier than job [j2] and [j1] always has higher - priority than [j2], then [j2] is scheduled only after [j1] is - completed. *) - Lemma early_hep_job_is_scheduled: - forall j1 j2, - arrives_in arr_seq j1 -> - job_arrival j1 < job_arrival j2 -> - always_higher_priority j1 j2 -> - forall t, - scheduled_at sched j2 t -> - completed_by sched j1 t. - Proof. - move=> j1 j2 ARR LE AHP t SCHED; apply/negPn/negP; intros NCOMPL. - move: H_sched_valid => [COARR MBR]. - have ARR_EXEC := jobs_must_arrive_to_be_ready sched MBR. - edestruct scheduling_of_any_segment_starts_with_preemption_time - as [pt [LET [PT ALL_SCHED]]]; try eauto 2. - move: LET => /andP [LE1 LE2]. - specialize (ALL_SCHED pt); feed ALL_SCHED; first by apply/andP; split. - have PEND1: pending sched j1 pt. - { apply/andP; split. - - by rewrite /has_arrived; ssrlia. - - by move: NCOMPL; apply contra, completion_monotonic. - } - apply H_job_ready in PEND1 => //; destruct PEND1 as [j3 [ARR3 [READY3 HEP3]]]. - move: (AHP pt) => /andP[HEP /negP NHEP]; eapply NHEP. - eapply EDF_is_transitive; last by apply HEP3. - eapply H_respects_policy; eauto 2. - apply/andP; split; first by done. - apply/negP; intros SCHED2. - have EQ := ideal_proc_model_is_a_uniprocessor_model _ _ _ pt SCHED2 ALL_SCHED. - subst j2; rename j3 into j. - by specialize (AHP 0); destruct AHP; auto. - Qed. - (** Clearly, under the EDF priority policy, jobs satisfy the conditions - described by the lemma above; hence EDF implies sequential tasks. *) + (** To prove sequentiality, we use lemma + [early_hep_job_is_scheduled]. Clearly, under the EDF priority + policy, jobs satisfy the conditions described by the lemma + (i.e., given two jobs [j1] and [j2] from the same task, if [j1] + arrives earlier than [j2], then [j1] always has a higher + priority than job [j2], and hence completes before [j2]); + therefore EDF implies sequential tasks. *) Lemma EDF_implies_sequential_tasks: sequential_tasks arr_seq sched. Proof. intros ? ? ? ARR1 ARR2 SAME LT. - apply early_hep_job_is_scheduled => //. + eapply early_hep_job_is_scheduled => //; eauto 2. + - by auto with basic_facts. - clear t; intros ?. move: SAME => /eqP SAME. apply /andP. diff --git a/analysis/facts/priority/sequential.v b/analysis/facts/priority/sequential.v new file mode 100644 index 000000000..790bf443d --- /dev/null +++ b/analysis/facts/priority/sequential.v @@ -0,0 +1,94 @@ +Require Export prosa.analysis.definitions.always_higher_priority. +Require Export prosa.analysis.facts.busy_interval.priority_inversion. + +(** In this section, we prove that, given two jobs [j1] and [j2], if + job [j1] arrives earlier than job [j2] and [j1] always has higher + priority than [j2], then [j2] is scheduled only after [j1] is + completed. *) +Section SequentialJLFP. + + (** Consider any type of tasks ... *) + Context {Task : TaskType}. + Context `{TaskCost Task}. + Context `{TaskDeadline Task}. + + (** ... with a bound on the maximum non-preemptive segment length. + The bound is needed to ensure that, at any instant, it always + exists a subsequent preemption time in which the scheduler can, + if needed, switch to another higher-priority job. *) + Context `{TaskMaxNonpreemptiveSegment Task}. + + (** Further, consider any type of jobs associated with these tasks. *) + Context {Job : JobType}. + Context `{JobTask Job Task}. + Context `{Arrival : JobArrival Job}. + Context `{Cost : JobCost Job}. + + (** Consider any arrival sequence. *) + Variable arr_seq : arrival_sequence Job. + + (** Consider a JLFP-policy that indicates a higher-or-equal priority + relation, and assume that this relation is transitive. *) + Context `{JLFP_policy Job}. + Hypothesis H_priority_is_transitive : transitive_priorities. + + (** Next, consider any ideal uni-processor schedule of this arrival sequence, ... *) + Variable sched : schedule (ideal.processor_state Job). + + (** ... allow for any work-bearing notion of job readiness, ... *) + Context `{@JobReady Job (ideal.processor_state Job) _ Cost Arrival}. + Hypothesis H_job_ready : work_bearing_readiness arr_seq sched. + + (** ... and assume that the schedule is valid. *) + Hypothesis H_sched_valid : valid_schedule sched arr_seq. + + (** In addition, we assume the existence of a function mapping jobs + to their preemption points ... *) + Context `{JobPreemptable Job}. + + (** ... and assume that it defines a valid preemption model with + bounded non-preemptive segments. *) + 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 policy defined by + the [job_preemptable] function (i.e., jobs have bounded + non-preemptive segments). *) + Hypothesis H_respects_policy : respects_policy_at_preemption_point arr_seq sched. + + (** We show that, given two jobs [j1] and [j2], if job [j1] arrives + earlier than job [j2] and [j1] always has higher priority than + [j2], then [j2] is scheduled only after [j1] is completed. *) + Lemma early_hep_job_is_scheduled : + forall j1 j2, + arrives_in arr_seq j1 -> + job_arrival j1 < job_arrival j2 -> + always_higher_priority j1 j2 -> + forall t, + scheduled_at sched j2 t -> + completed_by sched j1 t. + Proof. + move=> j1 j2 ARR LE AHP t SCHED; apply/negPn/negP; intros NCOMPL. + move: H_sched_valid => [COARR MBR]. + have ARR_EXEC := jobs_must_arrive_to_be_ready sched MBR. + edestruct scheduling_of_any_segment_starts_with_preemption_time + as [pt [LET [PT ALL_SCHED]]]; try eauto 2. + move: LET => /andP [LE1 LE2]. + specialize (ALL_SCHED pt); feed ALL_SCHED; first by apply/andP; split. + have PEND1: pending sched j1 pt. + { apply/andP; split. + - by rewrite /has_arrived; ssrlia. + - by move: NCOMPL; apply contra, completion_monotonic. + } + apply H_job_ready in PEND1 => //; destruct PEND1 as [j3 [ARR3 [READY3 HEP3]]]. + move: (AHP pt) => /andP[HEP /negP NHEP]; eapply NHEP. + eapply H_priority_is_transitive; last by apply HEP3. + eapply H_respects_policy; eauto 2. + apply/andP; split; first by done. + apply/negP; intros SCHED2. + have EQ := ideal_proc_model_is_a_uniprocessor_model _ _ _ pt SCHED2 ALL_SCHED. + subst j2; rename j3 into j. + by specialize (AHP 0); destruct AHP; auto. + Qed. + +End SequentialJLFP. diff --git a/results/edf/rta/bounded_pi.v b/results/edf/rta/bounded_pi.v index 372157f90..b2690aadf 100644 --- a/results/edf/rta/bounded_pi.v +++ b/results/edf/rta/bounded_pi.v @@ -1,4 +1,4 @@ -Require Export prosa.analysis.facts.edf. +Require Export prosa.analysis.facts.priority.edf. Require Export prosa.analysis.definitions.schedulability. Require Import prosa.model.priority.edf. Require Import prosa.model.task.absolute_deadline. -- GitLab