diff options
-rw-r--r-- | include/litmus/litmus.h | 2 | ||||
-rw-r--r-- | include/litmus/rt_param.h | 6 | ||||
-rw-r--r-- | litmus/edf_common.c | 24 | ||||
-rw-r--r-- | litmus/jobs.c | 8 |
4 files changed, 32 insertions, 8 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index 338245abd6ed..807b7888695a 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h | |||
@@ -63,7 +63,7 @@ void litmus_exit_task(struct task_struct *tsk); | |||
63 | #define get_exec_time(t) (tsk_rt(t)->job_params.exec_time) | 63 | #define get_exec_time(t) (tsk_rt(t)->job_params.exec_time) |
64 | #define get_deadline(t) (tsk_rt(t)->job_params.deadline) | 64 | #define get_deadline(t) (tsk_rt(t)->job_params.deadline) |
65 | #define get_release(t) (tsk_rt(t)->job_params.release) | 65 | #define get_release(t) (tsk_rt(t)->job_params.release) |
66 | 66 | #define get_lateness(t) (tsk_rt(t)->job_params.lateness) | |
67 | 67 | ||
68 | #define is_hrt(t) \ | 68 | #define is_hrt(t) \ |
69 | (tsk_rt(t)->task_params.cls == RT_CLASS_HARD) | 69 | (tsk_rt(t)->task_params.cls == RT_CLASS_HARD) |
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index 89ac0dda7d3d..fac939dbd33a 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
@@ -110,6 +110,12 @@ struct rt_job { | |||
110 | /* How much service has this job received so far? */ | 110 | /* How much service has this job received so far? */ |
111 | lt_t exec_time; | 111 | lt_t exec_time; |
112 | 112 | ||
113 | /* By how much did the prior job miss its deadline by? | ||
114 | * Value differs from tardiness in that lateness may | ||
115 | * be negative (when job finishes before its deadline). | ||
116 | */ | ||
117 | long long lateness; | ||
118 | |||
113 | /* Which job is this. This is used to let user space | 119 | /* Which job is this. This is used to let user space |
114 | * specify which job to wait for, which is important if jobs | 120 | * specify which job to wait for, which is important if jobs |
115 | * overrun. If we just call sys_sleep_next_period() then we | 121 | * overrun. If we just call sys_sleep_next_period() then we |
diff --git a/litmus/edf_common.c b/litmus/edf_common.c index 668737f0fbf9..54285aaa0405 100644 --- a/litmus/edf_common.c +++ b/litmus/edf_common.c | |||
@@ -78,17 +78,27 @@ int edf_higher_prio(struct task_struct* first, | |||
78 | else if (get_deadline(first_task) == get_deadline(second_task)) { | 78 | else if (get_deadline(first_task) == get_deadline(second_task)) { |
79 | /* Need to tie break */ | 79 | /* Need to tie break */ |
80 | 80 | ||
81 | /* Tie break by pid */ | 81 | /* Tie break by lateness. Jobs with greater lateness get |
82 | if (first_task->pid < second_task->pid) { | 82 | * priority. This should spread tardiness across all tasks, |
83 | * especially in task sets where all tasks have the same | ||
84 | * period and relative deadlines. | ||
85 | */ | ||
86 | if (get_lateness(first_task) > get_lateness(second_task)) { | ||
83 | return 1; | 87 | return 1; |
84 | } | 88 | } |
85 | else if (first_task->pid == second_task->pid) { | 89 | else if(get_lateness(first_task) == get_lateness(second_task)) { |
86 | /* If the PIDs are the same then the task with the | 90 | /* Tie break by pid */ |
87 | * inherited priority wins. | 91 | if (first_task->pid < second_task->pid) { |
88 | */ | ||
89 | if (!second_task->rt_param.inh_task) { | ||
90 | return 1; | 92 | return 1; |
91 | } | 93 | } |
94 | else if (first_task->pid == second_task->pid) { | ||
95 | /* If the PIDs are the same then the task with the | ||
96 | * inherited priority wins. | ||
97 | */ | ||
98 | if (!second_task->rt_param.inh_task) { | ||
99 | return 1; | ||
100 | } | ||
101 | } | ||
92 | } | 102 | } |
93 | } | 103 | } |
94 | return 0; /* fall-through. prio(second_task) > prio(first_task) */ | 104 | return 0; /* fall-through. prio(second_task) > prio(first_task) */ |
diff --git a/litmus/jobs.c b/litmus/jobs.c index bc8246572e54..fb093c03d53d 100644 --- a/litmus/jobs.c +++ b/litmus/jobs.c | |||
@@ -23,6 +23,14 @@ static inline void setup_release(struct task_struct *t, lt_t release) | |||
23 | void prepare_for_next_period(struct task_struct *t) | 23 | void prepare_for_next_period(struct task_struct *t) |
24 | { | 24 | { |
25 | BUG_ON(!t); | 25 | BUG_ON(!t); |
26 | |||
27 | /* Record lateness before we set up the next job's | ||
28 | * release and deadline. Lateness may be negative. | ||
29 | */ | ||
30 | t->rt_param.job_params.lateness = | ||
31 | (long long)litmus_clock() - | ||
32 | (long long)t->rt_param.job_params.deadline; | ||
33 | |||
26 | setup_release(t, get_release(t) + get_rt_period(t)); | 34 | setup_release(t, get_release(t) + get_rt_period(t)); |
27 | } | 35 | } |
28 | 36 | ||