Commit 3f39fe20 authored by Felipe Cerqueira's avatar Felipe Cerqueira

Major Commit: Suspension-aware Scheduling

1) Definition of a generic model for job suspensions based on
   received service (e.g., job j_1 should suspend for 4ms as
   soon as service reaches 5ms).

2) Definition of the dynamic suspension model (i.e., cumulative
   suspension of job j_1 <= X).

3) Analysis of suspension-aware scheduling by inflation of job
   costs (via schedule reduction). In the literature, this is
   called suspension-oblivious analysis.

4) Analysis of suspension-aware scheduling by adjusting job
   jitter (via schedule reduction).

5) Proof of (weak) sustainability of job costs under suspension-aware
   scheduling. We show that if we increase the costs of all jobs while
   reducing their suspension times in a certain way, the response times
   of all jobs do not decrease.

   This has an important implication regarding worst-case schedules: if
   some schedulability analysis already accounts for the fact that job
   suspension times can vary from 0 to the task suspension bound, then
   it's perfectly safe to assume that jobs execute for their WCET.

6) Proof of sustainability of the cost of a single job under
   suspension-aware scheduling. That is, we show that increasing the
   cost of a single job does not reduce its own response time.
   (Note that this is a very basic result that applies to many
   work-conserving, JLFP schedulers. We don't claim anything about
   the response time of other jobs.)
