Commit 30f8c1b5 authored by Felipe Cerqueira's avatar Felipe Cerqueira

Simplify work-conserving and implement concrete scheduler

- Now we have two definitions of work conserving, a simple version
  and another one based on count, along with a proof of equivalence.

- Implemented a concrete scheduler (basic and jitter)
parent 8ed0149e
......@@ -14,7 +14,7 @@
#
# This Makefile was generated by the command line :
# coq_makefile -R . rt ./util/ssromega.v ./util/lemmas.v ./util/Vbase.v ./util/divround.v ./analysis/basic/bertogna_fp_theory.v ./analysis/basic/bertogna_edf_comp.v ./analysis/basic/bertogna_fp_comp.v ./analysis/basic/bertogna_edf_theory.v ./analysis/jitter/bertogna_fp_theory.v ./analysis/jitter/bertogna_edf_comp.v ./analysis/jitter/bertogna_fp_comp.v ./analysis/jitter/bertogna_edf_theory.v ./model/basic/schedulability.v ./model/basic/interference_bound_edf.v ./model/basic/task.v ./model/basic/interference_bound_fp.v ./model/basic/task_arrival.v ./model/basic/interference_bound.v ./model/basic/platform.v ./model/basic/schedule.v ./model/basic/priority.v ./model/basic/interference_edf.v ./model/basic/interference.v ./model/basic/workload.v ./model/basic/job.v ./model/basic/arrival_sequence.v ./model/basic/response_time.v ./model/basic/platform_fp.v ./model/basic/workload_bound.v ./model/jitter/schedulability.v ./model/jitter/interference_bound_edf.v ./model/jitter/task.v ./model/jitter/interference_bound_fp.v ./model/jitter/task_arrival.v ./model/jitter/interference_bound.v ./model/jitter/platform.v ./model/jitter/schedule.v ./model/jitter/priority.v ./model/jitter/interference_edf.v ./model/jitter/interference.v ./model/jitter/workload.v ./model/jitter/job.v ./model/jitter/arrival_sequence.v ./model/jitter/response_time.v ./model/jitter/platform_fp.v ./model/jitter/workload_bound.v -o Makefile
# coq_makefile -R . rt ./util/ssromega.v ./util/lemmas.v ./util/Vbase.v ./util/divround.v ./implementation/basic/schedule.v ./implementation/jitter/schedule.v ./analysis/basic/bertogna_fp_theory.v ./analysis/basic/bertogna_edf_comp.v ./analysis/basic/bertogna_fp_comp.v ./analysis/basic/bertogna_edf_theory.v ./analysis/jitter/bertogna_fp_theory.v ./analysis/jitter/bertogna_edf_comp.v ./analysis/jitter/bertogna_fp_comp.v ./analysis/jitter/bertogna_edf_theory.v ./model/basic/schedulability.v ./model/basic/interference_bound_edf.v ./model/basic/task.v ./model/basic/interference_bound_fp.v ./model/basic/task_arrival.v ./model/basic/interference_bound.v ./model/basic/platform.v ./model/basic/schedule.v ./model/basic/priority.v ./model/basic/interference_edf.v ./model/basic/interference.v ./model/basic/workload.v ./model/basic/job.v ./model/basic/arrival_sequence.v ./model/basic/response_time.v ./model/basic/platform_fp.v ./model/basic/workload_bound.v ./model/jitter/schedulability.v ./model/jitter/interference_bound_edf.v ./model/jitter/task.v ./model/jitter/interference_bound_fp.v ./model/jitter/task_arrival.v ./model/jitter/interference_bound.v ./model/jitter/platform.v ./model/jitter/schedule.v ./model/jitter/priority.v ./model/jitter/interference_edf.v ./model/jitter/interference.v ./model/jitter/workload.v ./model/jitter/job.v ./model/jitter/arrival_sequence.v ./model/jitter/response_time.v ./model/jitter/platform_fp.v ./model/jitter/workload_bound.v -o Makefile
#
.DEFAULT_GOAL := all
......@@ -84,6 +84,8 @@ VFILES:=util/ssromega.v\
util/lemmas.v\
util/Vbase.v\
util/divround.v\
implementation/basic/schedule.v\
implementation/jitter/schedule.v\
analysis/basic/bertogna_fp_theory.v\
analysis/basic/bertogna_edf_comp.v\
analysis/basic/bertogna_fp_comp.v\
......
This diff is collapsed.
This diff is collapsed.
......@@ -32,6 +32,14 @@ Module Platform.
(* A scheduler is work-conserving iff when a job j is backlogged,
all processors are busy with other jobs. *)
Definition work_conserving :=
forall (j: JobIn arr_seq) t,
backlogged job_cost sched j t ->
forall cpu, exists j_other,
scheduled_on sched j_other cpu t.
(* We also provide an alternative, equivalent definition of work-conserving
based on counting the number of scheduled jobs. *)
Definition work_conserving_count :=
forall (j: JobIn arr_seq) t,
backlogged job_cost sched j t ->
size (jobs_scheduled_at sched t) = num_cpus.
......@@ -73,6 +81,83 @@ Module Platform.
forall (j: JobIn arr_seq),
valid_sporadic_job task_cost task_deadline job_cost job_deadline job_task j.
(* In this section, we prove that the two definitions of work-conserving are equivalent. *)
Section EquivalentDefinitions.
Lemma work_conserving_eq_work_conserving_count :
work_conserving <-> work_conserving_count.
Proof.
unfold work_conserving, work_conserving_count; split.
{
intros EX j t BACK.
specialize (EX j t BACK).
apply eq_trans with (y := size (enum (processor num_cpus)));
last by rewrite size_enum_ord.
unfold jobs_scheduled_at.
apply eq_trans with (y := size ((\cat_(cpu < num_cpus) map (fun x => Some x)
(make_sequence (sched cpu t)))));
first by rewrite -map_bigcat_ord size_map.
apply eq_trans with (y := size (\cat_(cpu < num_cpus) [:: sched cpu t])).
{
f_equal; apply eq_bigr; intros cpu _.
destruct (sched cpu t) eqn:SCHED; first by done.
by specialize (EX cpu); des; move: EX => /eqP EX; rewrite EX in SCHED.
}
rewrite size_bigcat_ord.
apply eq_trans with (y := \sum_(i < num_cpus) 1);
last by rewrite big_const_ord iter_addn mul1n addn0 size_enum_ord.
by apply eq_bigr.
}
{
intros SIZE j t BACK cpu.
specialize (SIZE j t BACK).
destruct ([exists cpu, sched cpu t == None]) eqn:EX; last first.
{
apply negbT in EX; rewrite negb_exists in EX.
move: EX => /forallP ALL; specialize (ALL cpu).
destruct (sched cpu t) eqn:SOME; last by done.
by exists j0; apply/eqP.
}
{
move: EX => /existsP [cpu' /eqP EX].
unfold jobs_scheduled_at in SIZE.
move: SIZE => /eqP SIZE; rewrite -[size _ == _]negbK in SIZE.
move: SIZE => /negP SIZE; exfalso; apply SIZE; clear SIZE.
rewrite neq_ltn; apply/orP; left.
rewrite size_bigcat_ord.
rewrite -> big_mkord_ord with (x0 := 0).
have MKORD := big_mkord (fun x => true); rewrite -MKORD.
have CAT := big_cat_nat _ (fun x => true).
rewrite -> CAT with (n := cpu'); [simpl | by done | by apply ltnW, ltn_ord].
assert (DIFF: exists k, num_cpus = (cpu' + k).+1).
{
exists (num_cpus - cpu').-1.
rewrite -addnS prednK; last by rewrite ltn_subRL addn0 ltn_ord.
rewrite addnBA; last by apply ltnW, ltn_ord.
by rewrite addnC -addnBA // subnn addn0.
}
des; rewrite {5}DIFF.
rewrite big_nat_recl; last by apply leq_addr.
apply leq_trans with (n := (\sum_(0 <= i < cpu') 1) + 1 + (\sum_(cpu' <= i < cpu' + k) 1));
last first.
{
rewrite 2!big_const_nat 2!iter_addn 2!mul1n addn0 subn0.
rewrite [cpu' + k]addnC -addnBA // subnn 2!addn0.
by rewrite -addnA [1 + k]addnC addnA addn1 -DIFF.
}
{
rewrite -addn1 addnC [_ + 1]addnC -addnA.
apply leq_add; first by done.
rewrite eq_fun_ord_to_nat; unfold make_sequence at 2; rewrite EX /= add0n.
apply leq_add; apply leq_sum; ins; unfold fun_ord_to_nat; des_eqrefl2; try done;
by unfold make_sequence; desf.
}
}
}
Qed.
End EquivalentDefinitions.
Section JobInvariantAsTaskInvariant.
(* Assume any work-conserving priority-based scheduler. *)
......@@ -174,6 +259,7 @@ Module Platform.
H_all_previous_jobs_completed into PREV,
H_completed_jobs_dont_execute into COMP,
H_jobs_must_arrive_to_execute into ARRIVE.
apply work_conserving_eq_work_conserving_count in WORK.
unfold valid_sporadic_job, valid_realtime_job,
enforces_JLDP_policy,
task_precedence_constraints, completed_jobs_dont_execute,
......
......@@ -189,6 +189,7 @@ Module PlatformFP.
H_completed_jobs_dont_execute into COMP,
H_all_previous_jobs_of_tsk_completed into PREVtsk,
H_jobs_must_arrive_to_execute into ARRIVE.
apply work_conserving_eq_work_conserving_count in WORK.
unfold valid_sporadic_job, valid_realtime_job,
enforces_FP_policy, enforces_JLDP_policy, FP_to_JLDP,
task_precedence_constraints, completed_jobs_dont_execute,
......
......@@ -43,6 +43,10 @@ Module Schedule.
Variable sched: schedule num_cpus arr_seq.
Variable j: JobIn arr_seq.
(* A job j is scheduled on processor cpu at time t iff such a mapping exists. *)
Definition scheduled_on (cpu: processor num_cpus) (t: time) :=
sched cpu t == Some j.
(* A job j is scheduled at time t iff there exists a cpu where it is mapped.*)
Definition scheduled (t: time) :=
[exists cpu in 'I_(num_cpus), sched cpu t == Some j].
......@@ -507,7 +511,8 @@ Module Schedule.
intros t.
unfold jobs_scheduled_at.
destruct num_cpus; first by rewrite big_ord0.
apply size_bigcat_ord; first by apply (Ordinal (ltnSn n)).
apply leq_trans with (1*n.+1); last by rewrite mul1n.
apply size_bigcat_ord_max.
by ins; unfold make_sequence; desf.
Qed.
......
......@@ -32,12 +32,20 @@ Module Platform.
(* A scheduler is work-conserving iff when a job j is backlogged,
all processors are busy with other jobs.
NOTE: backlogged means that jitter has passed. *)
NOTE: backlogged means that jitter has already passed. *)
Definition work_conserving :=
forall (j: JobIn arr_seq) t,
backlogged job_cost job_jitter sched j t ->
forall cpu, exists j_other,
scheduled_on sched j_other cpu t.
(* We also provide an alternative, equivalent definition of work-conserving
based on counting the number of scheduled jobs. *)
Definition work_conserving_count :=
forall (j: JobIn arr_seq) t,
backlogged job_cost job_jitter sched j t ->
size (jobs_scheduled_at sched t) = num_cpus.
End WorkConserving.
Section JLDP.
......@@ -75,6 +83,83 @@ Module Platform.
forall (j: JobIn arr_seq),
valid_sporadic_job task_cost task_deadline job_cost job_deadline job_task j.
(* In this section, we prove that the two definitions of work-conserving are equivalent. *)
Section EquivalentDefinitions.
Lemma work_conserving_eq_work_conserving_count :
work_conserving <-> work_conserving_count.
Proof.
unfold work_conserving, work_conserving_count; split.
{
intros EX j t BACK.
specialize (EX j t BACK).
apply eq_trans with (y := size (enum (processor num_cpus)));
last by rewrite size_enum_ord.
unfold jobs_scheduled_at.
apply eq_trans with (y := size ((\cat_(cpu < num_cpus) map (fun x => Some x)
(make_sequence (sched cpu t)))));
first by rewrite -map_bigcat_ord size_map.
apply eq_trans with (y := size (\cat_(cpu < num_cpus) [:: sched cpu t])).
{
f_equal; apply eq_bigr; intros cpu _.
destruct (sched cpu t) eqn:SCHED; first by done.
by specialize (EX cpu); des; move: EX => /eqP EX; rewrite EX in SCHED.
}
rewrite size_bigcat_ord.
apply eq_trans with (y := \sum_(i < num_cpus) 1);
last by rewrite big_const_ord iter_addn mul1n addn0 size_enum_ord.
by apply eq_bigr.
}
{
intros SIZE j t BACK cpu.
specialize (SIZE j t BACK).
destruct ([exists cpu, sched cpu t == None]) eqn:EX; last first.
{
apply negbT in EX; rewrite negb_exists in EX.
move: EX => /forallP ALL; specialize (ALL cpu).
destruct (sched cpu t) eqn:SOME; last by done.
by exists j0; apply/eqP.
}
{
move: EX => /existsP [cpu' /eqP EX].
unfold jobs_scheduled_at in SIZE.
move: SIZE => /eqP SIZE; rewrite -[size _ == _]negbK in SIZE.
move: SIZE => /negP SIZE; exfalso; apply SIZE; clear SIZE.
rewrite neq_ltn; apply/orP; left.
rewrite size_bigcat_ord.
rewrite -> big_mkord_ord with (x0 := 0).
have MKORD := big_mkord (fun x => true); rewrite -MKORD.
have CAT := big_cat_nat _ (fun x => true).
rewrite -> CAT with (n := cpu'); [simpl | by done | by apply ltnW, ltn_ord].
assert (DIFF: exists k, num_cpus = (cpu' + k).+1).
{
exists (num_cpus - cpu').-1.
rewrite -addnS prednK; last by rewrite ltn_subRL addn0 ltn_ord.
rewrite addnBA; last by apply ltnW, ltn_ord.
by rewrite addnC -addnBA // subnn addn0.
}
des; rewrite {5}DIFF.
rewrite big_nat_recl; last by apply leq_addr.
apply leq_trans with (n := (\sum_(0 <= i < cpu') 1) + 1 + (\sum_(cpu' <= i < cpu' + k) 1));
last first.
{
rewrite 2!big_const_nat 2!iter_addn 2!mul1n addn0 subn0.
rewrite [cpu' + k]addnC -addnBA // subnn 2!addn0.
by rewrite -addnA [1 + k]addnC addnA addn1 -DIFF.
}
{
rewrite -addn1 addnC [_ + 1]addnC -addnA.
apply leq_add; first by done.
rewrite eq_fun_ord_to_nat; unfold make_sequence at 2; rewrite EX /= add0n.
apply leq_add; apply leq_sum; ins; unfold fun_ord_to_nat; des_eqrefl2; try done;
by unfold make_sequence; desf.
}
}
}
Qed.
End EquivalentDefinitions.
Section JobInvariantAsTaskInvariant.
(* Assume any work-conserving priority-based scheduler. *)
......@@ -181,6 +266,7 @@ Module Platform.
H_all_previous_jobs_completed into PREV,
H_completed_jobs_dont_execute into COMP,
H_jobs_execute_after_jitter into JITTER.
apply work_conserving_eq_work_conserving_count in WORK.
unfold valid_sporadic_job, valid_realtime_job,
enforces_JLDP_policy,
task_precedence_constraints, completed_jobs_dont_execute,
......
......@@ -200,6 +200,7 @@ Module PlatformFP.
H_completed_jobs_dont_execute into COMP,
H_all_previous_jobs_of_tsk_completed into PREVtsk,
H_jobs_execute_after_jitter into JITTER.
apply work_conserving_eq_work_conserving_count in WORK.
unfold valid_sporadic_job, valid_realtime_job,
enforces_FP_policy, enforces_JLDP_policy, FP_to_JLDP,
task_precedence_constraints, completed_jobs_dont_execute,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment