aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2007-04-25 15:23:39 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2007-04-25 15:23:39 -0400
commit50e4938993cbb7ce43566c18d7d6616b2b8c61d6 (patch)
treef92a3da242cd4fa709835252fcaa23a18d782152 /kernel
parent3695e6b8dd1eeb288419674df951a35dd69ade52 (diff)
Fixed GSN-EDF job_arrival() function.
Now the correct job is linked in case that a linked job lowers its priority. This could happen if a tardy job's successor is immediately released in the scheduler_tick() function. The preemption_needed() function was made more robust to handle NULL pointers correctly (needed for GSN-EDF).
Diffstat (limited to 'kernel')
-rw-r--r--kernel/edf_common.c35
-rw-r--r--kernel/sched_gsn_edf.c15
2 files changed, 32 insertions, 18 deletions
diff --git a/kernel/edf_common.c b/kernel/edf_common.c
index 6a232a8f01..9aa4f39d1e 100644
--- a/kernel/edf_common.c
+++ b/kernel/edf_common.c
@@ -82,17 +82,23 @@ void __add_ready(edf_domain_t* edf, struct task_struct *new)
82 82
83struct task_struct* __take_ready(edf_domain_t* edf) 83struct task_struct* __take_ready(edf_domain_t* edf)
84{ 84{
85 struct task_struct *t = __peek_ready(edf);
86
87 /* kick it out of the ready list */
88 if (t)
89 list_del(&t->rt_list);
90 return t;
91}
92
93
94struct task_struct* __peek_ready(edf_domain_t* edf)
95{
85 struct task_struct *t = NULL; 96 struct task_struct *t = NULL;
86 /* either not yet released, preempted, or non-rt */ 97 /* either not yet released, preempted, or non-rt */
87 if (!list_empty(&edf->ready_queue)) { 98 if (!list_empty(&edf->ready_queue))
88
89 /* take next rt task */ 99 /* take next rt task */
90 t = list_entry(edf->ready_queue.next, struct task_struct, 100 t = list_entry(edf->ready_queue.next, struct task_struct,
91 rt_list); 101 rt_list);
92
93 /* kick it out of the ready list */
94 list_del(&t->rt_list);
95 }
96 return t; 102 return t;
97} 103}
98 104
@@ -225,13 +231,16 @@ void __prepare_new_releases(edf_domain_t *edf, jiffie_t start)
225int preemption_needed(edf_domain_t* edf, struct task_struct *t) 231int preemption_needed(edf_domain_t* edf, struct task_struct *t)
226{ 232{
227 /* we need the read lock for edf_ready_queue */ 233 /* we need the read lock for edf_ready_queue */
228 if (!list_empty(&edf->ready_queue) || is_np(t)) 234 /* no need to preempt if there is nothing pending */
229 { 235 if (list_empty(&edf->ready_queue))
230 if (is_realtime(t)) 236 return 0;
231 return edf_higher_prio(next_ready(edf), t); 237 /* we need to reschedule if t doesn't exist */
232 else 238 if (!t)
233 return 1; 239 return 1;
234 } 240 /* don't preempt if t is non-preemptable */
241 if (!is_np(t))
242 /* make sure to get non-rt stuff out of the way */
243 return !is_realtime(t) || edf_higher_prio(next_ready(edf), t);
235 return 0; 244 return 0;
236} 245}
237 246
diff --git a/kernel/sched_gsn_edf.c b/kernel/sched_gsn_edf.c
index dcf976930c..54f3ddc539 100644
--- a/kernel/sched_gsn_edf.c
+++ b/kernel/sched_gsn_edf.c
@@ -196,16 +196,21 @@ static noinline void gsnedf_job_arrival(struct task_struct* task)
196 196
197 BUG_ON(list_empty(&gsnedf_cpu_queue)); 197 BUG_ON(list_empty(&gsnedf_cpu_queue));
198 BUG_ON(!task); 198 BUG_ON(!task);
199 last = list_entry(gsnedf_cpu_queue.prev, cpu_entry_t, list);
200 199
201 if (is_released(task) && edf_higher_prio(task, last->linked)) { 200 /* first queue arriving job */
202 TRACE("arriving task %d linked to %d\n", task->pid, last->cpu); 201 requeue(task);
202
203 /* then check for any necessary preemptions */
204 last = list_entry(gsnedf_cpu_queue.prev, cpu_entry_t, list);
205 if (preemption_needed(&gsnedf, last->linked)) {
206 /* preemption necessary */
207 task = __take_ready(&gsnedf);
208 TRACE("job_arrival: task %d linked to %d\n", task->pid, last->cpu);
203 if (last->linked) 209 if (last->linked)
204 requeue(last->linked); 210 requeue(last->linked);
205 link_task_to_cpu(task, last); 211 link_task_to_cpu(task, last);
206 preempt(last); 212 preempt(last);
207 } else 213 }
208 requeue(task);
209} 214}
210 215
211/* check for current job releases */ 216/* check for current job releases */