parent 89a8d7d0
......@@ -255,7 +255,7 @@ Module ResponseTimeIterationFP.
Hypothesis H_valid_task_parameters:
valid_sporadic_taskset task_cost task_period task_deadline ts.
(* Assume any job arrival sequence with consistent, non-duplicate arrivals... *)
(* Assume any job arrival sequence with consistent, duplicate-free arrivals... *)
Variable arr_seq: arrival_sequence Job.
Hypothesis H_arrival_times_are_consistent: arrival_times_are_consistent job_arrival arr_seq.
Hypothesis H_no_duplicate_arrivals: arrival_sequence_is_a_set arr_seq.
......
......@@ -29,7 +29,7 @@ Module ResponseTimeAnalysisFP.
Variable job_deadline: Job -> time.
Variable job_task: Job -> SporadicTask.
(* Assume any job arrival sequence with consistent, non-duplicate arrivals... *)
(* Assume any job arrival sequence with consistent, duplicate-free arrivals... *)
Variable arr_seq: arrival_sequence Job.
Hypothesis H_arrival_times_are_consistent: arrival_times_are_consistent job_arrival arr_seq.
Hypothesis H_no_duplicate_arrivals: arrival_sequence_is_a_set arr_seq.
......
......@@ -160,7 +160,7 @@ Module WorkloadBoundFP.
Hypothesis H_valid_task_parameters:
valid_sporadic_taskset task_cost task_period task_deadline ts.
(* Consider any job arrival sequence with consistent, non-duplicate arrivals. *)
(* Consider any job arrival sequence with consistent, duplicate-free arrivals. *)
Variable arr_seq: arrival_sequence Job.
Hypothesis H_arrival_times_are_consistent: arrival_times_are_consistent job_arrival arr_seq.
Hypothesis H_arr_seq_is_a_set: arrival_sequence_is_a_set arr_seq.
......
......@@ -260,13 +260,13 @@ Module ResponseTimeIterationFP.
Variable job_task: Job -> SporadicTask.
(* Consider a task set ts... *)
Variable ts: taskset_of SporadicTask.
Variable ts: seq SporadicTask.
(* ...where tasks have valid parameters. *)
Hypothesis H_valid_task_parameters:
valid_sporadic_taskset task_cost task_period task_deadline ts.
(* ...with positive task costs and periods. *)
Hypothesis H_positive_costs: forall tsk, tsk \in ts -> task_cost tsk > 0.
Hypothesis H_positive_periods: forall tsk, tsk \in ts -> task_period tsk > 0.
(* Next, consider any job arrival sequence with consistent, non-duplicate arrivals, ... *)
(* Next, consider any job arrival sequence with consistent, duplicate-free arrivals, ... *)
Variable arr_seq: arrival_sequence Job.
Hypothesis H_arrival_times_are_consistent: arrival_times_are_consistent job_arrival arr_seq.
Hypothesis H_arr_seq_is_a_set: arrival_sequence_is_a_set arr_seq.
......@@ -276,18 +276,29 @@ Module ResponseTimeIterationFP.
forall j,
arrives_in arr_seq j ->
job_task j \in ts.
(* ... and satisfy the sporadic task model.*)
Hypothesis H_sporadic_tasks:
sporadic_task_model task_period job_arrival job_task arr_seq.
(* ...have valid parameters,...*)
Hypothesis H_valid_job_parameters:
(* Assume that the cost of each job is bounded by the cost of its task,... *)
Hypothesis H_job_cost_le_task_cost:
forall j,
arrives_in arr_seq j ->
valid_sporadic_job_with_jitter task_cost task_deadline task_jitter
job_cost job_deadline job_jitter job_task j.
job_cost j <= task_cost (job_task j).
(* ... and satisfy the sporadic task model.*)
Hypothesis H_sporadic_tasks:
sporadic_task_model task_period job_arrival job_task arr_seq.
(* ...the jitter of each job is bounded by the jitter of its task,... *)
Hypothesis H_job_jitter_le_task_jitter:
forall j,
arrives_in arr_seq j ->
job_jitter j <= task_jitter (job_task j).
(* ...and that job deadlines equal task deadlines. *)
Hypothesis H_job_deadline_eq_task_deadline:
forall j,
arrives_in arr_seq j ->
job_deadline j = task_deadline (job_task j).
(* Assume any fixed-priority policy... *)
Variable higher_eq_priority: FP_policy SporadicTask.
......@@ -329,26 +340,21 @@ Module ResponseTimeIterationFP.
(tsk, R) \In RTA_claimed_bounds ->
response_time_bounded_by tsk (task_jitter tsk + R).
Proof.
rename H_valid_task_parameters into PARAMS,
H_valid_job_parameters into JOBPARAMS.
unfold valid_sporadic_job, valid_realtime_job,
valid_sporadic_taskset, is_valid_sporadic_task in *.
unfold RTA_claimed_bounds; intros tsk R.
case SOME: fp_claimed_bounds => [rt_bounds|] IN; last by done.
move: (PARAMS) => PARAMStsk.
feed (PARAMStsk tsk);
[by apply fp_claimed_bounds_from_taskset with (tsk0 := tsk) (R0 := R) in SOME | des].
apply uniprocessor_response_time_bound_fp with
(task_cost0 := task_cost) (task_period0 := task_period)
(ts0 := ts) (task_deadline0 := task_deadline)
(job_deadline0 := job_deadline) (job_jitter0 := job_jitter)
(ts0 := ts) (job_jitter0 := job_jitter)
(higher_eq_priority0 := higher_eq_priority); try (by done).
{
apply fp_claimed_bounds_gt_zero with (task_cost0 := task_cost)
(task_period0 := task_period) (task_deadline0 := task_deadline)
(higher_eq_priority0 := higher_eq_priority) (ts0 := ts) (task_jitter0 := task_jitter)
(rt_bounds0 := rt_bounds) (tsk0 := tsk); try (by done).
by intros tsk0 IN0; specialize (PARAMS tsk0 IN0); des.
apply H_positive_costs.
by eapply fp_claimed_bounds_from_taskset; eauto 1.
}
by apply fp_claimed_bounds_yields_fixed_point with
(task_deadline0 := task_deadline) (rt_bounds0 := rt_bounds).
......@@ -370,17 +376,13 @@ Module ResponseTimeIterationFP.
have DL := fp_claimed_bounds_le_deadline task_cost task_period task_deadline
task_jitter higher_eq_priority ts.
have BOUND := fp_analysis_yields_response_time_bounds.
rename H_test_succeeds into TEST, H_valid_job_parameters into JOBPARAMS.
rename H_test_succeeds into TEST.
move:TEST; case TEST:(fp_claimed_bounds _ _ _ _ _) => [rt_bounds|] _//.
intros tsk IN.
move: (RESP rt_bounds TEST tsk IN) => [R INbounds].
specialize (DL rt_bounds TEST tsk R INbounds).
apply task_completes_before_deadline with
(task_deadline0 := task_deadline) (R0 := task_jitter tsk + R); try (by done).
{
intros j ARRj; unfold valid_sporadic_job_with_jitter in *.
by specialize (JOBPARAMS j ARRj); move: JOBPARAMS => [[_ [_ EQ]] _].
}
by apply BOUND; rewrite /RTA_claimed_bounds TEST.
Qed.
......
......@@ -30,34 +30,39 @@ Module ResponseTimeAnalysisFP.
Context {Job: eqType}.
Variable job_arrival: Job -> time.
Variable job_cost: Job -> time.
Variable job_deadline: Job -> time.
Variable job_jitter: Job -> time.
Variable job_task: Job -> SporadicTask.
(* Consider any job arrival sequence with consistent, non-duplicate arrivals... *)
(* Consider any task set ts... *)
Variable ts: seq SporadicTask.
(* ...with positive task periods. *)
Hypothesis H_positive_periods: forall tsk, tsk \in ts -> task_period tsk > 0.
(* Consider any job arrival sequence with consistent, duplicate-free arrivals... *)
Variable arr_seq: arrival_sequence Job.
Hypothesis H_arrival_times_are_consistent: arrival_times_are_consistent job_arrival arr_seq.
Hypothesis H_arr_seq_is_a_set: arrival_sequence_is_a_set arr_seq.
(* ... in which jobs arrive sporadically and have valid parameters. *)
(* ... in which jobs arrive sporadically,... *)
Hypothesis H_sporadic_tasks:
sporadic_task_model task_period job_arrival job_task arr_seq.
Hypothesis H_valid_job_parameters:
(* ...the cost of each job is bounded by the cost of its task, ... *)
Hypothesis H_job_cost_le_task_cost:
forall j,
arrives_in arr_seq j ->
valid_sporadic_job_with_jitter task_cost task_deadline task_jitter
job_cost job_deadline job_jitter job_task j.
job_cost j <= task_cost (job_task j).
(* Consider a task set ts where all tasks have valid parameters... *)
Variable ts: seq SporadicTask.
Hypothesis H_valid_task_parameters:
valid_sporadic_taskset task_cost task_period task_deadline ts.
(* ... and assume that all jobs in the arrival sequence come from the task set. *)
Hypothesis H_all_jobs_from_taskset:
(* ...and the jitter of each job is bounded by the jitter of its task. *)
Hypothesis H_job_jitter_le_task_jitter:
forall j,
arrives_in arr_seq j ->
job_task j \in ts.
job_jitter j <= task_jitter (job_task j).
(* Assume that all jobs in the arrival sequence come from the task set. *)
Hypothesis H_all_jobs_from_taskset:
forall j, arrives_in arr_seq j -> job_task j \in ts.
(* Next, consider any uniprocessor schedule of this arrival sequence... *)
Variable sched: schedule Job.
......@@ -105,15 +110,13 @@ Module ResponseTimeAnalysisFP.
Proof.
unfold valid_sporadic_job_with_jitter, valid_sporadic_job,
valid_sporadic_taskset, is_valid_sporadic_task in *.
rename H_response_time_is_fixed_point into FIX,
H_valid_task_parameters into PARAMS,
H_valid_job_parameters into JOBPARAMS.
rename H_response_time_is_fixed_point into FIX.
intros j IN JOBtsk.
set arr := actual_arrival job_arrival job_jitter.
apply completion_monotonic with (t := arr j + R); try (by done).
{
rewrite -addnA leq_add2l leq_add2r.
by rewrite -JOBtsk; specialize (JOBPARAMS j IN); des.
by rewrite -JOBtsk; apply H_job_jitter_le_task_jitter.
}
set prio := FP_to_JLFP job_task higher_eq_priority.
apply busy_interval_bounds_response_time with (arr_seq0 := arr_seq)
......@@ -122,8 +125,7 @@ Module ResponseTimeAnalysisFP.
- by intros x z y; apply H_priority_is_transitive.
intros t.
apply fp_workload_bound_holds with (task_cost0 := task_cost)
(task_period0 := task_period) (task_deadline0 := task_deadline)
(job_deadline0 := job_deadline) (task_jitter0 := task_jitter) (ts0 := ts); try (by done).
(task_period0 := task_period) (task_jitter0 := task_jitter) (ts0 := ts); try (by done).
by rewrite JOBtsk.
Qed.
......
......@@ -155,22 +155,22 @@ Module WorkloadBoundFP.
Context {Task: eqType}.
Variable task_cost: Task -> time.
Variable task_period: Task -> time.
Variable task_deadline: Task -> time.
Variable task_jitter: Task -> time.
Context {Job: eqType}.
Variable job_arrival: Job -> time.
Variable job_cost: Job -> time.
Variable job_deadline: Job -> time.
Variable job_jitter: Job -> time.
Variable job_task: Job -> Task.
(* Let ts be any task set with valid task parameters. *)
(* Let ts be any task set... *)
Variable ts: seq Task.
Hypothesis H_valid_task_parameters:
valid_sporadic_taskset task_cost task_period task_deadline ts.
(* ...with positive task periods. *)
Hypothesis H_positive_periods:
forall tsk, tsk \in ts -> task_period tsk > 0.
(* Consider any job arrival sequence with consistent, non-duplicate arrivals. *)
(* Consider any job arrival sequence with consistent, duplicate-free arrivals. *)
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.
......@@ -178,18 +178,21 @@ Module WorkloadBoundFP.
(* First, let's define some local names for clarity. *)
Let actual_arrivals := actual_arrivals_between job_arrival job_jitter arr_seq.
(* Next, assume that all jobs come from the task set ...*)
(* Next, assume that all jobs come from the task set, ...*)
Hypothesis H_all_jobs_from_taskset:
forall j, arrives_in arr_seq j -> job_task j \in ts.
(* ...the cost of each job is bounded by the cost of its task, ... *)
Hypothesis H_job_cost_le_task_cost:
forall j,
arrives_in arr_seq j ->
job_task j \in ts.
job_cost j <= task_cost (job_task j).
(* ...and have valid parameters. *)
Hypothesis H_valid_job_parameters:
(* ...and the jitter of each job is bounded by the jitter of its task. *)
Hypothesis H_job_jitter_le_task_jitter:
forall j,
arrives_in arr_seq j ->
valid_sporadic_job_with_jitter task_cost task_deadline task_jitter
job_cost job_deadline job_jitter job_task j.
job_jitter j <= task_jitter (job_task j).
(* Assume that jobs arrived sporadically. *)
Hypothesis H_sporadic_arrivals:
......@@ -221,16 +224,13 @@ Module WorkloadBoundFP.
actual_hp_workload t (t + R) <= R.
Proof.
rename H_fixed_point into FIX, H_all_jobs_from_taskset into FROMTS,
H_valid_job_parameters into JOBPARAMS,
H_valid_task_parameters into PARAMS,
H_arrival_times_are_consistent into CONS, H_arrival_sequence_is_a_set into SET.
unfold actual_hp_workload, workload_of_higher_or_equal_priority_tasks,
valid_sporadic_job_with_jitter, valid_sporadic_job, valid_realtime_job,
valid_sporadic_taskset, is_valid_sporadic_task in *.
have BOUND := sporadic_task_with_jitter_arrival_bound task_period task_jitter job_arrival
job_jitter job_task arr_seq CONS SET.
feed_n 2 BOUND; (try by done);
first by intros j ARRj; specialize (JOBPARAMS j ARRj); des.
feed_n 2 BOUND; (try by done).
intro t.
rewrite {2}FIX /workload_bound /total_workload_bound_fp.
set l := actual_arrivals_between job_arrival job_jitter arr_seq t (t + R).
......@@ -253,16 +253,12 @@ Module WorkloadBoundFP.
{
rewrite /num_actual_arrivals_of_task -sum1_size big_distrl /= big_filter.
apply leq_sum_seq; move => j1 IN1 /eqP EQ.
rewrite -EQ mul1n.
feed (JOBPARAMS j1).
{
rewrite mem_filter in IN1; move: IN1 => /andP [_ ARR1].
by apply in_arrivals_implies_arrived in ARR1.
}
by move: JOBPARAMS => [[_ [LE _]] _].
rewrite -EQ mul1n; apply H_job_cost_le_task_cost.
rewrite mem_filter in IN1; move: IN1 => /andP [_ ARR1].
by apply in_arrivals_implies_arrived in ARR1.
}
rewrite /task_workload_bound_FP leq_mul2r; apply/orP; right.
feed (BOUND t (t + R) tsk0); first by feed (PARAMS tsk0); last by des.
feed (BOUND t (t + R) tsk0); first by apply H_positive_periods.
by rewrite -addnA addKn in BOUND.
Qed.
......
Require Import rt.util.all.
Require Import rt.model.priority rt.model.suspension.
Require Import rt.model.arrival.basic.arrival_sequence.
Require Import rt.model.schedule.uni.jitter.schedule.
Require Import rt.model.schedule.uni.transformation.construction.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq.
(* In this file, we formalize a reduction from a suspension-aware schedule
to a jitter-aware schedule. *)
Module JitterScheduleConstruction.
Import UniprocessorScheduleWithJitter Suspension Priority ScheduleConstruction.
Section ConstructingJitterSchedule.
Context {Task: eqType}.
Context {Job: eqType}.
Variable job_arrival: Job -> time.
Variable job_task: Job -> Task.
(** Basic Setup & Setting*)
(* Consider any job arrival sequence. *)
Variable arr_seq: arrival_sequence Job.
(* Assume any FP policy and the corresponding job-level priority relation. *)
Variable higher_eq_priority: FP_policy Task.
Let job_higher_eq_priority := FP_to_JLFP job_task higher_eq_priority.
(* Consider the original job and task costs from the suspension-aware schedule... *)
Variable job_cost: Job -> time.
Variable task_cost: Task -> time.
(* ...and assume that jobs have associated suspension times. *)
Variable job_suspension_duration: job_suspension Job.
(* Next, consider any suspension-aware schedule of the arrival sequence. *)
Variable sched_susp: schedule Job.
(** Definition of the Reduction *)
(* Now we proceed with the reduction. Let j be the job to be analyzed. *)
Variable j: Job.
(* For simplicity, we give some local names for the parameters of this job... *)
Let arr_j := job_arrival j.
Let task_of_j := job_task j.
(* ...and recall the definition of other higher-or-equal-priority tasks. *)
Let other_hep_task tsk_other :=
higher_eq_priority tsk_other task_of_j && (tsk_other != task_of_j).
(* Moreover, assume that jobs from higher-priority tasks are associated a response-time bound R. *)
Variable R: Job -> time.
(* Now we are going to redefine the job parameters for the new schedule. *)
Section DefiningJobParameters.
(* First, we inflate job costs with suspension time. *)
Section CostInflation.
(* Recall the total suspension time of a job in the original schedule. *)
Let job_total_suspension :=
total_suspension job_cost job_suspension_duration.
(* We inflate job costs as follows.
(a) The cost of job j is inflated with its total suspension time.
(b) The cost of all other jobs remains unchanged. *)
Definition inflated_job_cost (any_j: Job) :=
if any_j == j then
job_cost any_j + job_total_suspension any_j
else
job_cost any_j.
End CostInflation.
(* Next, we show how to set the job jitter in the new schedule
to compensate for the suspension times. *)
Section ConvertingSuspensionToJitter.
(* Let any_j be any job in the new schedule. *)
Variable any_j: Job.
(* First, recall the distance between any_j and job j that is to be analyzed.
Note that since we use natural numbers, this distance saturates to 0 if
any_j arrives later than j. *)
Let distance_to_j := job_arrival j - job_arrival any_j.
(* Then, we define the actual job jitter in the new schedule as follows.
a) For every job of higher-priority tasks (with respect to job j), the jitter is set to
the minimum between the distance to j and the term (R any_j - job_cost any_j).
b) The remaining jobs have no jitter.
The intuition behind this formula is that any_j is to be released as close to job j as
possible, while not "trespassing" the response-time bound (R any_j) from sched_susp,
which is only assumed to be valid for higher-priority tasks. *)
Definition job_jitter :=
if other_hep_task (job_task any_j) then
minn distance_to_j (R any_j - job_cost any_j)
else 0.
End ConvertingSuspensionToJitter.
End DefiningJobParameters.
(** Schedule Construction *)
(* Next we generate a jitter-aware schedule using the job parameters above.
For that, we always pick the highest-priority pending job (after jitter) in
the new schedule. However, if there are multiple highest-priority jobs, we
try not to schedule job j in order to maximize interference. *)
Section ScheduleConstruction.
(* First, we define the schedule construction function. *)
Section ConstructionStep.
(* For any time t, suppose that we have generated the schedule prefix in the
interval [0, t). Then, we must define what should be scheduled at time t. *)
Variable sched_prefix: schedule Job.
Variable t: time.
(* For simplicity, let's define some local names. *)
Let job_is_pending := pending job_arrival inflated_job_cost job_jitter sched_prefix.
Let actual_job_arrivals_up_to := actual_arrivals_up_to job_arrival job_jitter arr_seq.
Let lower_priority j1 j2 := ~~ job_higher_eq_priority j1 j2.
(* Next, consider the list of pending jobs at time t that are different from j
and whose jitter has passed, in the new schedule. *)
Definition pending_jobs_other_than_j :=
[seq j_other <- actual_job_arrivals_up_to t | job_is_pending j_other t & j_other != j].
(* From the list of pending jobs, we can return one of the (possibly many)
highest-priority jobs, or None, in case there are no pending jobs. *)
Definition highest_priority_job_other_than_j :=
seq_min job_higher_eq_priority pending_jobs_other_than_j.
(* Then, we construct the new schedule at time t as follows.
a) If job j is pending and the highest-priority job (other than j) has
lower priority than j, we have to schedule j.
b) Else, if job j is not pending, we pick one of the highest priority pending jobs. *)
Definition build_schedule : option Job :=
if job_is_pending j t then
if highest_priority_job_other_than_j is Some j_hp then
if lower_priority j_hp j then
Some j
else Some j_hp
else Some j
else highest_priority_job_other_than_j.
End ConstructionStep.
(* Finally, starting from the empty schedule, ...*)
Let empty_schedule : schedule Job := fun t => None.
(* ...we use the recursive definition above to construct the jitter-aware schedule. *)
Definition sched_jitter := build_schedule_from_prefixes build_schedule empty_schedule.
End ScheduleConstruction.
End ConstructingJitterSchedule.
End JitterScheduleConstruction.
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
Require Import rt.util.all.
Require Import rt.model.priority rt.model.suspension.
Require Import rt.model.arrival.basic.arrival_sequence.
Require Import rt.model.schedule.uni.jitter.schedule.
Require Import rt.analysis.uni.susp.dynamic.jitter.jitter_schedule.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq.
(* In this file we construct a jitter-aware task set that contains the
jitter-aware schedule generated in the reduction. *)
Module JitterTaskSetGeneration.
Import UniprocessorScheduleWithJitter Suspension Priority
JitterScheduleConstruction.
Section GeneratingTaskset.
Context {Task: eqType}.
(** Analysis Setup *)
(* Let ts be the original, suspension-aware task set. *)
Variable ts: seq Task.
(* Assume that tasks have cost and suspension bound. *)
Variable original_task_cost: Task -> time.
Variable task_suspension_bound: Task -> time.
(* Consider any FP policy that is reflexive, transitive and total, i.e., that
indicates "higher-or-equal priority". *)
Variable higher_eq_priority: FP_policy Task.
(* Let tsk_i be any task to be analyzed... *)
Variable tsk_i: Task.
(* ...and recall the definition of higher-or-equal-priority tasks (other than tsk_i). *)
Let other_hep_task tsk_other := higher_eq_priority tsk_other tsk_i && (tsk_other != tsk_i).
(** Definition of Jitter-Aware Task Parameters *)
(* We are going to define next a jitter-aware task set that models the jitter-aware
schedule that we constructed in the reduction. *)
(* First, using the task suspension bounds, we inflate the cost of the analyzed task
in a suspension-oblivious manner. *)
Definition inflated_task_cost (tsk: Task) :=
if tsk == tsk_i then
original_task_cost tsk + task_suspension_bound tsk
else original_task_cost tsk.
(* Next, assuming that higher-priority tasks have a valid response-time bound R,... *)
Variable R: Task -> time.
(* ...we define the task jitter as follows. *)
Definition task_jitter (tsk: Task) :=
if other_hep_task tsk then
R tsk - original_task_cost tsk
else 0.
End GeneratingTaskset.
End JitterTaskSetGeneration.
\ No newline at end of file
Require Import rt.util.all.
Require Import rt.model.priority rt.model.suspension.
Require Import rt.model.arrival.basic.job rt.model.arrival.basic.task
rt.model.arrival.basic.arrival_sequence rt.model.arrival.basic.task_arrival.
Require Import rt.model.arrival.jitter.job.
Require Import rt.model.schedule.uni.schedulability rt.model.schedule.uni.service
rt.model.schedule.uni.workload
rt.model.schedule.uni.response_time.
Require Import rt.model.schedule.uni.jitter.schedule
rt.model.schedule.uni.jitter.platform.
Require Import rt.model.schedule.uni.susp.suspension_intervals
rt.model.schedule.uni.susp.schedule
rt.model.schedule.uni.susp.valid_schedule
rt.model.schedule.uni.susp.platform.
Require Import rt.analysis.uni.susp.dynamic.jitter.jitter_schedule
rt.analysis.uni.susp.dynamic.jitter.jitter_schedule_properties
rt.analysis.uni.susp.dynamic.jitter.jitter_schedule_service
rt.analysis.uni.susp.dynamic.jitter.jitter_taskset_generation.
From mathcomp Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq fintype bigop.
(* In this file, we determine task response-time bounds in suspension-aware
schedules using a reduction to jitter-aware schedules. *)
Module RTAByReduction.
Import TaskArrival SporadicTaskset Suspension Priority Workload Service Schedulability
UniprocessorScheduleWithJitter ResponseTime SuspensionIntervals ValidSuspensionAwareSchedule.
Module susp_aware := PlatformWithSuspensions.
Module reduction := JitterScheduleConstruction.
Module reduction_prop := JitterScheduleProperties.
Module reduction_serv := JitterScheduleService.
Module ts_gen := JitterTaskSetGeneration.
Section ComparingResponseTimeBounds.
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 *)
(* Let ts be any task set with constrained deadlines. *)
Variable ts: seq Task.
Hypothesis H_constrained_deadlines:
constrained_deadline_model task_period task_deadline ts.
(* Consider any consistent, duplicate-free job arrival sequence... *)
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.
(* ...with sporadic arrivals... *)
Hypothesis H_sporadic_arrivals:
sporadic_task_model task_period job_arrival job_task arr_seq.
(* ...and in which all jobs come from task set ts. *)
Hypothesis H_jobs_from_taskset:
forall j, arrives_in arr_seq j -> job_task j \in ts.
(* Since we consider real-time tasks, assume that job deadlines are equal to task deadlines. *)
Hypothesis H_job_deadlines_equal_task_deadlines:
forall j, arrives_in arr_seq j -> job_deadline j = task_deadline (job_task j).
(* Consider any FP policy that is reflexive, transitive and total.
Note that the policy does not depend on the schedule. *)
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.
(* Assume that jobs and tasks have associated costs... *)
Variable job_cost: Job -> time.
Variable task_cost: Task -> time.
(* ...and suspension times. *)
Variable job_suspension_duration: job_suspension Job.
Variable task_suspension_bound: Task -> time.
(* Assume that jobs have positive cost. *)
Hypothesis H_positive_costs:
forall j, arrives_in arr_seq j -> job_cost j > 0.
(* Next, consider any valid suspension-aware schedule of this arrival sequence.
(Note: see rt.model.schedule.uni.susp.valid_schedule.v for details) *)
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.
(** Analysis Setup *)
(* Now we proceed with the proof. Let tsk be the task to be analyzed. *)
Variable tsk: Task.
Hypothesis H_tsk_in_ts: tsk \in ts.
(* For simplicity, let's define some local names. *)
Let other_hep_task tsk_other :=
higher_eq_priority tsk_other tsk && (tsk_other != tsk).
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.
Let completed_in_sched_susp_by := completed_by job_cost sched_susp.
Let job_misses_no_deadline_in_sched_susp :=
job_misses_no_deadline job_arrival job_cost job_deadline sched_susp.
(* Assume that each task is associated a value R... *)
Variable R: Task -> time.
(* ...that bounds the response-time of all tasks with higher-or-equal priority
(other than tsk) in the suspension-aware schedule sched_susp. *)