diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-09-21 22:17:19 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-09-21 22:17:19 -0400 |
commit | 2554c82c261906350c606e70dc2bf566cefbb190 (patch) | |
tree | 1a5822358e17042340dbc7f16e57261661b06414 | |
parent | 68db1efcc856e22c12cdade27c939f4dedc4c5d4 (diff) |
EDF-WM: slice-aware budget checks and job completions
-rw-r--r-- | litmus/sched_edf_wm.c | 45 |
1 files 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) | |||
107 | p->task_params.semi_part.wm.slices + idx; | 107 | p->task_params.semi_part.wm.slices + idx; |
108 | 108 | ||
109 | /* Check if we need to update essential job parameters. */ | 109 | /* Check if we need to update essential job parameters. */ |
110 | if (!idx) | 110 | if (!idx) { |
111 | /* job completion */ | 111 | /* job completion */ |
112 | sched_trace_task_completion(t, !completion_signaled); | ||
112 | complete_sliced_job(t); | 113 | complete_sliced_job(t); |
114 | } | ||
113 | 115 | ||
114 | /* Update job parameters for new slice. */ | 116 | /* Update job parameters for new slice. */ |
115 | compute_slice_params(t); | 117 | compute_slice_params(t); |
116 | } | 118 | } |
117 | 119 | ||
120 | static int slice_budget_exhausted(struct task_struct* t) | ||
121 | { | ||
122 | struct rt_param* p = tsk_rt(t); | ||
123 | |||
124 | /* Compute how much execution time has been consumed | ||
125 | * since last slice advancement. */ | ||
126 | lt_t slice_exec = p->job_params.exec_time - p->semi_part.wm.exec_time; | ||
127 | return slice_exec >= p->semi_part.wm.slice->budget; | ||
128 | } | ||
129 | |||
118 | /* we assume the lock is being held */ | 130 | /* we assume the lock is being held */ |
119 | static void preempt(wm_domain_t *dom) | 131 | static void preempt(wm_domain_t *dom) |
120 | { | 132 | { |
@@ -179,15 +191,32 @@ static int wm_check_resched(rt_domain_t *edf) | |||
179 | return 0; | 191 | return 0; |
180 | } | 192 | } |
181 | 193 | ||
182 | static void job_completion(struct task_struct* t, int forced) | 194 | static void regular_job_completion(struct task_struct* t, int forced) |
183 | { | 195 | { |
184 | sched_trace_task_completion(t,forced); | 196 | sched_trace_task_completion(t, forced); |
185 | TRACE_TASK(t, "job_completion().\n"); | 197 | TRACE_TASK(t, "job_completion().\n"); |
186 | 198 | ||
187 | set_rt_flags(t, RT_F_SLEEP); | 199 | set_rt_flags(t, RT_F_SLEEP); |
188 | prepare_for_next_period(t); | 200 | prepare_for_next_period(t); |
189 | } | 201 | } |
190 | 202 | ||
203 | static void wm_job_or_slice_completion(struct task_struct* t, | ||
204 | int completion_signaled) | ||
205 | { | ||
206 | if (is_sliced_task(t)) | ||
207 | advance_next_slice(t, completion_signaled); | ||
208 | else | ||
209 | regular_job_completion(t, !completion_signaled); | ||
210 | } | ||
211 | |||
212 | static int wm_budget_exhausted(struct task_struct* t) | ||
213 | { | ||
214 | if (is_sliced_task(t)) | ||
215 | return slice_budget_exhausted(t); | ||
216 | else | ||
217 | return budget_exhausted(t); | ||
218 | } | ||
219 | |||
191 | static void wm_tick(struct task_struct *t) | 220 | static void wm_tick(struct task_struct *t) |
192 | { | 221 | { |
193 | wm_domain_t *dom = local_domain; | 222 | wm_domain_t *dom = local_domain; |
@@ -198,7 +227,7 @@ static void wm_tick(struct task_struct *t) | |||
198 | */ | 227 | */ |
199 | BUG_ON(is_realtime(t) && t != dom->scheduled); | 228 | BUG_ON(is_realtime(t) && t != dom->scheduled); |
200 | 229 | ||
201 | if (is_realtime(t) && budget_enforced(t) && budget_exhausted(t)) { | 230 | if (is_realtime(t) && budget_enforced(t) && wm_budget_exhausted(t)) { |
202 | set_tsk_need_resched(t); | 231 | set_tsk_need_resched(t); |
203 | TRACE_DOM(dom, "budget of %d exhausted in tick\n", | 232 | TRACE_DOM(dom, "budget of %d exhausted in tick\n", |
204 | t->pid); | 233 | t->pid); |
@@ -226,9 +255,9 @@ static struct task_struct* wm_schedule(struct task_struct * prev) | |||
226 | /* (0) Determine state */ | 255 | /* (0) Determine state */ |
227 | exists = dom->scheduled != NULL; | 256 | exists = dom->scheduled != NULL; |
228 | blocks = exists && !is_running(dom->scheduled); | 257 | blocks = exists && !is_running(dom->scheduled); |
229 | out_of_time = exists && | 258 | out_of_time = exists |
230 | budget_enforced(dom->scheduled) && | 259 | && budget_enforced(dom->scheduled) |
231 | budget_exhausted(dom->scheduled); | 260 | && wm_budget_exhausted(dom->scheduled); |
232 | sleep = exists && get_rt_flags(dom->scheduled) == RT_F_SLEEP; | 261 | sleep = exists && get_rt_flags(dom->scheduled) == RT_F_SLEEP; |
233 | preempt = edf_preemption_needed(edf, prev); | 262 | preempt = edf_preemption_needed(edf, prev); |
234 | 263 | ||
@@ -248,7 +277,7 @@ static struct task_struct* wm_schedule(struct task_struct * prev) | |||
248 | * this. | 277 | * this. |
249 | */ | 278 | */ |
250 | if ((out_of_time || sleep) && !blocks) { | 279 | if ((out_of_time || sleep) && !blocks) { |
251 | job_completion(dom->scheduled, !sleep); | 280 | wm_job_or_slice_completion(dom->scheduled, sleep); |
252 | resched = 1; | 281 | resched = 1; |
253 | } | 282 | } |
254 | 283 | ||