aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn M. Calandrino <jmc@cs.unc.edu>2008-04-30 17:23:35 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2008-04-30 17:23:35 -0400
commitd5f64980b4e9970bf9bdcb0acf35cfc6e3dfa701 (patch)
treeb605f4e240c7bde76e60c7ea5e618d1469c82346
parentc7d1f86705369bed0c65be15b898a9251de21c76 (diff)
LITMUS CORE: Release jobs with hrtimers
John's proposal for how to release jobs with hrtimers.
-rw-r--r--include/litmus/edf_common.h3
-rw-r--r--include/litmus/litmus.h12
-rw-r--r--include/litmus/rt_domain.h7
-rw-r--r--include/litmus/rt_param.h4
-rw-r--r--litmus/edf_common.c5
-rw-r--r--litmus/rt_domain.c46
-rw-r--r--litmus/sched_gsn_edf.c63
-rw-r--r--litmus/sched_litmus.c6
-rw-r--r--litmus/sched_psn_edf.c53
9 files changed, 147 insertions, 52 deletions
diff --git a/include/litmus/edf_common.h b/include/litmus/edf_common.h
index f3c930b137..669900bc4c 100644
--- a/include/litmus/edf_common.h
+++ b/include/litmus/edf_common.h
@@ -12,7 +12,8 @@
12#include <litmus/rt_domain.h> 12#include <litmus/rt_domain.h>
13 13
14 14
15void edf_domain_init(rt_domain_t* rt, check_resched_needed_t resched); 15void edf_domain_init(rt_domain_t* rt, check_resched_needed_t resched,
16 release_at_t release);
16 17
17int edf_higher_prio(struct task_struct* first, 18int edf_higher_prio(struct task_struct* first,
18 struct task_struct* second); 19 struct task_struct* second);
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h
index 6e99e651d7..7a27c987b6 100644
--- a/include/litmus/litmus.h
+++ b/include/litmus/litmus.h
@@ -163,6 +163,18 @@ inline static int budget_exhausted(struct task_struct* t)
163 163
164#define get_release(t) ((t)->rt_param.job_params.release) 164#define get_release(t) ((t)->rt_param.job_params.release)
165 165
166/* Our notion of time within LITMUS: kernel monotonic time. */
167static inline lt_t litmus_clock(void)
168{
169 return ktime_to_ns(ktime_get());
170}
171
172/* A macro to convert from nanoseconds to ktime_t. */
173#define ns_to_ktime(t) ktime_add_ns(ktime_set(0, 0), t)
174
175/* The high-resolution release timer for a task. */
176#define release_timer(t) ((t)->rt_param.job_params.release_timer)
177
166/* Honor the flag in the preempt_count variable that is set 178/* Honor the flag in the preempt_count variable that is set
167 * when scheduling is in progress. 179 * when scheduling is in progress.
168 */ 180 */
diff --git a/include/litmus/rt_domain.h b/include/litmus/rt_domain.h
index 79b6034f22..fd3c205bcc 100644
--- a/include/litmus/rt_domain.h
+++ b/include/litmus/rt_domain.h
@@ -8,7 +8,7 @@
8struct _rt_domain; 8struct _rt_domain;
9 9
10typedef int (*check_resched_needed_t)(struct _rt_domain *rt); 10typedef int (*check_resched_needed_t)(struct _rt_domain *rt);
11typedef void (*release_at_t)(struct task_struct *t, lt_t start); 11typedef void (*release_at_t)(struct task_struct *t);
12 12
13typedef struct _rt_domain { 13typedef struct _rt_domain {
14 /* runnable rt tasks are in here */ 14 /* runnable rt tasks are in here */
@@ -22,6 +22,9 @@ typedef struct _rt_domain {
22 /* how do we check if we need to kick another CPU? */ 22 /* how do we check if we need to kick another CPU? */
23 check_resched_needed_t check_resched; 23 check_resched_needed_t check_resched;
24 24
25 /* how do we setup a job release? */
26 release_at_t setup_release;
27
25 /* how are tasks ordered in the ready queue? */ 28 /* how are tasks ordered in the ready queue? */
26 list_cmp_t order; 29 list_cmp_t order;
27} rt_domain_t; 30} rt_domain_t;
@@ -33,7 +36,7 @@ typedef struct _rt_domain {
33 (!list_empty(&(rt)->ready_queue)) 36 (!list_empty(&(rt)->ready_queue))
34 37
35void rt_domain_init(rt_domain_t *rt, check_resched_needed_t f, 38void rt_domain_init(rt_domain_t *rt, check_resched_needed_t f,
36 list_cmp_t order); 39 release_at_t g, list_cmp_t order);
37 40
38void __add_ready(rt_domain_t* rt, struct task_struct *new); 41void __add_ready(rt_domain_t* rt, struct task_struct *new);
39void __add_release(rt_domain_t* rt, struct task_struct *task); 42void __add_release(rt_domain_t* rt, struct task_struct *task);
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h
index 9fb5b19b78..3704924729 100644
--- a/include/litmus/rt_param.h
+++ b/include/litmus/rt_param.h
@@ -42,6 +42,10 @@ struct rt_job {
42 lt_t release; 42 lt_t release;
43 /* What is the current deadline? */ 43 /* What is the current deadline? */
44 lt_t deadline; 44 lt_t deadline;
45
46 /* The high-resolution timer used to control its release. */
47 struct hrtimer release_timer;
48
45 /* How much service has this job received so far? 49 /* How much service has this job received so far?
46 */ 50 */
47 lt_t exec_time; 51 lt_t exec_time;
diff --git a/litmus/edf_common.c b/litmus/edf_common.c
index 3d9dca852d..2e055222ea 100644
--- a/litmus/edf_common.c
+++ b/litmus/edf_common.c
@@ -74,9 +74,10 @@ void edf_release_at(struct task_struct *t, lt_t start)
74 set_rt_flags(t, RT_F_RUNNING); 74 set_rt_flags(t, RT_F_RUNNING);
75} 75}
76 76
77void edf_domain_init(rt_domain_t* rt, check_resched_needed_t resched) 77void edf_domain_init(rt_domain_t* rt, check_resched_needed_t resched,
78 release_at_t release)
78{ 79{
79 rt_domain_init(rt, resched, edf_ready_order); 80 rt_domain_init(rt, resched, release, edf_ready_order);
80} 81}
81 82
82void edf_prepare_for_next_period(struct task_struct *t) 83void edf_prepare_for_next_period(struct task_struct *t)
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c
index fe7bd29b19..d29325f232 100644
--- a/litmus/rt_domain.c
+++ b/litmus/rt_domain.c
@@ -22,26 +22,48 @@ static int dummy_resched(rt_domain_t *rt)
22 return 0; 22 return 0;
23} 23}
24 24
25static void dummy_setup_release(struct task_struct *t)
26{
27}
28
25static int dummy_order(struct list_head* a, struct list_head* b) 29static int dummy_order(struct list_head* a, struct list_head* b)
26{ 30{
27 return 0; 31 return 0;
28} 32}
29 33
34/* We now set or clear a per_cpu flag indicating if a plugin-specific call
35 * to setup a timer (that handles a job release) needs to be made. There is
36 * no need to setup multiple timers for jobs that are released at the same
37 * time. The actual clearing of this flag is a side effect of the release_order
38 * comparison function that is used when inserting a task into the
39 * release queue.
40 */
41DEFINE_PER_CPU(int, call_setup_release) = 1;
30int release_order(struct list_head* a, struct list_head* b) 42int release_order(struct list_head* a, struct list_head* b)
31{ 43{
32 return earlier_release( 44 struct task_struct *task_a = list_entry(a, struct task_struct, rt_list);
33 list_entry(a, struct task_struct, rt_list), 45 struct task_struct *task_b = list_entry(b, struct task_struct, rt_list);
34 list_entry(b, struct task_struct, rt_list)); 46
47 /* If the release times are equal, clear the flag. */
48 if (get_release(task_a) == get_release(task_b)) {
49 __get_cpu_var(call_setup_release) = 0;
50 return 0;
51 }
52
53 return earlier_release(task_a, task_b);
35} 54}
36 55
37 56
38void rt_domain_init(rt_domain_t *rt, 57void rt_domain_init(rt_domain_t *rt,
39 check_resched_needed_t f, 58 check_resched_needed_t f,
59 release_at_t g,
40 list_cmp_t order) 60 list_cmp_t order)
41{ 61{
42 BUG_ON(!rt); 62 BUG_ON(!rt);
43 if (!f) 63 if (!f)
44 f = dummy_resched; 64 f = dummy_resched;
65 if (!g)
66 g = dummy_setup_release;
45 if (!order) 67 if (!order)
46 order = dummy_order; 68 order = dummy_order;
47 INIT_LIST_HEAD(&rt->ready_queue); 69 INIT_LIST_HEAD(&rt->ready_queue);
@@ -49,6 +71,7 @@ void rt_domain_init(rt_domain_t *rt,
49 rt->ready_lock = RW_LOCK_UNLOCKED; 71 rt->ready_lock = RW_LOCK_UNLOCKED;
50 rt->release_lock = SPIN_LOCK_UNLOCKED; 72 rt->release_lock = SPIN_LOCK_UNLOCKED;
51 rt->check_resched = f; 73 rt->check_resched = f;
74 rt->setup_release = g;
52 rt->order = order; 75 rt->order = order;
53} 76}
54 77
@@ -57,9 +80,9 @@ void rt_domain_init(rt_domain_t *rt,
57 */ 80 */
58void __add_ready(rt_domain_t* rt, struct task_struct *new) 81void __add_ready(rt_domain_t* rt, struct task_struct *new)
59{ 82{
60 TRACE("rt: adding %s/%d (%llu, %llu) to ready queue at %llu\n", 83 TRACE("rt: adding %s/%d (%llu, %llu) rel=%llu to ready queue at %llu\n",
61 new->comm, new->pid, get_exec_cost(new), get_rt_period(new), 84 new->comm, new->pid, get_exec_cost(new), get_rt_period(new),
62 sched_clock()); 85 get_release(new), litmus_clock());
63 86
64 if (!list_insert(&new->rt_list, &rt->ready_queue, rt->order)) 87 if (!list_insert(&new->rt_list, &rt->ready_queue, rt->order))
65 rt->check_resched(rt); 88 rt->check_resched(rt);
@@ -92,14 +115,25 @@ void __add_release(rt_domain_t* rt, struct task_struct *task)
92 task->comm, task->pid, get_exec_cost(task), get_rt_period(task), 115 task->comm, task->pid, get_exec_cost(task), get_rt_period(task),
93 get_release(task)); 116 get_release(task));
94 117
118 /* Set flag assuming that we will need to setup another timer for
119 * the release of this job. If it turns out that this is unnecessary
120 * (because another job is already being released at that time,
121 * and setting up two timers is redundant and inefficient), then
122 * we will clear that flag so another release timer isn't setup.
123 */
124 __get_cpu_var(call_setup_release) = 1;
95 list_insert(&task->rt_list, &rt->release_queue, release_order); 125 list_insert(&task->rt_list, &rt->release_queue, release_order);
126
127 /* Setup a job release -- this typically involves a timer. */
128 if (__get_cpu_var(call_setup_release))
129 rt->setup_release(task);
96} 130}
97 131
98void __release_pending(rt_domain_t* rt) 132void __release_pending(rt_domain_t* rt)
99{ 133{
100 struct list_head *pos, *save; 134 struct list_head *pos, *save;
101 struct task_struct *queued; 135 struct task_struct *queued;
102 lt_t now = sched_clock(); 136 lt_t now = litmus_clock();
103 list_for_each_safe(pos, save, &rt->release_queue) { 137 list_for_each_safe(pos, save, &rt->release_queue) {
104 queued = list_entry(pos, struct task_struct, rt_list); 138 queued = list_entry(pos, struct task_struct, rt_list);
105 if (likely(is_released(queued, now))) { 139 if (likely(is_released(queued, now))) {
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index e879b02888..0381ddf98b 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -264,7 +264,7 @@ static noinline void requeue(struct task_struct* task)
264 * the release and 264 * the release and
265 * deadline. We just must check if it has been released. 265 * deadline. We just must check if it has been released.
266 */ 266 */
267 if (is_released(task, sched_clock())) 267 if (is_released(task, litmus_clock()))
268 __add_ready(&gsnedf, task); 268 __add_ready(&gsnedf, task);
269 else { 269 else {
270 /* it has got to wait */ 270 /* it has got to wait */
@@ -306,17 +306,16 @@ static noinline void gsnedf_job_arrival(struct task_struct* task)
306} 306}
307 307
308/* check for current job releases */ 308/* check for current job releases */
309static noinline void gsnedf_release_jobs(void) 309static noinline void gsnedf_release_jobs(void)
310{ 310{
311 struct list_head *pos, *save; 311 struct list_head *pos, *save;
312 struct task_struct *queued; 312 struct task_struct *queued;
313 lt_t now = sched_clock(); 313 lt_t now = litmus_clock();
314
315 314
316 list_for_each_safe(pos, save, &gsnedf.release_queue) { 315 list_for_each_safe(pos, save, &gsnedf.release_queue) {
317 queued = list_entry(pos, struct task_struct, rt_list); 316 queued = list_entry(pos, struct task_struct, rt_list);
318 if (likely(is_released(queued, now))) { 317 if (likely(is_released(queued, now))) {
319 /* this one is ready to go*/ 318 /* this one is ready to go */
320 list_del(pos); 319 list_del(pos);
321 set_rt_flags(queued, RT_F_RUNNING); 320 set_rt_flags(queued, RT_F_RUNNING);
322 321
@@ -329,6 +328,37 @@ static noinline void gsnedf_release_jobs(void)
329 } 328 }
330} 329}
331 330
331/* handles job releases when a timer expires */
332static enum hrtimer_restart gsnedf_release_job_timer(struct hrtimer *timer)
333{
334 unsigned long flags;
335
336 spin_lock_irqsave(&gsnedf_lock, flags);
337
338 /* Release all pending ready jobs. */
339 gsnedf_release_jobs();
340
341 spin_unlock_irqrestore(&gsnedf_lock, flags);
342
343 return HRTIMER_NORESTART;
344}
345
346/* setup a new job release timer */
347static void gsnedf_setup_release_job_timer(struct task_struct *task)
348{
349 hrtimer_init(&release_timer(task), CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
350 release_timer(task).function = gsnedf_release_job_timer;
351#ifdef CONFIG_HIGH_RES_TIMERS
352 release_timer(task).cb_mode = HRTIMER_CB_IRQSAFE_NO_RESTART;
353#endif
354
355 /* Expiration time of timer is release time of task. */
356 release_timer(task).expires = ns_to_ktime(get_release(task));
357
358 hrtimer_start(&release_timer(task), release_timer(task).expires,
359 HRTIMER_MODE_ABS);
360}
361
332/* gsnedf_tick - this function is called for every local timer 362/* gsnedf_tick - this function is called for every local timer
333 * interrupt. 363 * interrupt.
334 * 364 *
@@ -337,8 +367,6 @@ static noinline void gsnedf_release_jobs(void)
337 */ 367 */
338static void gsnedf_tick(struct task_struct* t) 368static void gsnedf_tick(struct task_struct* t)
339{ 369{
340 unsigned long flags;
341
342 if (is_realtime(t) && budget_exhausted(t)) { 370 if (is_realtime(t) && budget_exhausted(t)) {
343 if (!is_np(t)) { 371 if (!is_np(t)) {
344 /* np tasks will be preempted when they become 372 /* np tasks will be preempted when they become
@@ -356,21 +384,6 @@ static void gsnedf_tick(struct task_struct* t)
356 request_exit_np(t); 384 request_exit_np(t);
357 } 385 }
358 } 386 }
359
360 /* only the first CPU needs to release jobs */
361 /* FIXME: drive this from a hrtimer */
362 if (smp_processor_id() == 0) {
363 spin_lock_irqsave(&gsnedf_lock, flags);
364
365 /* Try to release pending jobs */
366 gsnedf_release_jobs();
367
368 /* We don't need to check linked != scheduled since
369 * set_tsk_need_resched has been set by preempt() if necessary.
370 */
371
372 spin_unlock_irqrestore(&gsnedf_lock, flags);
373 }
374} 387}
375 388
376/* caller holds gsnedf_lock */ 389/* caller holds gsnedf_lock */
@@ -524,7 +537,7 @@ static void gsnedf_task_new(struct task_struct * t, int on_rq, int running)
524 t->rt_param.linked_on = NO_CPU; 537 t->rt_param.linked_on = NO_CPU;
525 538
526 /* setup job params */ 539 /* setup job params */
527 edf_release_at(t, sched_clock()); 540 edf_release_at(t, litmus_clock());
528 541
529 gsnedf_job_arrival(t); 542 gsnedf_job_arrival(t);
530 spin_unlock_irqrestore(&gsnedf_lock, flags); 543 spin_unlock_irqrestore(&gsnedf_lock, flags);
@@ -543,7 +556,7 @@ static void gsnedf_task_wake_up(struct task_struct *task)
543 if (get_rt_flags(task) == RT_F_EXIT_SEM) { 556 if (get_rt_flags(task) == RT_F_EXIT_SEM) {
544 set_rt_flags(task, RT_F_RUNNING); 557 set_rt_flags(task, RT_F_RUNNING);
545 } else { 558 } else {
546 now = sched_clock(); 559 now = litmus_clock();
547 if (is_tardy(task, now)) { 560 if (is_tardy(task, now)) {
548 /* new sporadic release */ 561 /* new sporadic release */
549 edf_release_at(task, now); 562 edf_release_at(task, now);
@@ -711,7 +724,7 @@ static int __init init_gsn_edf(void)
711 INIT_LIST_HEAD(&entry->list); 724 INIT_LIST_HEAD(&entry->list);
712 } 725 }
713 726
714 edf_domain_init(&gsnedf, NULL); 727 edf_domain_init(&gsnedf, NULL, gsnedf_setup_release_job_timer);
715 return register_sched_plugin(&gsn_edf_plugin); 728 return register_sched_plugin(&gsn_edf_plugin);
716} 729}
717 730
diff --git a/litmus/sched_litmus.c b/litmus/sched_litmus.c
index 89ae3941db..16cdf2db59 100644
--- a/litmus/sched_litmus.c
+++ b/litmus/sched_litmus.c
@@ -5,7 +5,7 @@
5 5
6static void update_time_litmus(struct rq *rq, struct task_struct *p) 6static void update_time_litmus(struct rq *rq, struct task_struct *p)
7{ 7{
8 lt_t now = sched_clock(); 8 lt_t now = litmus_clock();
9 p->rt_param.job_params.exec_time += 9 p->rt_param.job_params.exec_time +=
10 now - p->rt_param.job_params.exec_start; 10 now - p->rt_param.job_params.exec_start;
11 p->rt_param.job_params.exec_start = now; 11 p->rt_param.job_params.exec_start = now;
@@ -88,7 +88,7 @@ static struct task_struct *pick_next_task_litmus(struct rq *rq)
88 struct task_struct* picked = rq->litmus_next; 88 struct task_struct* picked = rq->litmus_next;
89 rq->litmus_next = NULL; 89 rq->litmus_next = NULL;
90 if (picked) 90 if (picked)
91 picked->rt_param.job_params.exec_start = sched_clock(); 91 picked->rt_param.job_params.exec_start = litmus_clock();
92 return picked; 92 return picked;
93} 93}
94 94
@@ -103,7 +103,7 @@ static void task_tick_litmus(struct rq *rq, struct task_struct *p)
103 */ 103 */
104static void set_curr_task_litmus(struct rq *rq) 104static void set_curr_task_litmus(struct rq *rq)
105{ 105{
106 rq->curr->rt_param.job_params.exec_start = sched_clock(); 106 rq->curr->rt_param.job_params.exec_start = litmus_clock();
107} 107}
108 108
109 109
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c
index 961680d0a6..b60c2ce0b7 100644
--- a/litmus/sched_psn_edf.c
+++ b/litmus/sched_psn_edf.c
@@ -42,9 +42,10 @@ DEFINE_PER_CPU(psnedf_domain_t, psnedf_domains);
42 42
43static void psnedf_domain_init(psnedf_domain_t* pedf, 43static void psnedf_domain_init(psnedf_domain_t* pedf,
44 check_resched_needed_t check, 44 check_resched_needed_t check,
45 release_at_t release,
45 int cpu) 46 int cpu)
46{ 47{
47 edf_domain_init(&pedf->domain, check); 48 edf_domain_init(&pedf->domain, check, release);
48 pedf->cpu = cpu; 49 pedf->cpu = cpu;
49 pedf->lock = SPIN_LOCK_UNLOCKED; 50 pedf->lock = SPIN_LOCK_UNLOCKED;
50 pedf->scheduled = NULL; 51 pedf->scheduled = NULL;
@@ -59,7 +60,7 @@ static void requeue(struct task_struct* t, rt_domain_t *edf)
59 TRACE_TASK(t, "requeue: !TASK_RUNNING"); 60 TRACE_TASK(t, "requeue: !TASK_RUNNING");
60 61
61 set_rt_flags(t, RT_F_RUNNING); 62 set_rt_flags(t, RT_F_RUNNING);
62 if (is_released(t, sched_clock())) 63 if (is_released(t, litmus_clock()))
63 __add_ready(edf, t); 64 __add_ready(edf, t);
64 else 65 else
65 __add_release(edf, t); /* it has got to wait */ 66 __add_release(edf, t); /* it has got to wait */
@@ -98,11 +99,41 @@ static int psnedf_check_resched(rt_domain_t *edf)
98 return ret; 99 return ret;
99} 100}
100 101
102/* handles job releases when a timer expires */
103static enum hrtimer_restart psnedf_release_job_timer(struct hrtimer *timer)
104{
105 unsigned long flags;
106 rt_domain_t *edf = local_edf;
107 psnedf_domain_t *pedf = local_pedf;
108
109 spin_lock_irqsave(&pedf->lock, flags);
110
111 /* Release all pending ready jobs. */
112 __release_pending(edf);
113
114 spin_unlock_irqrestore(&pedf->lock, flags);
115
116 return HRTIMER_NORESTART;
117}
118
119/* setup a new job release timer */
120static void psnedf_setup_release_job_timer(struct task_struct *task)
121{
122 hrtimer_init(&release_timer(task), CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
123 release_timer(task).function = psnedf_release_job_timer;
124#ifdef CONFIG_HIGH_RES_TIMERS
125 release_timer(task).cb_mode = HRTIMER_CB_IRQSAFE_NO_RESTART;
126#endif
127
128 /* Expiration time of timer is release time of task. */
129 release_timer(task).expires = ns_to_ktime(get_release(task));
130
131 hrtimer_start(&release_timer(task), release_timer(task).expires,
132 HRTIMER_MODE_ABS);
133}
101 134
102static void psnedf_tick(struct task_struct *t) 135static void psnedf_tick(struct task_struct *t)
103{ 136{
104 unsigned long flags;
105 rt_domain_t *edf = local_edf;
106 psnedf_domain_t *pedf = local_pedf; 137 psnedf_domain_t *pedf = local_pedf;
107 138
108 /* Check for inconsistency. We don't need the lock for this since 139 /* Check for inconsistency. We don't need the lock for this since
@@ -121,11 +152,6 @@ static void psnedf_tick(struct task_struct *t)
121 request_exit_np(t); 152 request_exit_np(t);
122 } 153 }
123 } 154 }
124
125 spin_lock_irqsave(&pedf->lock, flags);
126 /* FIXME: release via hrtimer */
127 __release_pending(edf);
128 spin_unlock_irqrestore(&pedf->lock, flags);
129} 155}
130 156
131static void job_completion(struct task_struct* t) 157static void job_completion(struct task_struct* t)
@@ -225,7 +251,7 @@ static void psnedf_task_new(struct task_struct * t, int on_rq, int running)
225 smp_processor_id(), t->pid, get_partition(t)); 251 smp_processor_id(), t->pid, get_partition(t));
226 252
227 /* setup job parameters */ 253 /* setup job parameters */
228 edf_release_at(t, sched_clock()); 254 edf_release_at(t, litmus_clock());
229 255
230 /* The task should be running in the queue, otherwise signal 256 /* The task should be running in the queue, otherwise signal
231 * code will try to wake it up with fatal consequences. 257 * code will try to wake it up with fatal consequences.
@@ -258,7 +284,7 @@ static void psnedf_task_wake_up(struct task_struct *task)
258 * 284 *
259 * FIXME: This should be done in some more predictable and userspace-controlled way. 285 * FIXME: This should be done in some more predictable and userspace-controlled way.
260 */ 286 */
261 now = sched_clock(); 287 now = litmus_clock();
262 if (is_tardy(task, now) && 288 if (is_tardy(task, now) &&
263 get_rt_flags(task) != RT_F_EXIT_SEM) { 289 get_rt_flags(task) != RT_F_EXIT_SEM) {
264 /* new sporadic release */ 290 /* new sporadic release */
@@ -319,7 +345,7 @@ static long psnedf_pi_block(struct pi_semaphore *sem,
319 /* queued in domain*/ 345 /* queued in domain*/
320 list_del(&t->rt_list); 346 list_del(&t->rt_list);
321 /* readd to make priority change take place */ 347 /* readd to make priority change take place */
322 if (is_released(t, sched_clock())) 348 if (is_released(t, litmus_clock()))
323 __add_ready(edf, t); 349 __add_ready(edf, t);
324 else 350 else
325 __add_release(edf, t); 351 __add_release(edf, t);
@@ -430,7 +456,8 @@ static int __init init_psn_edf(void)
430 for (i = 0; i < NR_CPUS; i++) 456 for (i = 0; i < NR_CPUS; i++)
431 { 457 {
432 psnedf_domain_init(remote_pedf(i), 458 psnedf_domain_init(remote_pedf(i),
433 psnedf_check_resched, i); 459 psnedf_check_resched,
460 psnedf_setup_release_job_timer, i);
434 } 461 }
435 return register_sched_plugin(&psn_edf_plugin); 462 return register_sched_plugin(&psn_edf_plugin);
436} 463}