diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2009-12-17 21:47:19 -0500 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-29 17:19:53 -0400 |
commit | 0b28a3122d6917784701377e15a863489aee1c6c (patch) | |
tree | 259c8f59ed477e81f97b5dc6ac7ec8ce06ce1e26 /litmus | |
parent | c15be843778236e9f2fdbc207ab36ba996b2bb1b (diff) |
[ported from 2008.3] Add release-master support
Diffstat (limited to 'litmus')
-rw-r--r-- | litmus/rt_domain.c | 21 | ||||
-rw-r--r-- | litmus/sched_gsn_edf.c | 26 |
2 files changed, 36 insertions, 11 deletions
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c index 78e76421aeba..62c9fdcd22be 100644 --- a/litmus/rt_domain.c +++ b/litmus/rt_domain.c | |||
@@ -158,6 +158,7 @@ static void reinit_release_heap(struct task_struct* t) | |||
158 | 158 | ||
159 | /* initialize */ | 159 | /* initialize */ |
160 | heap_init(&rh->heap); | 160 | heap_init(&rh->heap); |
161 | atomic_set(&rh->info.state, HRTIMER_START_ON_INACTIVE); | ||
161 | } | 162 | } |
162 | /* arm_release_timer() - start local release timer or trigger | 163 | /* arm_release_timer() - start local release timer or trigger |
163 | * remote timer (pull timer) | 164 | * remote timer (pull timer) |
@@ -217,14 +218,18 @@ static void arm_release_timer(rt_domain_t *_rt) | |||
217 | TRACE_TASK(t, "arming timer 0x%p\n", &rh->timer); | 218 | TRACE_TASK(t, "arming timer 0x%p\n", &rh->timer); |
218 | /* we cannot arm the timer using hrtimer_start() | 219 | /* we cannot arm the timer using hrtimer_start() |
219 | * as it may deadlock on rq->lock | 220 | * as it may deadlock on rq->lock |
221 | * | ||
222 | * PINNED mode is ok on both local and remote CPU | ||
220 | */ | 223 | */ |
221 | /* FIXME now only one cpu without pulling | 224 | if (rt->release_master == NO_CPU) |
222 | * later more cpus; hrtimer_pull should call | 225 | __hrtimer_start_range_ns(&rh->timer, |
223 | * __hrtimer_start... always with PINNED mode | 226 | ns_to_ktime(rh->release_time), |
224 | */ | 227 | 0, HRTIMER_MODE_ABS_PINNED, 0); |
225 | __hrtimer_start_range_ns(&rh->timer, | 228 | else |
226 | ns_to_ktime(rh->release_time), | 229 | hrtimer_start_on(rt->release_master, |
227 | 0, HRTIMER_MODE_ABS_PINNED, 0); | 230 | &rh->info, &rh->timer, |
231 | ns_to_ktime(rh->release_time), | ||
232 | HRTIMER_MODE_ABS_PINNED); | ||
228 | } else | 233 | } else |
229 | TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); | 234 | TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); |
230 | } | 235 | } |
@@ -246,6 +251,8 @@ void rt_domain_init(rt_domain_t *rt, | |||
246 | if (!order) | 251 | if (!order) |
247 | order = dummy_order; | 252 | order = dummy_order; |
248 | 253 | ||
254 | rt->release_master = NO_CPU; | ||
255 | |||
249 | heap_init(&rt->ready_queue); | 256 | heap_init(&rt->ready_queue); |
250 | INIT_LIST_HEAD(&rt->tobe_released); | 257 | INIT_LIST_HEAD(&rt->tobe_released); |
251 | for (i = 0; i < RELEASE_QUEUE_SLOTS; i++) | 258 | for (i = 0; i < RELEASE_QUEUE_SLOTS; i++) |
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c index 69990805e16a..a223e69f2efb 100644 --- a/litmus/sched_gsn_edf.c +++ b/litmus/sched_gsn_edf.c | |||
@@ -393,6 +393,12 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev) | |||
393 | int out_of_time, sleep, preempt, np, exists, blocks; | 393 | int out_of_time, sleep, preempt, np, exists, blocks; |
394 | struct task_struct* next = NULL; | 394 | struct task_struct* next = NULL; |
395 | 395 | ||
396 | /* Bail out early if we are the release master. | ||
397 | * The release master never schedules any real-time tasks. | ||
398 | */ | ||
399 | if (gsnedf.release_master == entry->cpu) | ||
400 | return NULL; | ||
401 | |||
396 | spin_lock(&gsnedf_lock); | 402 | spin_lock(&gsnedf_lock); |
397 | clear_will_schedule(); | 403 | clear_will_schedule(); |
398 | 404 | ||
@@ -515,8 +521,15 @@ static void gsnedf_task_new(struct task_struct * t, int on_rq, int running) | |||
515 | if (running) { | 521 | if (running) { |
516 | entry = &per_cpu(gsnedf_cpu_entries, task_cpu(t)); | 522 | entry = &per_cpu(gsnedf_cpu_entries, task_cpu(t)); |
517 | BUG_ON(entry->scheduled); | 523 | BUG_ON(entry->scheduled); |
518 | entry->scheduled = t; | 524 | |
519 | tsk_rt(t)->scheduled_on = task_cpu(t); | 525 | if (entry->cpu != gsnedf.release_master) { |
526 | entry->scheduled = t; | ||
527 | tsk_rt(t)->scheduled_on = task_cpu(t); | ||
528 | } else { | ||
529 | /* do not schedule on release master */ | ||
530 | preempt(entry); /* force resched */ | ||
531 | tsk_rt(t)->scheduled_on = NO_CPU; | ||
532 | } | ||
520 | } else { | 533 | } else { |
521 | t->rt_param.scheduled_on = NO_CPU; | 534 | t->rt_param.scheduled_on = NO_CPU; |
522 | } | 535 | } |
@@ -758,6 +771,7 @@ static long gsnedf_activate_plugin(void) | |||
758 | cpu_entry_t *entry; | 771 | cpu_entry_t *entry; |
759 | 772 | ||
760 | heap_init(&gsnedf_cpu_heap); | 773 | heap_init(&gsnedf_cpu_heap); |
774 | gsnedf.release_master = atomic_read(&release_master_cpu); | ||
761 | 775 | ||
762 | for_each_online_cpu(cpu) { | 776 | for_each_online_cpu(cpu) { |
763 | entry = &per_cpu(gsnedf_cpu_entries, cpu); | 777 | entry = &per_cpu(gsnedf_cpu_entries, cpu); |
@@ -765,8 +779,12 @@ static long gsnedf_activate_plugin(void) | |||
765 | atomic_set(&entry->will_schedule, 0); | 779 | atomic_set(&entry->will_schedule, 0); |
766 | entry->linked = NULL; | 780 | entry->linked = NULL; |
767 | entry->scheduled = NULL; | 781 | entry->scheduled = NULL; |
768 | TRACE("GSN-EDF: Initializing CPU #%d.\n", cpu); | 782 | if (cpu != gsnedf.release_master) { |
769 | update_cpu_position(entry); | 783 | TRACE("GSN-EDF: Initializing CPU #%d.\n", cpu); |
784 | update_cpu_position(entry); | ||
785 | } else { | ||
786 | TRACE("GSN-EDF: CPU %d is release master.\n", cpu); | ||
787 | } | ||
770 | } | 788 | } |
771 | return 0; | 789 | return 0; |
772 | } | 790 | } |