aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2011-01-26 17:41:51 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2011-01-26 17:44:48 -0500
commitf8db543cc4e96dc82e0bd249899321be44ec3427 (patch)
tree72c5f286364439587cad12675c30ec2fc44b457e
parent7be35bec55b1b6d6a2483e0ec3703a483da1e5a6 (diff)
EDF-WM: rely on generic enforcement timer
Since LITMUS^RT 2010.2 has generic support for precise budget enforcement, we don't need to implement it EDF-WM anymore.
-rw-r--r--litmus/sched_edf_wm.c97
1 files changed, 0 insertions, 97 deletions
diff --git a/litmus/sched_edf_wm.c b/litmus/sched_edf_wm.c
index f4219ca812d3..8b7be32b40dd 100644
--- a/litmus/sched_edf_wm.c
+++ b/litmus/sched_edf_wm.c
@@ -18,10 +18,6 @@ typedef struct {
18 int cpu; 18 int cpu;
19 struct task_struct* scheduled; /* only RT tasks */ 19 struct task_struct* scheduled; /* only RT tasks */
20 20
21 /* The enforcement timer is used to accurately police
22 * slice budgets. */
23 struct hrtimer enforcement_timer;
24 int timer_armed;
25/* 21/*
26 * scheduling lock slock 22 * scheduling lock slock
27 * protects the domain and serializes scheduling decisions 23 * protects the domain and serializes scheduling decisions
@@ -39,7 +35,6 @@ DEFINE_PER_CPU(wm_domain_t, wm_domains);
39#define local_domain (&__get_cpu_var(wm_domains)) 35#define local_domain (&__get_cpu_var(wm_domains))
40#define remote_domain(cpu) (&per_cpu(wm_domains, cpu)) 36#define remote_domain(cpu) (&per_cpu(wm_domains, cpu))
41#define domain_of_task(task) (remote_domain(get_partition(task))) 37#define domain_of_task(task) (remote_domain(get_partition(task)))
42#define domain_from_timer(t) (container_of((t), wm_domain_t, enforcement_timer))
43 38
44static int is_sliced_task(struct task_struct* t) 39static int is_sliced_task(struct task_struct* t)
45{ 40{
@@ -115,14 +110,6 @@ static lt_t slice_budget_remaining(struct task_struct* t)
115 return slice_budget(t) - slice_exec_time(t); 110 return slice_budget(t) - slice_exec_time(t);
116} 111}
117 112
118static lt_t wm_budget_remaining(struct task_struct* t)
119{
120 if (is_sliced_task(t))
121 return slice_budget_remaining(t);
122 else
123 return budget_remaining(t);
124}
125
126static int wm_budget_exhausted(struct task_struct* t) 113static int wm_budget_exhausted(struct task_struct* t)
127{ 114{
128 if (is_sliced_task(t)) 115 if (is_sliced_task(t))
@@ -214,78 +201,6 @@ static void preempt(wm_domain_t *dom)
214 preempt_if_preemptable(NULL, dom->cpu); 201 preempt_if_preemptable(NULL, dom->cpu);
215} 202}
216 203
217static enum hrtimer_restart on_enforcement_timeout(struct hrtimer *timer)
218{
219 wm_domain_t *dom = domain_from_timer(timer);
220 unsigned long flags;
221
222 raw_spin_lock_irqsave(&dom->slock, flags);
223 if (likely(dom->timer_armed)) {
224 TRACE_DOM(dom, "enforcement timer fired.\n");
225 dom->timer_armed = 0;
226 preempt(dom);
227 } else
228 TRACE_DOM(dom, "timer fired but not armed???\n");
229 raw_spin_unlock_irqrestore(&dom->slock, flags);
230 return HRTIMER_NORESTART;
231}
232
233/* assumes called with IRQs off */
234static void cancel_enforcement_timer(wm_domain_t* dom)
235{
236 int ret;
237
238 TRACE_DOM(dom, "cancelling enforcement timer.\n");
239
240 /* Arming the timer makes only sense locally. */
241 BUG_ON(dom->cpu != raw_smp_processor_id());
242
243 /* Since interrupts are disabled and and dom->timer_armed is only
244 * modified locally, we do not need to lock this domain.
245 */
246
247 if (dom->timer_armed) {
248 ret = hrtimer_try_to_cancel(&dom->enforcement_timer);
249 /* Should never be inactive. */
250 BUG_ON(ret == 0);
251 /* Should never be running concurrently. */
252 BUG_ON(ret == -1);
253
254 dom->timer_armed = 0;
255 }
256}
257
258/* assumes called with IRQs off */
259static void arm_enforcement_timer(wm_domain_t* dom, struct task_struct* t)
260{
261 lt_t when_to_fire;
262
263 TRACE_DOM(dom, "arming enforcement timer.\n");
264
265 /* The task has to belong to this domain. */
266 BUG_ON(domain_of_task(t) != dom);
267
268 /* Arming the timer makes only sense locally. */
269 BUG_ON(dom->cpu != raw_smp_processor_id());
270
271 /* Calling this when there is no budget left for the task
272 * makes no sense. */
273 BUG_ON(wm_budget_exhausted(t));
274
275 /* __hrtimer_start_range_ns() cancels the timer
276 * anyway, so we don't have to check whether it is still armed
277 */
278
279 when_to_fire = litmus_clock() + wm_budget_remaining(t);
280 __hrtimer_start_range_ns(&dom->enforcement_timer,
281 ns_to_ktime(when_to_fire),
282 0 /* delta */,
283 HRTIMER_MODE_ABS_PINNED,
284 0 /* no wakeup */);
285
286 dom->timer_armed = 1;
287}
288
289static void wm_domain_init(wm_domain_t* dom, 204static void wm_domain_init(wm_domain_t* dom,
290 check_resched_needed_t check, 205 check_resched_needed_t check,
291 release_jobs_t release, 206 release_jobs_t release,
@@ -294,9 +209,6 @@ static void wm_domain_init(wm_domain_t* dom,
294 edf_domain_init(&dom->domain, check, release); 209 edf_domain_init(&dom->domain, check, release);
295 dom->cpu = cpu; 210 dom->cpu = cpu;
296 dom->scheduled = NULL; 211 dom->scheduled = NULL;
297 dom->timer_armed = 0;
298 hrtimer_init(&dom->enforcement_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
299 dom->enforcement_timer.function = on_enforcement_timeout;
300} 212}
301 213
302static void wm_requeue_remote(struct task_struct *t) 214static void wm_requeue_remote(struct task_struct *t)
@@ -473,15 +385,6 @@ static struct task_struct* wm_schedule(struct task_struct * prev)
473 wm_requeue_remote(migrate); 385 wm_requeue_remote(migrate);
474 } 386 }
475 387
476 if (next && budget_precisely_enforced(next)) {
477 /* Make sure we call into the scheduler when this budget
478 * expires. */
479 arm_enforcement_timer(dom, next);
480 } else if (dom->timer_armed) {
481 /* Make sure we don't cause unnecessary interrupts. */
482 cancel_enforcement_timer(dom);
483 }
484
485 return next; 388 return next;
486} 389}
487 390