diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-05-11 18:33:45 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2008-05-11 18:33:45 -0400 |
commit | 72d790931b605257f4be4d1b7240981711ab3717 (patch) | |
tree | 81449d47b3c54825894ca00b0f5d929986d85378 | |
parent | 1b0b2b02697583bbe3aa6060e3f28d0a75c66ab6 (diff) |
GSN/PSN: improve locking
-rw-r--r-- | litmus/rt_domain.c | 1 | ||||
-rw-r--r-- | litmus/sched_gsn_edf.c | 20 | ||||
-rw-r--r-- | litmus/sched_psn_edf.c | 18 |
3 files changed, 25 insertions, 14 deletions
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c index 1088e6fed8..0134947ee6 100644 --- a/litmus/rt_domain.c +++ b/litmus/rt_domain.c | |||
@@ -141,6 +141,7 @@ struct task_struct* __peek_ready(rt_domain_t* rt) | |||
141 | */ | 141 | */ |
142 | void __add_release(rt_domain_t* rt, struct task_struct *task) | 142 | void __add_release(rt_domain_t* rt, struct task_struct *task) |
143 | { | 143 | { |
144 | TRACE_TASK(task, "add_release(), rel=%llu\n", get_release(task)); | ||
144 | list_add(&task->rt_list, &rt->release_queue); | 145 | list_add(&task->rt_list, &rt->release_queue); |
145 | task->rt_param.domain = rt; | 146 | task->rt_param.domain = rt; |
146 | do_without_rqlock(&rt->arm_timers); | 147 | do_without_rqlock(&rt->arm_timers); |
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c index b8dc0b1f8e..5d61fe053c 100644 --- a/litmus/sched_gsn_edf.c +++ b/litmus/sched_gsn_edf.c | |||
@@ -179,8 +179,8 @@ static noinline void link_task_to_cpu(struct task_struct* linked, | |||
179 | * the caller to get things right. | 179 | * the caller to get things right. |
180 | */ | 180 | */ |
181 | if (entry != sched) { | 181 | if (entry != sched) { |
182 | TRACE_TASK(linked, | 182 | TRACE_TASK(linked, |
183 | "already scheduled on %d, updating link.\n", | 183 | "already scheduled on %d, updating link.\n", |
184 | sched->cpu); | 184 | sched->cpu); |
185 | tmp = sched->linked; | 185 | tmp = sched->linked; |
186 | linked->rt_param.linked_on = sched->cpu; | 186 | linked->rt_param.linked_on = sched->cpu; |
@@ -396,7 +396,7 @@ static void gsnedf_tick(struct task_struct* t) | |||
396 | static struct task_struct* gsnedf_schedule(struct task_struct * prev) | 396 | static struct task_struct* gsnedf_schedule(struct task_struct * prev) |
397 | { | 397 | { |
398 | cpu_entry_t* entry = &__get_cpu_var(gsnedf_cpu_entries); | 398 | cpu_entry_t* entry = &__get_cpu_var(gsnedf_cpu_entries); |
399 | int out_of_time, sleep, preempt, np, exists, blocks; | 399 | int out_of_time, sleep, preempt, np, exists, blocks; |
400 | struct task_struct* next = NULL; | 400 | struct task_struct* next = NULL; |
401 | 401 | ||
402 | /* Will be released in finish_switch. */ | 402 | /* Will be released in finish_switch. */ |
@@ -419,15 +419,15 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev) | |||
419 | TRACE_TASK(prev, "invoked gsnedf_schedule.\n"); | 419 | TRACE_TASK(prev, "invoked gsnedf_schedule.\n"); |
420 | 420 | ||
421 | if (exists) | 421 | if (exists) |
422 | TRACE_TASK(prev, | 422 | TRACE_TASK(prev, |
423 | "blocks:%d out_of_time:%d np:%d sleep:%d preempt:%d " | 423 | "blocks:%d out_of_time:%d np:%d sleep:%d preempt:%d " |
424 | "state:%d sig:%d\n", | 424 | "state:%d sig:%d\n", |
425 | blocks, out_of_time, np, sleep, preempt, | 425 | blocks, out_of_time, np, sleep, preempt, |
426 | prev->state, signal_pending(prev)); | 426 | prev->state, signal_pending(prev)); |
427 | if (entry->linked && preempt) | 427 | if (entry->linked && preempt) |
428 | TRACE_TASK(prev, "will be preempted by %s/%d\n", | 428 | TRACE_TASK(prev, "will be preempted by %s/%d\n", |
429 | entry->linked->comm, entry->linked->pid); | 429 | entry->linked->comm, entry->linked->pid); |
430 | 430 | ||
431 | 431 | ||
432 | /* If a task blocks we have no choice but to reschedule. | 432 | /* If a task blocks we have no choice but to reschedule. |
433 | */ | 433 | */ |
@@ -481,12 +481,15 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev) | |||
481 | 481 | ||
482 | spin_unlock(&gsnedf_lock); | 482 | spin_unlock(&gsnedf_lock); |
483 | 483 | ||
484 | TRACE("gsnedf_lock released, next=0x%p\n", next); | ||
485 | |||
486 | |||
484 | if (next) | 487 | if (next) |
485 | TRACE_TASK(next, "scheduled at %llu\n", litmus_clock()); | 488 | TRACE_TASK(next, "scheduled at %llu\n", litmus_clock()); |
486 | else if (exists && !next) | 489 | else if (exists && !next) |
487 | TRACE("becomes idle at %llu.\n", litmus_clock()); | 490 | TRACE("becomes idle at %llu.\n", litmus_clock()); |
488 | 491 | ||
489 | 492 | ||
490 | return next; | 493 | return next; |
491 | } | 494 | } |
492 | 495 | ||
@@ -498,6 +501,7 @@ static void gsnedf_finish_switch(struct task_struct *prev) | |||
498 | cpu_entry_t* entry = &__get_cpu_var(gsnedf_cpu_entries); | 501 | cpu_entry_t* entry = &__get_cpu_var(gsnedf_cpu_entries); |
499 | 502 | ||
500 | entry->scheduled = is_realtime(current) ? current : NULL; | 503 | entry->scheduled = is_realtime(current) ? current : NULL; |
504 | TRACE_TASK(prev, "switched away from\n"); | ||
501 | } | 505 | } |
502 | 506 | ||
503 | 507 | ||
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c index 55c55862d1..290654bb8d 100644 --- a/litmus/sched_psn_edf.c +++ b/litmus/sched_psn_edf.c | |||
@@ -58,7 +58,7 @@ static void psnedf_domain_init(psnedf_domain_t* pedf, | |||
58 | static void requeue(struct task_struct* t, rt_domain_t *edf) | 58 | static void requeue(struct task_struct* t, rt_domain_t *edf) |
59 | { | 59 | { |
60 | if (t->state != TASK_RUNNING) | 60 | if (t->state != TASK_RUNNING) |
61 | TRACE_TASK(t, "requeue: !TASK_RUNNING"); | 61 | TRACE_TASK(t, "requeue: !TASK_RUNNING\n"); |
62 | 62 | ||
63 | set_rt_flags(t, RT_F_RUNNING); | 63 | set_rt_flags(t, RT_F_RUNNING); |
64 | if (is_released(t, litmus_clock())) | 64 | if (is_released(t, litmus_clock())) |
@@ -197,17 +197,21 @@ static struct task_struct* psnedf_schedule(struct task_struct * prev) | |||
197 | if (exists) | 197 | if (exists) |
198 | next = prev; | 198 | next = prev; |
199 | 199 | ||
200 | if (next) | 200 | if (next) { |
201 | TRACE_TASK(next, " == next\n"); | ||
201 | set_rt_flags(next, RT_F_RUNNING); | 202 | set_rt_flags(next, RT_F_RUNNING); |
203 | } else { | ||
204 | TRACE("becoming idle.\n"); | ||
205 | } | ||
202 | 206 | ||
203 | pedf->scheduled = next; | 207 | pedf->scheduled = next; |
204 | spin_unlock(&pedf->slock); | 208 | spin_unlock(&pedf->slock); |
209 | |||
205 | return next; | 210 | return next; |
206 | } | 211 | } |
207 | 212 | ||
208 | 213 | ||
209 | /* Prepare a task for running in RT mode | 214 | /* Prepare a task for running in RT mode |
210 | * Enqueues the task into master queue data structure | ||
211 | */ | 215 | */ |
212 | static void psnedf_task_new(struct task_struct * t, int on_rq, int running) | 216 | static void psnedf_task_new(struct task_struct * t, int on_rq, int running) |
213 | { | 217 | { |
@@ -215,8 +219,7 @@ static void psnedf_task_new(struct task_struct * t, int on_rq, int running) | |||
215 | psnedf_domain_t* pedf = task_pedf(t); | 219 | psnedf_domain_t* pedf = task_pedf(t); |
216 | unsigned long flags; | 220 | unsigned long flags; |
217 | 221 | ||
218 | TRACE("[%d] psn edf: prepare new %d on CPU %d\n", | 222 | TRACE_TASK(t, "new\n"); |
219 | smp_processor_id(), t->pid, get_partition(t)); | ||
220 | 223 | ||
221 | /* setup job parameters */ | 224 | /* setup job parameters */ |
222 | release_at(t, litmus_clock()); | 225 | release_at(t, litmus_clock()); |
@@ -244,6 +247,7 @@ static void psnedf_task_wake_up(struct task_struct *task) | |||
244 | rt_domain_t* edf = task_edf(task); | 247 | rt_domain_t* edf = task_edf(task); |
245 | lt_t now; | 248 | lt_t now; |
246 | 249 | ||
250 | TRACE_TASK(task, "wake up\n"); | ||
247 | spin_lock_irqsave(&pedf->slock, flags); | 251 | spin_lock_irqsave(&pedf->slock, flags); |
248 | BUG_ON(in_list(&task->rt_list)); | 252 | BUG_ON(in_list(&task->rt_list)); |
249 | /* We need to take suspensions because of semaphores into | 253 | /* We need to take suspensions because of semaphores into |
@@ -261,11 +265,13 @@ static void psnedf_task_wake_up(struct task_struct *task) | |||
261 | } | 265 | } |
262 | requeue(task, edf); | 266 | requeue(task, edf); |
263 | spin_unlock_irqrestore(&pedf->slock, flags); | 267 | spin_unlock_irqrestore(&pedf->slock, flags); |
268 | TRACE_TASK(task, "wake up done\n"); | ||
264 | } | 269 | } |
265 | 270 | ||
266 | static void psnedf_task_block(struct task_struct *t) | 271 | static void psnedf_task_block(struct task_struct *t) |
267 | { | 272 | { |
268 | /* only running tasks can block, thus t is in no queue */ | 273 | /* only running tasks can block, thus t is in no queue */ |
274 | TRACE_TASK(t, "block, state=%d\n", t->state); | ||
269 | BUG_ON(!is_realtime(t)); | 275 | BUG_ON(!is_realtime(t)); |
270 | BUG_ON(in_list(&t->rt_list)); | 276 | BUG_ON(in_list(&t->rt_list)); |
271 | } | 277 | } |
@@ -316,7 +322,7 @@ static long psnedf_pi_block(struct pi_semaphore *sem, | |||
316 | if (is_released(t, litmus_clock())) | 322 | if (is_released(t, litmus_clock())) |
317 | __add_ready(edf, t); | 323 | __add_ready(edf, t); |
318 | else | 324 | else |
319 | __add_release(edf, t); | 325 | add_release(edf, t); |
320 | } | 326 | } |
321 | } | 327 | } |
322 | 328 | ||