diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-09-22 23:18:11 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-09-22 23:18:11 -0400 |
commit | 3aa64c84584432a5050c3bfb1d322f9bcdde1faa (patch) | |
tree | c1ab4956061900629768a548ca9be4801ccfcff6 | |
parent | b6fd57bbcc9cb4b5e5e79ac5dfc48cca08e94e8c (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.c | 85 |
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 | ||
93 | static 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 | |||
102 | static lt_t slice_budget(struct task_struct* t) | ||
103 | { | ||
104 | return tsk_rt(t)->semi_part.wm.slice->budget; | ||
105 | } | ||
106 | |||
107 | static 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 */ | ||
113 | static lt_t slice_budget_remaining(struct task_struct* t) | ||
114 | { | ||
115 | return slice_budget(t) - slice_exec_time(t); | ||
116 | } | ||
117 | |||
118 | static 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 | |||
126 | static 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 | |||
93 | static void advance_next_slice(struct task_struct* t, int completion_signaled) | 134 | static 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 | ||
134 | static lt_t slice_exec_time(struct task_struct* t) | 175 | /* assumes time_passed does not advance past the last slice */ |
135 | { | 176 | static 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 | |||
143 | static 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 | ||
148 | static 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)) { |
154 | static 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 */ | ||
160 | static 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 | ||
274 | static 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 | |||
282 | static void wm_tick(struct task_struct *t) | 303 | static void wm_tick(struct task_struct *t) |
283 | { | 304 | { |
284 | wm_domain_t *dom = local_domain; | 305 | wm_domain_t *dom = local_domain; |