aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/edf_common.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2013-01-21 20:00:29 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2013-01-21 20:00:29 -0500
commit95717fa9f4b9f725928e898c42fb0e711e896311 (patch)
tree6c552bd879cdafcd90b6bdacdc167338dd3189bf /litmus/edf_common.c
parent84aa3706d63edda13560ff812740cac0adf744e1 (diff)
Fixed case where blocked tasks are released.
Fixed bug where AUX tasks were being added to the ready queue while those AUX tasks were actually blocked. Bug stems from the fact that the AUX tasks do not make themselves realtime, but another thread does this instead. Also fixed minor bugs elsewhere. NOTE: ONLY FIXES C-EDF. OTHER PLUGINS REMAIN TO BE FIXED.
Diffstat (limited to 'litmus/edf_common.c')
-rw-r--r--litmus/edf_common.c114
1 files changed, 45 insertions, 69 deletions
diff --git a/litmus/edf_common.c b/litmus/edf_common.c
index 441fbfddf0c2..ef22eb93dbf3 100644
--- a/litmus/edf_common.c
+++ b/litmus/edf_common.c
@@ -67,11 +67,14 @@ int edf_higher_prio(struct task_struct* first, struct task_struct* second)
67 return 0; 67 return 0;
68 } 68 }
69 69
70
71 /* check for NULL tasks */ 70 /* check for NULL tasks */
72 if (!first || !second) { 71 if (!first || !second) {
73 return first && !second; 72 return first && !second;
74 } 73 }
74 /* check for non-realtime */
75 if (!is_realtime(first) || !is_realtime(second)) {
76 return is_realtime(first) && !is_realtime(second);
77 }
75 78
76 /* There is some goofy stuff in this code here. There are three subclasses 79 /* There is some goofy stuff in this code here. There are three subclasses
77 * within the SCHED_LITMUS scheduling class: 80 * within the SCHED_LITMUS scheduling class:
@@ -92,49 +95,31 @@ int edf_higher_prio(struct task_struct* first, struct task_struct* second)
92 95
93#if defined(CONFIG_REALTIME_AUX_TASK_PRIORITY_BOOSTED) 96#if defined(CONFIG_REALTIME_AUX_TASK_PRIORITY_BOOSTED)
94 /* run aux tasks at max priority */ 97 /* run aux tasks at max priority */
95 /* TODO: Actually use prio-boosting. */ 98 if (tsk_rt(first)->is_aux_task != tsk_rt(second)->is_aux_task) {
96 if (first->rt_param.is_aux_task != second->rt_param.is_aux_task) 99 return (tsk_rt(first)->is_aux_task > tsk_rt(second)->is_aux_task);
97 {
98 return (first->rt_param.is_aux_task > second->rt_param.is_aux_task);
99 }
100 else if(first->rt_param.is_aux_task && second->rt_param.is_aux_task)
101 {
102 if(first->group_leader == second->group_leader) {
103 TRACE_CUR("aux tie break!\n"); // tie-break by BASE priority of the aux tasks
104 goto aux_tie_break;
105 }
106 first = first->group_leader;
107 second = second->group_leader;
108 } 100 }
109#elif defined(CONFIG_REALTIME_AUX_TASK_PRIORITY_INHERITANCE) 101#elif defined(CONFIG_REALTIME_AUX_TASK_PRIORITY_INHERITANCE)
110 { 102 {
111 int first_lo_aux = first->rt_param.is_aux_task && !first->rt_param.inh_task; 103 int first_lo_aux = tsk_rt(first)->is_aux_task && !tsk_rt(first)->inh_task;
112 int second_lo_aux = second->rt_param.is_aux_task && !second->rt_param.inh_task; 104 int second_lo_aux = tsk_rt(second)->is_aux_task && !tsk_rt(second)->inh_task;
113 105
114 /* prioritize aux tasks without inheritance below real-time tasks */ 106 /* prioritize aux tasks without inheritance below real-time tasks */
115 if (first_lo_aux || second_lo_aux) { 107 if (first_lo_aux || second_lo_aux) {
116 // one of these is an aux task without inheritance. 108 // one of these is an aux task without inheritance.
117 if(first_lo_aux && second_lo_aux) { 109 if (first_lo_aux != second_lo_aux) {
118 TRACE_CUR("aux tie break!\n"); // tie-break by BASE priority of the aux tasks 110 int temp = (first_lo_aux < second_lo_aux); // non-lo-aux has higher priority.
119 goto aux_tie_break;
120 }
121 else {
122
123 // make the aux thread lowest priority real-time task
124 int temp = 0;
125 if (first_lo_aux && is_realtime(second)) {
126// temp = 0;
127 }
128 else if(second_lo_aux && is_realtime(first)) {
129 temp = 1;
130 }
131 TRACE_CUR("%s/%d >> %s/%d --- %d\n", first->comm, first->pid, second->comm, second->pid, temp); 111 TRACE_CUR("%s/%d >> %s/%d --- %d\n", first->comm, first->pid, second->comm, second->pid, temp);
132 return temp; 112 return temp;
133 } 113 }
114 else {
115 /* both MUST be lo_aux. tie-break. */
116 TRACE_CUR("aux tie break!\n");
117 goto aux_tie_break;
118 }
134 } 119 }
135 120
136 if (first->rt_param.is_aux_task && second->rt_param.is_aux_task && 121 if (tsk_rt(first)->is_aux_task && tsk_rt(second)->is_aux_task &&
137 first->rt_param.inh_task == second->rt_param.inh_task) { 122 tsk_rt(first)->inh_task == tsk_rt(second)->inh_task) {
138 // inh_task is !NULL for both tasks since neither was a lo_aux task. 123 // inh_task is !NULL for both tasks since neither was a lo_aux task.
139 // Both aux tasks inherit from the same task, so tie-break 124 // Both aux tasks inherit from the same task, so tie-break
140 // by base priority of the aux tasks. 125 // by base priority of the aux tasks.
@@ -146,33 +131,26 @@ int edf_higher_prio(struct task_struct* first, struct task_struct* second)
146 131
147#ifdef CONFIG_LITMUS_SOFTIRQD 132#ifdef CONFIG_LITMUS_SOFTIRQD
148 { 133 {
149 int first_lo_klmirqd = first->rt_param.is_interrupt_thread && !first->rt_param.inh_task; 134 int first_lo_klmirqd = tsk_rt(first)->is_interrupt_thread && !tsk_rt(first)->inh_task;
150 int second_lo_klmirqd = second->rt_param.is_interrupt_thread && !second->rt_param.inh_task; 135 int second_lo_klmirqd = tsk_rt(second)->is_interrupt_thread && !tsk_rt(second)->inh_task;
151 136
152 /* prioritize aux tasks without inheritance below real-time tasks */ 137 /* prioritize aux tasks without inheritance below real-time tasks */
153 if (first_lo_klmirqd || second_lo_klmirqd) { 138 if (first_lo_klmirqd || second_lo_klmirqd) {
154 // one of these is an klmirqd thread without inheritance. 139 // one of these is an klmirqd thread without inheritance.
155 if(first_lo_klmirqd && second_lo_klmirqd) { 140 if (first_lo_klmirqd != second_lo_klmirqd) {
156 TRACE_CUR("klmirqd tie break!\n"); // tie-break by BASE priority of the aux tasks 141 int temp = (first_lo_klmirqd < second_lo_klmirqd); // non-klmirqd has higher priority
157 goto klmirqd_tie_break;
158 }
159 else {
160 // make the klmirqd thread the lowest-priority real-time task
161 // but (above low-prio aux tasks and Linux tasks)
162 int temp = 0;
163 if (first_lo_klmirqd && is_realtime(second)) {
164// temp = 0;
165 }
166 else if(second_lo_klmirqd && is_realtime(first)) {
167 temp = 1;
168 }
169 TRACE_CUR("%s/%d >> %s/%d --- %d\n", first->comm, first->pid, second->comm, second->pid, temp); 142 TRACE_CUR("%s/%d >> %s/%d --- %d\n", first->comm, first->pid, second->comm, second->pid, temp);
170 return temp; 143 return temp;
171 } 144 }
145 else {
146 /* both MUST be klmirqd. tie-break. */
147 TRACE_CUR("klmirqd tie break!\n");
148 goto klmirqd_tie_break;
149 }
172 } 150 }
173 151
174 if (first->rt_param.is_interrupt_thread && second->rt_param.is_interrupt_thread && 152 if (tsk_rt(first)->is_interrupt_thread && tsk_rt(second)->is_interrupt_thread &&
175 first->rt_param.inh_task == second->rt_param.inh_task) { 153 tsk_rt(first)->inh_task == tsk_rt(second)->inh_task) {
176 // inh_task is !NULL for both tasks since neither was a lo_klmirqd task. 154 // inh_task is !NULL for both tasks since neither was a lo_klmirqd task.
177 // Both klmirqd tasks inherit from the same task, so tie-break 155 // Both klmirqd tasks inherit from the same task, so tie-break
178 // by base priority of the klmirqd tasks. 156 // by base priority of the klmirqd tasks.
@@ -187,19 +165,19 @@ int edf_higher_prio(struct task_struct* first, struct task_struct* second)
187 /* Check for EFFECTIVE priorities. Change task 165 /* Check for EFFECTIVE priorities. Change task
188 * used for comparison in such a case. 166 * used for comparison in such a case.
189 */ 167 */
190 if (unlikely(first->rt_param.inh_task) 168 if (unlikely(tsk_rt(first)->inh_task)
191#ifdef CONFIG_LITMUS_NESTED_LOCKING 169#ifdef CONFIG_LITMUS_NESTED_LOCKING
192 && (first_mode == EFFECTIVE) 170 && (first_mode == EFFECTIVE)
193#endif 171#endif
194 ) { 172 ) {
195 first_task = first->rt_param.inh_task; 173 first_task = tsk_rt(first)->inh_task;
196 } 174 }
197 if (unlikely(second->rt_param.inh_task) 175 if (unlikely(tsk_rt(second)->inh_task)
198#ifdef CONFIG_LITMUS_NESTED_LOCKING 176#ifdef CONFIG_LITMUS_NESTED_LOCKING
199 && (second_mode == EFFECTIVE) 177 && (second_mode == EFFECTIVE)
200#endif 178#endif
201 ) { 179 ) {
202 second_task = second->rt_param.inh_task; 180 second_task = tsk_rt(second)->inh_task;
203 } 181 }
204 182
205 /* Check for priority boosting. Tie-break by start of boosting. 183 /* Check for priority boosting. Tie-break by start of boosting.
@@ -222,17 +200,14 @@ int edf_higher_prio(struct task_struct* first, struct task_struct* second)
222 200
223#endif 201#endif
224 202
225#ifdef CONFIG_REALTIME_AUX_TASKS 203#ifdef CONFIG_REALTIME_AUX_TASK_PRIORITY_INHERITANCE
226aux_tie_break: 204aux_tie_break:
227#endif 205#endif
228#ifdef CONFIG_LITMUS_SOFTIRQD 206#ifdef CONFIG_LITMUS_SOFTIRQD
229klmirqd_tie_break: 207klmirqd_tie_break:
230#endif 208#endif
231 209
232 if (!is_realtime(second_task)) { 210 if (earlier_deadline(first_task, second_task)) {
233 return 1;
234 }
235 else if (earlier_deadline(first_task, second_task)) {
236 return 1; 211 return 1;
237 } 212 }
238 else if (get_deadline(first_task) == get_deadline(second_task)) { 213 else if (get_deadline(first_task) == get_deadline(second_task)) {
@@ -297,10 +272,10 @@ klmirqd_tie_break:
297 } 272 }
298 else if (first_task->pid == second_task->pid) { 273 else if (first_task->pid == second_task->pid) {
299#ifdef CONFIG_LITMUS_SOFTIRQD 274#ifdef CONFIG_LITMUS_SOFTIRQD
300 if (first_task->rt_param.is_interrupt_thread < second_task->rt_param.is_interrupt_thread) { 275 if (tsk_rt(first_task)->is_interrupt_thread < tsk_rt(second_task)->is_interrupt_thread) {
301 return 1; 276 return 1;
302 } 277 }
303 else if (first_task->rt_param.is_interrupt_thread == second_task->rt_param.is_interrupt_thread) { 278 else if (tsk_rt(first_task)->is_interrupt_thread == tsk_rt(second_task)->is_interrupt_thread) {
304#endif 279#endif
305 280
306#if defined(CONFIG_REALTIME_AUX_TASK_PRIORITY_INHERITANCE) 281#if defined(CONFIG_REALTIME_AUX_TASK_PRIORITY_INHERITANCE)
@@ -311,7 +286,7 @@ klmirqd_tie_break:
311#endif 286#endif
312 287
313 /* Something could be wrong if you get this far. */ 288 /* Something could be wrong if you get this far. */
314 if (unlikely(first->rt_param.inh_task == second->rt_param.inh_task)) { 289 if (unlikely(tsk_rt(first)->inh_task == tsk_rt(second)->inh_task)) {
315 /* Both tasks have the same inherited priority. 290 /* Both tasks have the same inherited priority.
316 * Likely in a bug-condition. 291 * Likely in a bug-condition.
317 */ 292 */
@@ -324,22 +299,22 @@ klmirqd_tie_break:
324 } 299 }
325 else { 300 else {
326 /* At least one task must inherit */ 301 /* At least one task must inherit */
327 BUG_ON(!first->rt_param.inh_task && 302 BUG_ON(!tsk_rt(first)->inh_task &&
328 !second->rt_param.inh_task); 303 !tsk_rt(second)->inh_task);
329 304
330 /* The task withOUT the inherited priority wins. */ 305 /* The task withOUT the inherited priority wins. */
331 if (second->rt_param.inh_task) { 306 if (tsk_rt(second)->inh_task) {
332 /* 307 /*
333 * common with aux tasks. 308 * common with aux tasks.
334 TRACE_CUR("unusual comparison: " 309 TRACE_CUR("unusual comparison: "
335 "first = %s/%d first_task = %s/%d " 310 "first = %s/%d first_task = %s/%d "
336 "second = %s/%d second_task = %s/%d\n", 311 "second = %s/%d second_task = %s/%d\n",
337 first->comm, first->pid, 312 first->comm, first->pid,
338 (first->rt_param.inh_task) ? first->rt_param.inh_task->comm : "(nil)", 313 (tsk_rt(first)->inh_task) ? tsk_rt(first)->inh_task->comm : "(nil)",
339 (first->rt_param.inh_task) ? first->rt_param.inh_task->pid : 0, 314 (tsk_rt(first)->inh_task) ? tsk_rt(first)->inh_task->pid : 0,
340 second->comm, second->pid, 315 second->comm, second->pid,
341 (second->rt_param.inh_task) ? second->rt_param.inh_task->comm : "(nil)", 316 (tsk_rt(second)->inh_task) ? tsk_rt(second)->inh_task->comm : "(nil)",
342 (second->rt_param.inh_task) ? second->rt_param.inh_task->pid : 0); 317 (tsk_rt(second)->inh_task) ? tsk_rt(second)->inh_task->pid : 0);
343 */ 318 */
344 return 1; 319 return 1;
345 } 320 }
@@ -426,3 +401,4 @@ int edf_preemption_needed(rt_domain_t* rt, struct task_struct *t)
426 /* make sure to get non-rt stuff out of the way */ 401 /* make sure to get non-rt stuff out of the way */
427 return !is_realtime(t) || edf_higher_prio(__next_ready(rt), t); 402 return !is_realtime(t) || edf_higher_prio(__next_ready(rt), t);
428} 403}
404