diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-05-10 15:38:19 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-05-10 15:38:19 -0400 |
commit | 43e4fc9dc6f608c6a794cfb0e2b458c37ab2d8b9 (patch) | |
tree | aa9eeeb3959f2e64326c1da7149f5493e43bbb83 /kernel | |
parent | 663a9f81d1723da7e3c74b07b0d53275fed0369e (diff) |
simplify P-EDF
- use edf_higher_prio
- use is_released macro
- store scheduled task in per CPU state
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched_part_edf.c | 54 |
1 files changed, 20 insertions, 34 deletions
diff --git a/kernel/sched_part_edf.c b/kernel/sched_part_edf.c index cdc75165b2..46a999e122 100644 --- a/kernel/sched_part_edf.c +++ b/kernel/sched_part_edf.c | |||
@@ -15,11 +15,10 @@ | |||
15 | 15 | ||
16 | 16 | ||
17 | typedef struct { | 17 | typedef struct { |
18 | edf_domain_t domain; | 18 | edf_domain_t domain; |
19 | int cpu; | 19 | int cpu; |
20 | int executes_realtime; | 20 | struct task_struct* scheduled; /* only RT tasks */ |
21 | jiffie_t cur_deadline; | 21 | spinlock_t lock; |
22 | spinlock_t lock; | ||
23 | } part_edf_domain_t; | 22 | } part_edf_domain_t; |
24 | 23 | ||
25 | 24 | ||
@@ -28,10 +27,9 @@ static void part_edf_domain_init(part_edf_domain_t* pedf, | |||
28 | int cpu) | 27 | int cpu) |
29 | { | 28 | { |
30 | edf_domain_init(&pedf->domain, check); | 29 | edf_domain_init(&pedf->domain, check); |
31 | pedf->cur_deadline = 0; | ||
32 | pedf->cpu = cpu; | 30 | pedf->cpu = cpu; |
33 | pedf->lock = SPIN_LOCK_UNLOCKED; | 31 | pedf->lock = SPIN_LOCK_UNLOCKED; |
34 | pedf->executes_realtime = 0; | 32 | pedf->scheduled = NULL; |
35 | } | 33 | } |
36 | 34 | ||
37 | DEFINE_PER_CPU(part_edf_domain_t, part_edf_domains); | 35 | DEFINE_PER_CPU(part_edf_domain_t, part_edf_domains); |
@@ -39,7 +37,6 @@ DEFINE_PER_CPU(part_edf_domain_t, part_edf_domains); | |||
39 | /* This check is trivial in partioned systems as we only have to consider | 37 | /* This check is trivial in partioned systems as we only have to consider |
40 | * the CPU of the partition. | 38 | * the CPU of the partition. |
41 | * | 39 | * |
42 | * TODO: implement will_schedule test. | ||
43 | */ | 40 | */ |
44 | static int part_edf_check_resched(edf_domain_t *edf) | 41 | static int part_edf_check_resched(edf_domain_t *edf) |
45 | { | 42 | { |
@@ -47,17 +44,16 @@ static int part_edf_check_resched(edf_domain_t *edf) | |||
47 | int ret = 0; | 44 | int ret = 0; |
48 | 45 | ||
49 | spin_lock(&pedf->lock); | 46 | spin_lock(&pedf->lock); |
50 | if (!list_empty(&edf->ready_queue)) { | 47 | |
51 | if (!pedf->executes_realtime || | 48 | /* because this is a callback from edf_domain_t we already hold |
52 | time_before( | 49 | * the necessary lock for the ready queue |
53 | next_ready(edf)->rt_param.times.deadline, | 50 | */ |
54 | pedf->cur_deadline) | 51 | if (preemption_needed(edf, pedf->scheduled)) { |
55 | ) { | 52 | if (pedf->cpu == smp_processor_id()) |
56 | if (pedf->cpu == smp_processor_id()) | 53 | set_tsk_need_resched(current); |
57 | set_tsk_need_resched(current); | 54 | else |
58 | else | 55 | smp_send_reschedule(pedf->cpu); |
59 | smp_send_reschedule(pedf->cpu); | 56 | ret = 1; |
60 | } | ||
61 | } | 57 | } |
62 | spin_unlock(&pedf->lock); | 58 | spin_unlock(&pedf->lock); |
63 | return ret; | 59 | return ret; |
@@ -108,8 +104,6 @@ static int part_edf_schedule(struct task_struct * prev, | |||
108 | runqueue_t * rq) | 104 | runqueue_t * rq) |
109 | { | 105 | { |
110 | int need_deactivate = 1; | 106 | int need_deactivate = 1; |
111 | int rt; | ||
112 | jiffie_t deadline; | ||
113 | unsigned long flags; | 107 | unsigned long flags; |
114 | part_edf_domain_t* pedf = &__get_cpu_var(part_edf_domains); | 108 | part_edf_domain_t* pedf = &__get_cpu_var(part_edf_domains); |
115 | edf_domain_t* edf = &pedf->domain; | 109 | edf_domain_t* edf = &pedf->domain; |
@@ -128,8 +122,6 @@ static int part_edf_schedule(struct task_struct * prev, | |||
128 | */ | 122 | */ |
129 | TRACE("prev will be next, already released\n"); | 123 | TRACE("prev will be next, already released\n"); |
130 | *next = prev; | 124 | *next = prev; |
131 | rt = 1; | ||
132 | deadline = prev->rt_param.times.deadline; | ||
133 | need_deactivate = 0; | 125 | need_deactivate = 0; |
134 | } else { | 126 | } else { |
135 | /* either not yet released, preempted, or non-rt */ | 127 | /* either not yet released, preempted, or non-rt */ |
@@ -138,19 +130,14 @@ static int part_edf_schedule(struct task_struct * prev, | |||
138 | /* stick the task into the runqueue */ | 130 | /* stick the task into the runqueue */ |
139 | __activate_task(*next, rq); | 131 | __activate_task(*next, rq); |
140 | set_task_cpu(*next, smp_processor_id()); | 132 | set_task_cpu(*next, smp_processor_id()); |
141 | rt = 1; | 133 | } |
142 | deadline = (*next)->rt_param.times.deadline; | ||
143 | } | ||
144 | else | ||
145 | rt = deadline = 0; | ||
146 | } | 134 | } |
147 | spin_lock(&pedf->lock); | 135 | spin_lock(&pedf->lock); |
148 | pedf->executes_realtime = rt; | 136 | pedf->scheduled = *next; |
149 | pedf->cur_deadline = deadline; | ||
150 | spin_unlock(&pedf->lock); | 137 | spin_unlock(&pedf->lock); |
151 | if (rt) { | 138 | if (*next) |
152 | set_rt_flags(*next, RT_F_RUNNING); | 139 | set_rt_flags(*next, RT_F_RUNNING); |
153 | } | 140 | |
154 | write_unlock_irqrestore(&edf->ready_lock, flags); | 141 | write_unlock_irqrestore(&edf->ready_lock, flags); |
155 | } | 142 | } |
156 | 143 | ||
@@ -177,8 +164,7 @@ static void part_edf_finish_switch(struct task_struct *prev) | |||
177 | * the release and | 164 | * the release and |
178 | * deadline. We just must check if has been released. | 165 | * deadline. We just must check if has been released. |
179 | */ | 166 | */ |
180 | if (time_before_eq(prev->rt_param.times.release, jiffies) | 167 | if (is_released(prev) && get_rt_mode() == MODE_RT_RUN) { |
181 | && get_rt_mode() == MODE_RT_RUN) { | ||
182 | /* already released */ | 168 | /* already released */ |
183 | add_ready(edf, prev); | 169 | add_ready(edf, prev); |
184 | TRACE("%d goes straight to ready queue\n", prev->pid); | 170 | TRACE("%d goes straight to ready queue\n", prev->pid); |