From 2554c82c261906350c606e70dc2bf566cefbb190 Mon Sep 17 00:00:00 2001 From: "Bjoern B. Brandenburg" Date: Tue, 21 Sep 2010 22:17:19 -0400 Subject: EDF-WM: slice-aware budget checks and job completions --- litmus/sched_edf_wm.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/litmus/sched_edf_wm.c b/litmus/sched_edf_wm.c index 0098a3aab5b5..135f618db6b3 100644 --- a/litmus/sched_edf_wm.c +++ b/litmus/sched_edf_wm.c @@ -107,14 +107,26 @@ static void advance_next_slice(struct task_struct* t, int completion_signaled) p->task_params.semi_part.wm.slices + idx; /* Check if we need to update essential job parameters. */ - if (!idx) + if (!idx) { /* job completion */ + sched_trace_task_completion(t, !completion_signaled); complete_sliced_job(t); + } /* Update job parameters for new slice. */ compute_slice_params(t); } +static int slice_budget_exhausted(struct task_struct* t) +{ + struct rt_param* p = tsk_rt(t); + + /* Compute how much execution time has been consumed + * since last slice advancement. */ + lt_t slice_exec = p->job_params.exec_time - p->semi_part.wm.exec_time; + return slice_exec >= p->semi_part.wm.slice->budget; +} + /* we assume the lock is being held */ static void preempt(wm_domain_t *dom) { @@ -179,15 +191,32 @@ static int wm_check_resched(rt_domain_t *edf) return 0; } -static void job_completion(struct task_struct* t, int forced) +static void regular_job_completion(struct task_struct* t, int forced) { - sched_trace_task_completion(t,forced); + sched_trace_task_completion(t, forced); TRACE_TASK(t, "job_completion().\n"); set_rt_flags(t, RT_F_SLEEP); prepare_for_next_period(t); } +static void wm_job_or_slice_completion(struct task_struct* t, + int completion_signaled) +{ + if (is_sliced_task(t)) + advance_next_slice(t, completion_signaled); + else + regular_job_completion(t, !completion_signaled); +} + +static int wm_budget_exhausted(struct task_struct* t) +{ + if (is_sliced_task(t)) + return slice_budget_exhausted(t); + else + return budget_exhausted(t); +} + static void wm_tick(struct task_struct *t) { wm_domain_t *dom = local_domain; @@ -198,7 +227,7 @@ static void wm_tick(struct task_struct *t) */ BUG_ON(is_realtime(t) && t != dom->scheduled); - if (is_realtime(t) && budget_enforced(t) && budget_exhausted(t)) { + if (is_realtime(t) && budget_enforced(t) && wm_budget_exhausted(t)) { set_tsk_need_resched(t); TRACE_DOM(dom, "budget of %d exhausted in tick\n", t->pid); @@ -226,9 +255,9 @@ static struct task_struct* wm_schedule(struct task_struct * prev) /* (0) Determine state */ exists = dom->scheduled != NULL; blocks = exists && !is_running(dom->scheduled); - out_of_time = exists && - budget_enforced(dom->scheduled) && - budget_exhausted(dom->scheduled); + out_of_time = exists + && budget_enforced(dom->scheduled) + && wm_budget_exhausted(dom->scheduled); sleep = exists && get_rt_flags(dom->scheduled) == RT_F_SLEEP; preempt = edf_preemption_needed(edf, prev); @@ -248,7 +277,7 @@ static struct task_struct* wm_schedule(struct task_struct * prev) * this. */ if ((out_of_time || sleep) && !blocks) { - job_completion(dom->scheduled, !sleep); + wm_job_or_slice_completion(dom->scheduled, sleep); resched = 1; } -- cgit v1.2.2