aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2010-09-22 23:18:11 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2010-09-22 23:18:11 -0400
commit3aa64c84584432a5050c3bfb1d322f9bcdde1faa (patch)
treec1ab4956061900629768a548ca9be4801ccfcff6
parentb6fd57bbcc9cb4b5e5e79ac5dfc48cca08e94e8c (diff)
EDF-WM: handle races between out_of_time and blocks
Also move budget handling functions to top of file.
-rw-r--r--litmus/sched_edf_wm.c85
1 files changed, 53 insertions, 32 deletions
diff --git a/litmus/sched_edf_wm.c b/litmus/sched_edf_wm.c
index e25977a91c8b..c3d241a42566 100644
--- a/litmus/sched_edf_wm.c
+++ b/litmus/sched_edf_wm.c
@@ -90,6 +90,47 @@ static void complete_sliced_job(struct task_struct* t)
90 p->semi_part.wm.job_deadline = p->job_params.deadline; 90 p->semi_part.wm.job_deadline = p->job_params.deadline;
91} 91}
92 92
93static lt_t slice_exec_time(struct task_struct* t)
94{
95 struct rt_param* p = tsk_rt(t);
96
97 /* Compute how much execution time has been consumed
98 * since last slice advancement. */
99 return p->job_params.exec_time - p->semi_part.wm.exec_time;
100}
101
102static lt_t slice_budget(struct task_struct* t)
103{
104 return tsk_rt(t)->semi_part.wm.slice->budget;
105}
106
107static int slice_budget_exhausted(struct task_struct* t)
108{
109 return slice_exec_time(t) >= slice_budget(t);
110}
111
112/* assumes positive remainder; overflows otherwise */
113static lt_t slice_budget_remaining(struct task_struct* t)
114{
115 return slice_budget(t) - slice_exec_time(t);
116}
117
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)
127{
128 if (is_sliced_task(t))
129 return slice_budget_exhausted(t);
130 else
131 return budget_exhausted(t);
132}
133
93static void advance_next_slice(struct task_struct* t, int completion_signaled) 134static void advance_next_slice(struct task_struct* t, int completion_signaled)
94{ 135{
95 int idx; 136 int idx;
@@ -131,34 +172,22 @@ static void advance_next_slice(struct task_struct* t, int completion_signaled)
131 compute_slice_params(t); 172 compute_slice_params(t);
132} 173}
133 174
134static lt_t slice_exec_time(struct task_struct* t) 175/* assumes time_passed does not advance past the last slice */
135{ 176static void fast_forward_slices(struct task_struct* t, lt_t time_passed)
136 struct rt_param* p = tsk_rt(t);
137
138 /* Compute how much execution time has been consumed
139 * since last slice advancement. */
140 return p->job_params.exec_time - p->semi_part.wm.exec_time;
141}
142
143static lt_t slice_budget(struct task_struct* t)
144{ 177{
145 return tsk_rt(t)->semi_part.wm.slice->budget; 178 TRACE_TASK(t, "fast forwarding %lluns\n", time_passed);
146}
147 179
148static int slice_budget_exhausted(struct task_struct* t) 180 /* this is NOT the slice version */
149{ 181 BUG_ON(budget_remaining(t) <= time_passed);
150 return slice_exec_time(t) >= slice_budget(t);
151}
152 182
153/* assumes positive remainder; overflows otherwise */ 183 if (wm_budget_exhausted(t)) {
154static lt_t slice_budget_remaining(struct task_struct* t) 184 /* This can happen if a suspension raced
155{ 185 * with a normal slice advancement. wm_schedule()
156 return slice_budget(t) - slice_exec_time(t); 186 * does not process out_of_time when a task blocks. */
157} 187 TRACE_TASK(t, "block raced with out_of_time?\n");
188 advance_next_slice(t, 0);
189 }
158 190
159/* assumes time_passed does not advance past the last slice */
160static void fast_forward_slices(struct task_struct* t, lt_t time_passed)
161{
162 while (time_passed && 191 while (time_passed &&
163 time_passed >= slice_budget_remaining(t)) { 192 time_passed >= slice_budget_remaining(t)) {
164 /* slice completely exhausted */ 193 /* slice completely exhausted */
@@ -271,14 +300,6 @@ static void wm_job_or_slice_completion(struct task_struct* t,
271 regular_job_completion(t, !completion_signaled); 300 regular_job_completion(t, !completion_signaled);
272} 301}
273 302
274static int wm_budget_exhausted(struct task_struct* t)
275{
276 if (is_sliced_task(t))
277 return slice_budget_exhausted(t);
278 else
279 return budget_exhausted(t);
280}
281
282static void wm_tick(struct task_struct *t) 303static void wm_tick(struct task_struct *t)
283{ 304{
284 wm_domain_t *dom = local_domain; 305 wm_domain_t *dom = local_domain;