aboutsummaryrefslogtreecommitdiffstats
path: root/litmus
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2014-02-19 15:30:22 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2014-02-19 15:33:42 -0500
commit8a74106e25e8e4d38bc1ad651258de170262ee73 (patch)
tree45541986718a8441d34daa7d88be30d0e2d95017 /litmus
parentb3d2b207a895731c10c5e3b92df9ce1d6d974038 (diff)
Port C-FL PGM algorithms to G-EDF.
Diffstat (limited to 'litmus')
-rw-r--r--litmus/sched_gsn_edf.c100
1 files changed, 65 insertions, 35 deletions
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index b819b62915f1..b6973e20cf97 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -457,45 +457,67 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev)
457 if (exists) 457 if (exists)
458 TRACE_TASK(prev, 458 TRACE_TASK(prev,
459 "blocks:%d out_of_time:%d np:%d sleep:%d preempt:%d " 459 "blocks:%d out_of_time:%d np:%d sleep:%d preempt:%d "
460 "state:%d sig:%d\n", 460 "state:%d sig:%d boosted:%d\n",
461 blocks, out_of_time, np, sleep, preempt, 461 blocks, out_of_time, np, sleep, preempt,
462 prev->state, signal_pending(prev)); 462 prev->state, signal_pending(prev),
463 is_priority_boosted(entry->scheduled));
463 if (entry->linked && preempt) 464 if (entry->linked && preempt)
464 TRACE_TASK(prev, "will be preempted by %s/%d\n", 465 TRACE_TASK(prev, "will be preempted by %s/%d\n",
465 entry->linked->comm, entry->linked->pid); 466 entry->linked->comm, entry->linked->pid);
466 467
467#ifdef CONFIG_SCHED_PGM 468#ifdef CONFIG_SCHED_PGM
468 if (exists && is_pgm_waiting(entry->scheduled)) { 469 if (exists) {
469 if (!is_priority_boosted(entry->scheduled)) { 470 if (is_pgm_sending(entry->scheduled)) {
470 TRACE_TASK(entry->scheduled, "is waiting for PGM tokens.\n"); 471 if (!is_pgm_satisfied(entry->scheduled)) {
471 BUG_ON(is_pgm_satisfied(entry->scheduled)); 472 if (!is_priority_boosted(entry->scheduled)) {
472 473 TRACE_TASK(entry->scheduled, "is sending PGM tokens and needs boosting.\n");
473 /* Boost priority so we'll be scheduled immediately 474 BUG_ON(is_pgm_satisfied(entry->scheduled));
474 when needed tokens arrive. */ 475
475 tsk_rt(entry->scheduled)->priority_boosted = 1; 476 /* We are either sending tokens or waiting for tokes.
476 tsk_rt(entry->scheduled)->boost_start_time = litmus_clock(); 477 If waiting: Boost priority so we'll be scheduled
477 478 immediately when needed tokens arrive.
478 if (unlikely(!blocks)) { 479 If sending: Boost priority so no one (specifically, our
479 /* Task has probably blocked on an inbound token socket, but 480 consumers) will preempt us while signalling the token
480 if not, re-evaluate scheduling decisions */ 481 transmission.
481 unlink(entry->scheduled); 482 */
482 gsnedf_job_arrival(entry->scheduled); 483 tsk_rt(entry->scheduled)->priority_boosted = 1;
484 tsk_rt(entry->scheduled)->boost_start_time = litmus_clock();
485
486 if (likely(!blocks)) {
487 unlink(entry->scheduled);
488 gsnedf_job_arrival(entry->scheduled);
489 /* we may regain the processor */
490 if (preempt) {
491 preempt = entry->scheduled != entry->linked;
492 if (!preempt) {
493 TRACE_TASK(entry->scheduled, "blocked preemption by lazy boosting.\n");
494 }
495 }
496 }
497 }
483 } 498 }
484 } 499 else { /* sending is satisfied */
485 else if (is_pgm_satisfied(entry->scheduled)) { 500 tsk_rt(entry->scheduled)->ctrl_page->pgm_sending = 0;
486 TRACE_TASK(entry->scheduled, "is done waiting for PGM tokens.\n"); 501 tsk_rt(entry->scheduled)->ctrl_page->pgm_satisfied = 0;
487 BUG_ON(!is_priority_boosted(entry->scheduled)); 502
488 503 if (is_priority_boosted(entry->scheduled)) {
489 /* clear any boosting */ 504 TRACE_TASK(entry->scheduled,
490 tsk_rt(entry->scheduled)->priority_boosted = 0; 505 "is done sending PGM tokens must relinquish boosting.\n");
491 setup_pgm_release(entry->scheduled); 506 /* clear boosting */
492 507 tsk_rt(entry->scheduled)->priority_boosted = 0;
493 if (likely(!blocks)) { 508 if(likely(!blocks)) {
494 /* Task has probably called sched_yield(), so blocking is 509 /* recheck priority */
495 unlikely. Re-evaluate scheduling decisions because we 510 unlink(entry->scheduled);
496 still want to run. */ 511 gsnedf_job_arrival(entry->scheduled);
497 unlink(entry->scheduled); 512 /* we may lose the processor */
498 gsnedf_job_arrival(entry->scheduled); 513 if (!preempt) {
514 preempt = entry->scheduled != entry->linked;
515 if (preempt) {
516 TRACE_TASK(entry->scheduled, "preempted by lazy unboosting.\n");
517 }
518 }
519 }
520 }
499 } 521 }
500 } 522 }
501 } 523 }
@@ -511,10 +533,13 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev)
511 * that we are still linked. Multiple calls to request_exit_np() don't 533 * that we are still linked. Multiple calls to request_exit_np() don't
512 * hurt. 534 * hurt.
513 */ 535 */
514 if (np && (out_of_time || preempt || sleep)) { 536 if (np && (out_of_time || sleep)) {
515 unlink(entry->scheduled); 537 unlink(entry->scheduled);
516 request_exit_np(entry->scheduled); 538 request_exit_np(entry->scheduled);
517 } 539 }
540 else if (np && preempt) {
541 request_exit_np(entry->scheduled);
542 }
518 543
519 /* Any task that is preemptable and either exhausts its execution 544 /* Any task that is preemptable and either exhausts its execution
520 * budget or wants to sleep completes. We may have to reschedule after 545 * budget or wants to sleep completes. We may have to reschedule after
@@ -545,12 +570,14 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev)
545 entry->scheduled->rt_param.scheduled_on = NO_CPU; 570 entry->scheduled->rt_param.scheduled_on = NO_CPU;
546 TRACE_TASK(entry->scheduled, "scheduled_on = NO_CPU\n"); 571 TRACE_TASK(entry->scheduled, "scheduled_on = NO_CPU\n");
547 } 572 }
548 } else 573 }
574 else {
549 /* Only override Linux scheduler if we have a real-time task 575 /* Only override Linux scheduler if we have a real-time task
550 * scheduled that needs to continue. 576 * scheduled that needs to continue.
551 */ 577 */
552 if (exists) 578 if (exists)
553 next = prev; 579 next = prev;
580 }
554 581
555 sched_state_task_picked(); 582 sched_state_task_picked();
556 583
@@ -565,7 +592,6 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev)
565 TRACE("becomes idle at %llu.\n", litmus_clock()); 592 TRACE("becomes idle at %llu.\n", litmus_clock());
566#endif 593#endif
567 594
568
569 return next; 595 return next;
570} 596}
571 597
@@ -637,6 +663,10 @@ static void gsnedf_task_wake_up(struct task_struct *task)
637 release_at(task, now); 663 release_at(task, now);
638 sched_trace_task_release(task); 664 sched_trace_task_release(task);
639 } 665 }
666 if (is_pgm_waiting(task)) {
667 /* shift out release/deadline, if needed */
668 setup_pgm_release(task);
669 }
640 gsnedf_job_arrival(task); 670 gsnedf_job_arrival(task);
641 raw_spin_unlock_irqrestore(&gsnedf_lock, flags); 671 raw_spin_unlock_irqrestore(&gsnedf_lock, flags);
642} 672}