diff options
Diffstat (limited to 'litmus/sched_psn_edf.c')
-rw-r--r-- | litmus/sched_psn_edf.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c index b0c8126bd44a..a5fda133bad9 100644 --- a/litmus/sched_psn_edf.c +++ b/litmus/sched_psn_edf.c | |||
@@ -169,17 +169,25 @@ static void psnedf_tick(struct task_struct *t) | |||
169 | */ | 169 | */ |
170 | BUG_ON(is_realtime(t) && t != pedf->scheduled); | 170 | BUG_ON(is_realtime(t) && t != pedf->scheduled); |
171 | 171 | ||
172 | if (is_realtime(t) && budget_enforced(t) && budget_exhausted(t)) { | 172 | if (is_realtime(t) && budget_exhausted(t)) |
173 | if (!is_np(t)) { | 173 | { |
174 | litmus_reschedule_local(); | 174 | if (budget_signalled(t) && !sigbudget_sent(t)) { |
175 | TRACE("psnedf_scheduler_tick: " | 175 | /* signal exhaustion */ |
176 | "%d is preemptable " | 176 | send_sigbudget(t); |
177 | " => FORCE_RESCHED\n", t->pid); | 177 | } |
178 | } else if (is_user_np(t)) { | 178 | |
179 | TRACE("psnedf_scheduler_tick: " | 179 | if (budget_enforced(t)) { |
180 | "%d is non-preemptable, " | 180 | if (!is_np(t)) { |
181 | "preemption delayed.\n", t->pid); | 181 | litmus_reschedule_local(); |
182 | request_exit_np(t); | 182 | TRACE("psnedf_scheduler_tick: " |
183 | "%d is preemptable " | ||
184 | " => FORCE_RESCHED\n", t->pid); | ||
185 | } else if (is_user_np(t)) { | ||
186 | TRACE("psnedf_scheduler_tick: " | ||
187 | "%d is non-preemptable, " | ||
188 | "preemption delayed.\n", t->pid); | ||
189 | request_exit_np(t); | ||
190 | } | ||
183 | } | 191 | } |
184 | } | 192 | } |
185 | } | 193 | } |
@@ -190,8 +198,7 @@ static struct task_struct* psnedf_schedule(struct task_struct * prev) | |||
190 | rt_domain_t* edf = &pedf->domain; | 198 | rt_domain_t* edf = &pedf->domain; |
191 | struct task_struct* next; | 199 | struct task_struct* next; |
192 | 200 | ||
193 | int out_of_time, sleep, preempt, | 201 | int out_of_time, signal_budget, sleep, preempt, np, exists, blocks, resched; |
194 | np, exists, blocks, resched; | ||
195 | 202 | ||
196 | raw_spin_lock(&pedf->slock); | 203 | raw_spin_lock(&pedf->slock); |
197 | 204 | ||
@@ -208,6 +215,10 @@ static struct task_struct* psnedf_schedule(struct task_struct * prev) | |||
208 | out_of_time = exists && | 215 | out_of_time = exists && |
209 | budget_enforced(pedf->scheduled) && | 216 | budget_enforced(pedf->scheduled) && |
210 | budget_exhausted(pedf->scheduled); | 217 | budget_exhausted(pedf->scheduled); |
218 | signal_budget = exists && | ||
219 | budget_signalled(pedf->scheduled) && | ||
220 | budget_exhausted(pedf->scheduled) && | ||
221 | !sigbudget_sent(pedf->scheduled); | ||
211 | np = exists && is_np(pedf->scheduled); | 222 | np = exists && is_np(pedf->scheduled); |
212 | sleep = exists && get_rt_flags(pedf->scheduled) == RT_F_SLEEP; | 223 | sleep = exists && get_rt_flags(pedf->scheduled) == RT_F_SLEEP; |
213 | preempt = edf_preemption_needed(edf, prev); | 224 | preempt = edf_preemption_needed(edf, prev); |
@@ -218,6 +229,10 @@ static struct task_struct* psnedf_schedule(struct task_struct * prev) | |||
218 | */ | 229 | */ |
219 | resched = preempt; | 230 | resched = preempt; |
220 | 231 | ||
232 | /* Send the signal that the budget has been exhausted */ | ||
233 | if (signal_budget) | ||
234 | send_sigbudget(pedf->scheduled); | ||
235 | |||
221 | /* If a task blocks we have no choice but to reschedule. | 236 | /* If a task blocks we have no choice but to reschedule. |
222 | */ | 237 | */ |
223 | if (blocks) | 238 | if (blocks) |