aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-04-12 15:17:26 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2013-04-12 15:17:26 -0400
commit4ffefb822b9d65d4efbedb60e3c9a0e76895cc5b (patch)
tree905444d931d01e59a8bd1b06a1e9e88b89a05377
parentf4ffe0719dfc150ee182f308d31a226b034f206b (diff)
Changed completion flag use to remove race condition in Cedf,Gedf.
-rw-r--r--include/litmus/budget.h2
-rw-r--r--litmus/jobs.c2
-rw-r--r--litmus/sched_cedf.c3
-rw-r--r--litmus/sched_gsn_edf.c3
-rw-r--r--litmus/sync.c12
5 files changed, 14 insertions, 8 deletions
diff --git a/include/litmus/budget.h b/include/litmus/budget.h
index 33344ee8d5f9..c4e9e40a828e 100644
--- a/include/litmus/budget.h
+++ b/include/litmus/budget.h
@@ -29,7 +29,7 @@ static inline int requeue_preempted_job(struct task_struct* t)
29 /* Add task to ready queue only if not subject to budget enforcement or 29 /* Add task to ready queue only if not subject to budget enforcement or
30 * if the job has budget remaining. t may be NULL. 30 * if the job has budget remaining. t may be NULL.
31 */ 31 */
32 return t && (!budget_exhausted(t) || !budget_enforced(t)); 32 return t && !is_completed(t) && (!budget_exhausted(t) || !budget_enforced(t));
33} 33}
34 34
35#endif 35#endif
diff --git a/litmus/jobs.c b/litmus/jobs.c
index 13a4ed4c9e93..3edb7ab4af60 100644
--- a/litmus/jobs.c
+++ b/litmus/jobs.c
@@ -28,7 +28,7 @@ void prepare_for_next_period(struct task_struct *t)
28 * release and deadline. Lateness may be negative. 28 * release and deadline. Lateness may be negative.
29 */ 29 */
30 t->rt_param.job_params.lateness = 30 t->rt_param.job_params.lateness =
31 (long long)litmus_clock() - 31 (long long)litmus_clock() -
32 (long long)t->rt_param.job_params.deadline; 32 (long long)t->rt_param.job_params.deadline;
33 33
34 setup_release(t, get_release(t) + get_rt_period(t)); 34 setup_release(t, get_release(t) + get_rt_period(t));
diff --git a/litmus/sched_cedf.c b/litmus/sched_cedf.c
index 6e1327bbf504..91f7c6f91dc4 100644
--- a/litmus/sched_cedf.c
+++ b/litmus/sched_cedf.c
@@ -171,7 +171,6 @@ static noinline void link_task_to_cpu(struct task_struct* linked,
171 171
172 /* Link new task to CPU. */ 172 /* Link new task to CPU. */
173 if (linked) { 173 if (linked) {
174 tsk_rt(linked)->completed = 0;
175 /* handle task is already scheduled somewhere! */ 174 /* handle task is already scheduled somewhere! */
176 on_cpu = linked->rt_param.scheduled_on; 175 on_cpu = linked->rt_param.scheduled_on;
177 if (on_cpu != NO_CPU) { 176 if (on_cpu != NO_CPU) {
@@ -350,7 +349,7 @@ static noinline void job_completion(struct task_struct *t, int forced)
350 TRACE_TASK(t, "job_completion().\n"); 349 TRACE_TASK(t, "job_completion().\n");
351 350
352 /* set flags */ 351 /* set flags */
353 tsk_rt(t)->completed = 1; 352 tsk_rt(t)->completed = 0;
354 /* prepare for next period */ 353 /* prepare for next period */
355 prepare_for_next_period(t); 354 prepare_for_next_period(t);
356 if (is_early_releasing(t) || is_released(t, litmus_clock())) 355 if (is_early_releasing(t) || is_released(t, litmus_clock()))
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index 5956978ccdbe..04454e8ce51e 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -173,7 +173,6 @@ static noinline void link_task_to_cpu(struct task_struct* linked,
173 173
174 /* Link new task to CPU. */ 174 /* Link new task to CPU. */
175 if (linked) { 175 if (linked) {
176 tsk_rt(linked)->completed = 0;
177 /* handle task is already scheduled somewhere! */ 176 /* handle task is already scheduled somewhere! */
178 on_cpu = linked->rt_param.scheduled_on; 177 on_cpu = linked->rt_param.scheduled_on;
179 if (on_cpu != NO_CPU) { 178 if (on_cpu != NO_CPU) {
@@ -341,7 +340,7 @@ static noinline void job_completion(struct task_struct *t, int forced)
341 TRACE_TASK(t, "job_completion().\n"); 340 TRACE_TASK(t, "job_completion().\n");
342 341
343 /* set flags */ 342 /* set flags */
344 tsk_rt(t)->completed = 1; 343 tsk_rt(t)->completed = 0;
345 /* prepare for next period */ 344 /* prepare for next period */
346 prepare_for_next_period(t); 345 prepare_for_next_period(t);
347 if (is_early_releasing(t) || is_released(t, litmus_clock())) 346 if (is_early_releasing(t) || is_released(t, litmus_clock()))
diff --git a/litmus/sync.c b/litmus/sync.c
index 3e79e0a12a5a..88a050e10ee7 100644
--- a/litmus/sync.c
+++ b/litmus/sync.c
@@ -50,12 +50,20 @@ static long do_wait_for_ts_release(void)
50 ret = wait_for_completion_interruptible(&wait.completion); 50 ret = wait_for_completion_interruptible(&wait.completion);
51 51
52 if (!ret) { 52 if (!ret) {
53 /* Setting this flag before releasing ensures that this CPU
54 * will be the next CPU to requeue the task on a ready or
55 * release queue.
56 */
57 tsk_rt(current)->completed = 1;
58 mb();
59
53 /* Completion succeeded, setup release. */ 60 /* Completion succeeded, setup release. */
54 litmus->release_at(current, wait.ts_release_time 61 litmus->release_at(current, wait.ts_release_time
55 + current->rt_param.task_params.phase 62 + current->rt_param.task_params.phase
56 - current->rt_param.task_params.period); 63 - current->rt_param.task_params.period);
57 /* trigger advance to next job release at the programmed time */ 64
58 ret = complete_job(); 65 schedule();
66 ret = 0;
59 } else { 67 } else {
60 /* We were interrupted, must cleanup list. */ 68 /* We were interrupted, must cleanup list. */
61 mutex_lock(&task_release_lock); 69 mutex_lock(&task_release_lock);