aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/edf_common.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-09-10 13:30:24 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2012-09-10 13:30:24 -0400
commit893c8943ce5c5527f05ab7e9208d5a942d77d8b5 (patch)
treeaa9e84b3503ff97c1d87bc9c2ce6682e51cfc971 /litmus/edf_common.c
parent901fdd9c22790039a76c1d3ee01828a2f124f6f3 (diff)
parentd3c32e91e3fce2a57083a734efae6d9de06ec02f (diff)
Merge branch 'prop/robust-tie-break' into wip-gpu-rtas12
Conflicts: include/litmus/binheap.h include/litmus/fdso.h include/litmus/litmus.h litmus/Makefile litmus/binheap.c litmus/edf_common.c litmus/fdso.c litmus/jobs.c litmus/locking.c
Diffstat (limited to 'litmus/edf_common.c')
-rw-r--r--litmus/edf_common.c132
1 files changed, 94 insertions, 38 deletions
diff --git a/litmus/edf_common.c b/litmus/edf_common.c
index b346bdd65b3b..a1cdc10ea6f1 100644
--- a/litmus/edf_common.c
+++ b/litmus/edf_common.c
@@ -18,6 +18,30 @@
18 18
19#include <litmus/edf_common.h> 19#include <litmus/edf_common.h>
20 20
21#ifdef CONFIG_EDF_TIE_BREAK_LATENESS_NORM
22#include <litmus/fpmath.h>
23#endif
24
25#ifdef CONFIG_EDF_TIE_BREAK_HASH
26#include <linux/hash.h>
27static inline long edf_hash(struct task_struct *t)
28{
29 /* pid is 32 bits, so normally we would shove that into the
30 * upper 32-bits and and put the job number in the bottom
31 * and hash the 64-bit number with hash_64(). Sadly,
32 * in testing, hash_64() doesn't distribute keys were the
33 * upper bits are close together (as would be the case with
34 * pids) and job numbers are equal (as would be the case with
35 * synchronous task sets with all relative deadlines equal).
36 *
37 * A 2006 Linux patch proposed the following solution
38 * (but for some reason it wasn't accepted...).
39 *
40 * At least this workaround works for 32-bit systems as well.
41 */
42 return hash_32(hash_32((u32)tsk_rt(t)->job_params.job_no, 32) ^ t->pid, 32);
43}
44#endif
21 45
22 46
23/* edf_higher_prio - returns true if first has a higher EDF priority 47/* edf_higher_prio - returns true if first has a higher EDF priority
@@ -88,58 +112,90 @@ int edf_higher_prio(struct task_struct* first, struct task_struct* second)
88 112
89#endif 113#endif
90 114
91// // rate-monotonic for testing
92// if (!is_realtime(second_task)) {
93// return true;
94// }
95//
96// if (shorter_period(first_task, second_task)) {
97// return true;
98// }
99//
100// if (get_period(first_task) == get_period(second_task)) {
101// if (first_task->pid < second_task->pid) {
102// return true;
103// }
104// else if (first_task->pid == second_task->pid) {
105// return !second->rt_param.inh_task;
106// }
107// }
108
109 if (!is_realtime(second_task)) { 115 if (!is_realtime(second_task)) {
110 return true; 116 return 1;
111 } 117 }
112 118 else if (earlier_deadline(first_task, second_task)) {
113 if (earlier_deadline(first_task, second_task)) { 119 return 1;
114 return true;
115 } 120 }
116 if (get_deadline(first_task) == get_deadline(second_task)) { 121 else if (get_deadline(first_task) == get_deadline(second_task)) {
117 122 /* Need to tie break. All methods must set pid_break to 0/1 if
118 if (shorter_period(first_task, second_task)) { 123 * first_task does not have priority over second_task.
119 return true; 124 */
125 int pid_break;
126
127#if defined(CONFIG_EDF_TIE_BREAK_LATENESS)
128 /* Tie break by lateness. Jobs with greater lateness get
129 * priority. This should spread tardiness across all tasks,
130 * especially in task sets where all tasks have the same
131 * period and relative deadlines.
132 */
133 if (get_lateness(first_task) > get_lateness(second_task)) {
134 return 1;
135 }
136 pid_break = (get_lateness(first_task) == get_lateness(second_task));
137
138
139#elif defined(CONFIG_EDF_TIE_BREAK_LATENESS_NORM)
140 /* Tie break by lateness, normalized by relative deadline. Jobs with
141 * greater normalized lateness get priority.
142 *
143 * Note: Considered using the algebraically equivalent
144 * lateness(first)*relative_deadline(second) >
145 lateness(second)*relative_deadline(first)
146 * to avoid fixed-point math, but values are prone to overflow if inputs
147 * are on the order of several seconds, even in 64-bit.
148 */
149 fp_t fnorm = _frac(get_lateness(first_task),
150 get_rt_relative_deadline(first_task));
151 fp_t snorm = _frac(get_lateness(second_task),
152 get_rt_relative_deadline(second_task));
153 if (_gt(fnorm, snorm)) {
154 return 1;
155 }
156 pid_break = _eq(fnorm, snorm);
157
158
159#elif defined(CONFIG_EDF_TIE_BREAK_HASH)
160 /* Tie break by comparing hashs of (pid, job#) tuple. There should be
161 * a 50% chance that first_task has a higher priority than second_task.
162 */
163 long fhash = edf_hash(first_task);
164 long shash = edf_hash(second_task);
165 if (fhash < shash) {
166 return 1;
120 } 167 }
121 if (get_rt_period(first_task) == get_rt_period(second_task)) { 168 pid_break = (fhash == shash);
169#else
170
171
172 /* CONFIG_EDF_PID_TIE_BREAK */
173 pid_break = 1; // fall through to tie-break by pid;
174#endif
175
176 /* Tie break by pid */
177 if(pid_break) {
122 if (first_task->pid < second_task->pid) { 178 if (first_task->pid < second_task->pid) {
123 return true; 179 return 1;
124 } 180 }
125 if (first_task->pid == second_task->pid) { 181 else if (first_task->pid == second_task->pid) {
126#ifdef CONFIG_LITMUS_SOFTIRQD 182#ifdef CONFIG_LITMUS_SOFTIRQD
127 if (first_task->rt_param.is_proxy_thread < 183 if (first_task->rt_param.is_proxy_thread <
128 second_task->rt_param.is_proxy_thread) { 184 second_task->rt_param.is_proxy_thread) {
129 return true; 185 return 1;
130 }
131 if(first_task->rt_param.is_proxy_thread == second_task->rt_param.is_proxy_thread) {
132 return !second->rt_param.inh_task;
133 } 186 }
134#else
135 return !second->rt_param.inh_task;
136#endif 187#endif
188 /* If the PIDs are the same then the task with the
189 * inherited priority wins.
190 */
191 if (!second_task->rt_param.inh_task) {
192 return 1;
193 }
137 } 194 }
138
139 } 195 }
140 } 196 }
141 197
142 return false; 198 return 0; /* fall-through. prio(second_task) > prio(first_task) */
143} 199}
144 200
145 201