diff options
author | John M. Calandrino <jmc@jupiter-cs.cs.unc.edu> | 2007-04-24 15:48:52 -0400 |
---|---|---|
committer | John M. Calandrino <jmc@jupiter-cs.cs.unc.edu> | 2007-04-24 15:48:52 -0400 |
commit | 3421ae6ac693210251335faefda997b0ccbde16d (patch) | |
tree | 37b53ae7dd78a81b654cebbcee430418f7a00b8d /kernel | |
parent | 92f94ecce15c3b22dc07ceba9422e511dbfa0b19 (diff) |
Fixed GSN-EDF to handle correct wakeup of tasks that just exited a
semaphore.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/litmus.c | 7 | ||||
-rw-r--r-- | kernel/sched.c | 4 | ||||
-rw-r--r-- | kernel/sched_gsn_edf.c | 31 |
3 files changed, 23 insertions, 19 deletions
diff --git a/kernel/litmus.c b/kernel/litmus.c index dba56a2905..f182ca093a 100644 --- a/kernel/litmus.c +++ b/kernel/litmus.c | |||
@@ -517,10 +517,9 @@ int litmus_dummy_scheduler_setup(int cmd, void __user *parameter); | |||
517 | long litmus_dummy_sleep_next_period(void); | 517 | long litmus_dummy_sleep_next_period(void); |
518 | long litmus_dummy_enter_np(struct task_struct *task); | 518 | long litmus_dummy_enter_np(struct task_struct *task); |
519 | long litmus_dummy_exit_np(struct task_struct *task); | 519 | long litmus_dummy_exit_np(struct task_struct *task); |
520 | long litmus_dummy_inherit_priority(struct task_struct *offspring, | 520 | long litmus_dummy_inherit_priority(struct pi_semaphore *sem, |
521 | struct task_struct *deceased); | 521 | struct task_struct *new_waiter); |
522 | long litmus_dummy_return_priority(struct task_struct *offspring, | 522 | long litmus_dummy_return_priority(struct pi_semaphore *sem); |
523 | struct task_struct *deceased); | ||
524 | 523 | ||
525 | 524 | ||
526 | #define CHECK(func) {\ | 525 | #define CHECK(func) {\ |
diff --git a/kernel/sched.c b/kernel/sched.c index 9e70cde182..667a1279c1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3799,6 +3799,7 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, | |||
3799 | wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list); | 3799 | wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list); |
3800 | unsigned flags = curr->flags; | 3800 | unsigned flags = curr->flags; |
3801 | 3801 | ||
3802 | set_rt_flags((struct task_struct*)curr->private, RT_F_EXIT_SEM); | ||
3802 | if (curr->func(curr, mode, sync, key) && | 3803 | if (curr->func(curr, mode, sync, key) && |
3803 | (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) | 3804 | (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) |
3804 | break; | 3805 | break; |
@@ -3818,7 +3819,8 @@ static void __pi_wake_up_common(struct pi_semaphore *s, unsigned int mode, | |||
3818 | list_for_each_safe(tmp, next, &s->wait.task_list) { | 3819 | list_for_each_safe(tmp, next, &s->wait.task_list) { |
3819 | wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list); | 3820 | wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list); |
3820 | unsigned flags = curr->flags; | 3821 | unsigned flags = curr->flags; |
3821 | 3822 | ||
3823 | set_rt_flags((struct task_struct*)curr->private, RT_F_EXIT_SEM); | ||
3822 | if (curr->func(curr, mode, sync, key) && | 3824 | if (curr->func(curr, mode, sync, key) && |
3823 | (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) | 3825 | (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) |
3824 | break; | 3826 | break; |
diff --git a/kernel/sched_gsn_edf.c b/kernel/sched_gsn_edf.c index 02f5ac924b..abf88a8f79 100644 --- a/kernel/sched_gsn_edf.c +++ b/kernel/sched_gsn_edf.c | |||
@@ -411,24 +411,27 @@ static void gsnedf_wake_up_task(struct task_struct *task) | |||
411 | task->pid, task->time_slice); | 411 | task->pid, task->time_slice); |
412 | task->state = TASK_RUNNING; | 412 | task->state = TASK_RUNNING; |
413 | 413 | ||
414 | /* FIXME: We need to take suspensions because of semaphores into | 414 | /* We need to take suspensions because of semaphores into |
415 | * account! If a job resumes after being suspended due to acquiring | 415 | * account! If a job resumes after being suspended due to acquiring |
416 | * a semaphore, it should never be treated as a new job release. | 416 | * a semaphore, it should never be treated as a new job release. |
417 | */ | 417 | */ |
418 | if (is_tardy(task)) { | 418 | if (get_rt_flags(task) == RT_F_EXIT_SEM) { |
419 | /* new sporadic release */ | ||
420 | prepare_new_release(task); | ||
421 | sched_trace_job_release(task); | ||
422 | } | ||
423 | else if (task->time_slice) | ||
424 | /* came back in time before deadline | ||
425 | */ | ||
426 | set_rt_flags(task, RT_F_RUNNING); | 419 | set_rt_flags(task, RT_F_RUNNING); |
427 | 420 | } else { | |
421 | if (is_tardy(task)) { | ||
422 | /* new sporadic release */ | ||
423 | prepare_new_release(task); | ||
424 | sched_trace_job_release(task); | ||
425 | } | ||
426 | else if (task->time_slice) | ||
427 | /* came back in time before deadline | ||
428 | */ | ||
429 | set_rt_flags(task, RT_F_RUNNING); | ||
430 | } | ||
431 | |||
428 | queue_lock_irqsave(&gsnedf_lock, flags); | 432 | queue_lock_irqsave(&gsnedf_lock, flags); |
429 | gsnedf_job_arrival(task); | 433 | gsnedf_job_arrival(task); |
430 | queue_unlock_irqrestore(&gsnedf_lock, flags); | 434 | queue_unlock_irqrestore(&gsnedf_lock, flags); |
431 | |||
432 | } | 435 | } |
433 | 436 | ||
434 | static void gsnedf_task_blocks(struct task_struct *t) | 437 | static void gsnedf_task_blocks(struct task_struct *t) |