diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-09-21 22:49:37 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-10-18 17:07:27 -0400 |
commit | 8cc60b37588e130bed9d418bcfbe4d64c3a91935 (patch) | |
tree | 8a3644e785bcd47984d76be0ccbe58f20da9fa4c /litmus | |
parent | 2ed4499a959f8fc30e430b6644ec83ceb7d49ef6 (diff) |
rt_domain_t: add add_release_on()
This API addition allows the calling code to override
the release master for a given rt_domain_t object. This
is particularly useful if a job is supposed to migrate
to a particular CPU. This need arises for example in semi-
partitioned schedulers.
Diffstat (limited to 'litmus')
-rw-r--r-- | litmus/rt_domain.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c index 8a3ff706c208..d27af48e0298 100644 --- a/litmus/rt_domain.c +++ b/litmus/rt_domain.c | |||
@@ -169,7 +169,12 @@ static void reinit_release_heap(struct task_struct* t) | |||
169 | * - tobe_lock taken | 169 | * - tobe_lock taken |
170 | * - IRQ disabled | 170 | * - IRQ disabled |
171 | */ | 171 | */ |
172 | static void arm_release_timer(rt_domain_t *_rt) | 172 | #ifdef CONFIG_RELEASE_MASTER |
173 | #define arm_release_timer(t) arm_release_timer_on((t), NO_CPU) | ||
174 | static void arm_release_timer_on(rt_domain_t *_rt , int target_cpu) | ||
175 | #else | ||
176 | static void arm_release_master(rt_domain_t *_rt) | ||
177 | #endif | ||
173 | { | 178 | { |
174 | rt_domain_t *rt = _rt; | 179 | rt_domain_t *rt = _rt; |
175 | struct list_head list; | 180 | struct list_head list; |
@@ -224,17 +229,21 @@ static void arm_release_timer(rt_domain_t *_rt) | |||
224 | * PINNED mode is ok on both local and remote CPU | 229 | * PINNED mode is ok on both local and remote CPU |
225 | */ | 230 | */ |
226 | #ifdef CONFIG_RELEASE_MASTER | 231 | #ifdef CONFIG_RELEASE_MASTER |
227 | if (rt->release_master == NO_CPU) | 232 | if (rt->release_master == NO_CPU && |
233 | target_cpu == NO_CPU) | ||
228 | #endif | 234 | #endif |
229 | __hrtimer_start_range_ns(&rh->timer, | 235 | __hrtimer_start_range_ns(&rh->timer, |
230 | ns_to_ktime(rh->release_time), | 236 | ns_to_ktime(rh->release_time), |
231 | 0, HRTIMER_MODE_ABS_PINNED, 0); | 237 | 0, HRTIMER_MODE_ABS_PINNED, 0); |
232 | #ifdef CONFIG_RELEASE_MASTER | 238 | #ifdef CONFIG_RELEASE_MASTER |
233 | else | 239 | else |
234 | hrtimer_start_on(rt->release_master, | 240 | hrtimer_start_on( |
235 | &rh->info, &rh->timer, | 241 | /* target_cpu overrides release master */ |
236 | ns_to_ktime(rh->release_time), | 242 | (target_cpu != NO_CPU ? |
237 | HRTIMER_MODE_ABS_PINNED); | 243 | target_cpu : rt->release_master), |
244 | &rh->info, &rh->timer, | ||
245 | ns_to_ktime(rh->release_time), | ||
246 | HRTIMER_MODE_ABS_PINNED); | ||
238 | #endif | 247 | #endif |
239 | } else | 248 | } else |
240 | TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); | 249 | TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); |
@@ -299,6 +308,25 @@ void __merge_ready(rt_domain_t* rt, struct bheap* tasks) | |||
299 | rt->check_resched(rt); | 308 | rt->check_resched(rt); |
300 | } | 309 | } |
301 | 310 | ||
311 | |||
312 | #ifdef CONFIG_RELEASE_MASTER | ||
313 | void __add_release_on(rt_domain_t* rt, struct task_struct *task, | ||
314 | int target_cpu) | ||
315 | { | ||
316 | TRACE_TASK(task, "add_release_on(), rel=%llu, target=%d\n", | ||
317 | get_release(task), target_cpu); | ||
318 | list_add(&tsk_rt(task)->list, &rt->tobe_released); | ||
319 | task->rt_param.domain = rt; | ||
320 | |||
321 | /* start release timer */ | ||
322 | TS_SCHED2_START(task); | ||
323 | |||
324 | arm_release_timer_on(rt, target_cpu); | ||
325 | |||
326 | TS_SCHED2_END(task); | ||
327 | } | ||
328 | #endif | ||
329 | |||
302 | /* add_release - add a real-time task to the rt release queue. | 330 | /* add_release - add a real-time task to the rt release queue. |
303 | * @task: the sleeping task | 331 | * @task: the sleeping task |
304 | */ | 332 | */ |