aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2007-05-13 23:08:48 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2007-05-13 23:08:48 -0400
commit1d5e607b3ec430f15c563b888157a77adeac8f88 (patch)
tree7194bde4e012beca8571f5a760c2ef38efb6e5d5 /kernel
parent4791a27f872d536da02d36c1c85c35f68007960b (diff)
Initial implementation of inherit and return priority for PSN-EDF.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched_psn_edf.c77
1 files changed, 37 insertions, 40 deletions
diff --git a/kernel/sched_psn_edf.c b/kernel/sched_psn_edf.c
index 804c1298c7..9bee6256f2 100644
--- a/kernel/sched_psn_edf.c
+++ b/kernel/sched_psn_edf.c
@@ -398,8 +398,7 @@ static long psnedf_handle_priority_change(struct task_struct *t)
398 return ret; 398 return ret;
399} 399}
400 400
401#if 0 401/* XXX: Do we need to call handle_priority_change here ourselves? */
402
403static long psnedf_inherit_priority(struct pi_semaphore *sem, 402static long psnedf_inherit_priority(struct pi_semaphore *sem,
404 struct task_struct *new_waiter) 403 struct task_struct *new_waiter)
405{ 404{
@@ -409,53 +408,54 @@ static long psnedf_inherit_priority(struct pi_semaphore *sem,
409 408
410 spin_lock_irqsave(&pedf->lock, flags); 409 spin_lock_irqsave(&pedf->lock, flags);
411 410
412 /* If no inherited task, need to fix that. This occurs when 411 /* inherit_priority(xxx, NULL) is called if the current just
413 * the semaphore has been claimed, but the inherited task has 412 * became the owner of the semaphore. In this case we must check
414 * not yet been determined. Need to also compare against your 413 * whether current should inherit the priority of a waiter, but only
415 * own task priority! 414 * if doesn't already has an inherityed priority. (Why? That's how John
416 */ 415 * did in GSN-EDF... -BBB)
417 if (sem->holder && sem->holder == current && 416 */
418 !sem->holder->rt_param.inh_task) { 417 if (sem->holder == current && !current->rt_param.inh_task) {
419 TRACE("LOCK %d\n", current->pid); 418 /* we "inherit" our own priority by default */
420 sem->holder->rt_param.inh_task = sem->holder; 419 current->rt_param.inh_task = current;
420
421 if (sem->hp_sem_task && 421 if (sem->hp_sem_task &&
422 edf_higher_prio(sem->hp_sem_task, sem->holder)) { 422 edf_higher_prio(sem->hp_sem_task, sem->holder))
423 sem->holder->rt_param.inh_task = sem->hp_sem_task; 423 /* there is a higher-priority job waiting */
424 unlink(sem->holder); 424 current->rt_param.inh_task = sem->hp_sem_task;
425 gsnedf_job_arrival(sem->holder); /* requeue/link */ 425 /* handle priority change? */
426 } else { 426 else
427 sem->hp_sem_task = sem->holder; 427 /* well then set the highest-priority field accordingly */
428 } 428 sem->hp_sem_task = current;
429 } 429 }
430 430
431 /* Check if new waiting task increases priority of 431 /* Check if new waiting task increases priority of
432 * holder, and if so, respond appropriately. 432 * holder, and if so, respond appropriately.
433 */ 433 */
434 if (new_waiter && edf_higher_prio(new_waiter, sem->hp_sem_task)) { 434 if (new_waiter &&
435 edf_higher_prio(new_waiter, sem->hp_sem_task)) {
435 sem->hp_sem_task = new_waiter; 436 sem->hp_sem_task = new_waiter;
436 437 if (sem->holder)
437 /* Holder priority changed... make sure to
438 * update system as a result.
439 */
440 if (sem->holder) {
441 sem->holder->rt_param.inh_task = new_waiter; 438 sem->holder->rt_param.inh_task = new_waiter;
442 } 439 /* call handle_priority_change? */
443 } 440 }
444 441
445 spin_unlock_irqrestore(&pedf->lock, flags); 442 spin_unlock_irqrestore(&pedf->lock, flags);
446 return ret; 443 return ret;
447} 444}
448 445
446
449/* This function is called on a semaphore release, and assumes that 447/* This function is called on a semaphore release, and assumes that
450 * the current task is also the semaphore holder. 448 * the current task is also the semaphore holder.
451 */ 449 */
452static long gsnedf_return_priority(struct pi_semaphore *sem) 450static long psnedf_return_priority(struct pi_semaphore *sem)
453{ 451{
454 struct list_head *tmp, *next; 452 struct list_head *tmp, *next;
455 unsigned long flags; 453 unsigned long flags;
456 int ret = 0; 454 psnedf_domain_t* pedf = task_pedf(current);
455 int ret = 0;
456 struct task_struct * curr;
457 457
458 queue_lock_irqsave(&gsnedf_lock, flags); 458 spin_lock_irqsave(&pedf->lock, flags);
459 459
460 /* Find new highest-priority semaphore task 460 /* Find new highest-priority semaphore task
461 * if holder task is the current hp_sem_task. 461 * if holder task is the current hp_sem_task.
@@ -464,16 +464,13 @@ static long gsnedf_return_priority(struct pi_semaphore *sem)
464 sem->hp_sem_task = NULL; 464 sem->hp_sem_task = NULL;
465 if (waitqueue_active(&sem->wait)) { 465 if (waitqueue_active(&sem->wait)) {
466 list_for_each_safe(tmp, next, &sem->wait.task_list) { 466 list_for_each_safe(tmp, next, &sem->wait.task_list) {
467 wait_queue_t *curr = list_entry(tmp, 467 curr = (struct task_struct*)
468 wait_queue_t, task_list); 468 list_entry(tmp, wait_queue_t,
469 469 task_list)->private;
470
470 /* Compare task prios, find high prio task. */ 471 /* Compare task prios, find high prio task. */
471 if (edf_higher_prio( 472 if (edf_higher_prio(curr, sem->hp_sem_task))
472 (struct task_struct*)curr->private, 473 sem->hp_sem_task = curr;
473 sem->hp_sem_task)) {
474 sem->hp_sem_task =
475 (struct task_struct *)curr->private;
476 }
477 } 474 }
478 } 475 }
479 } 476 }
@@ -484,12 +481,12 @@ static long gsnedf_return_priority(struct pi_semaphore *sem)
484 /* Remove current task as holder. */ 481 /* Remove current task as holder. */
485 sem->holder = NULL; 482 sem->holder = NULL;
486 483
487 TRACE("UNLOCK %d\n", current->pid); 484 TRACE_TASK(current, "priority returned.\n");
488 485
489 queue_unlock_irqrestore(&gsnedf_lock, flags); 486 spin_unlock_irqrestore(&pedf->lock, flags);
490 return ret; 487 return ret;
491} 488}
492#endif 489
493 490
494static int psnedf_mode_change(int new_mode) 491static int psnedf_mode_change(int new_mode)
495{ 492{