diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-05-13 23:08:48 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-05-13 23:08:48 -0400 |
commit | 1d5e607b3ec430f15c563b888157a77adeac8f88 (patch) | |
tree | 7194bde4e012beca8571f5a760c2ef38efb6e5d5 /kernel | |
parent | 4791a27f872d536da02d36c1c85c35f68007960b (diff) |
Initial implementation of inherit and return priority for PSN-EDF.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched_psn_edf.c | 77 |
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 | |||
403 | static long psnedf_inherit_priority(struct pi_semaphore *sem, | 402 | static 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 | */ |
452 | static long gsnedf_return_priority(struct pi_semaphore *sem) | 450 | static 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 | ||
494 | static int psnedf_mode_change(int new_mode) | 491 | static int psnedf_mode_change(int new_mode) |
495 | { | 492 | { |