aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2011-09-21 18:48:49 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2011-09-21 18:48:49 -0400
commit06051baff7db5e0c1b80d7b2a873b022191cdcec (patch)
tree8f0a776714f91092f312bde90df9757291382d02
parent96b86e34ab2d7d49e3e6174935c0aca2828415f5 (diff)
Formatting
-rw-r--r--litmus/sched_mc.c100
1 files changed, 35 insertions, 65 deletions
diff --git a/litmus/sched_mc.c b/litmus/sched_mc.c
index 1f2b13c6a219..0ec03b3949d2 100644
--- a/litmus/sched_mc.c
+++ b/litmus/sched_mc.c
@@ -4,10 +4,6 @@
4 * Implementation of the Mixed Criticality scheduling algorithm. 4 * Implementation of the Mixed Criticality scheduling algorithm.
5 * 5 *
6 * (Per Mollison, Erickson, Anderson, Baruah, Scoredos 2010) 6 * (Per Mollison, Erickson, Anderson, Baruah, Scoredos 2010)
7 *
8 * This version uses the simple approach and serializes all scheduling
9 * decisions by the use of a queue lock. This is probably not the
10 * best way to do it, but it should suffice for now.
11 */ 7 */
12 8
13#include <linux/spinlock.h> 9#include <linux/spinlock.h>
@@ -75,7 +71,6 @@ typedef struct {
75} domain_data_t; 71} domain_data_t;
76 72
77static cpu_entry_t* cpus[NR_CPUS]; 73static cpu_entry_t* cpus[NR_CPUS];
78static raw_spinlock_t global_lock;
79 74
80#define domain_data(dom) (container_of(dom, domain_data_t, domain)) 75#define domain_data(dom) (container_of(dom, domain_data_t, domain))
81#define is_global(dom) (domain_data(dom)->heap) 76#define is_global(dom) (domain_data(dom)->heap)
@@ -86,8 +81,7 @@ static raw_spinlock_t global_lock;
86 (((e)->linked) ? tsk_mc_crit((e)->linked) : NUM_CRIT_LEVELS - 1) 81 (((e)->linked) ? tsk_mc_crit((e)->linked) : NUM_CRIT_LEVELS - 1)
87#define crit_cpu(ce) \ 82#define crit_cpu(ce) \
88 (container_of((void*)((ce) - (ce)->level), cpu_entry_t, crit_entries)) 83 (container_of((void*)((ce) - (ce)->level), cpu_entry_t, crit_entries))
89 84/* Useful debug macros */
90/* useful debug macros */
91#define TS "(%s/%d:%d:%s)" 85#define TS "(%s/%d:%d:%s)"
92#define TA(t) (t) ? (is_ghost(t)) ? "ghost" : t->comm : "NULL", (t) ? t->pid : 1, \ 86#define TA(t) (t) ? (is_ghost(t)) ? "ghost" : t->comm : "NULL", (t) ? t->pid : 1, \
93 (t) ? t->rt_param.job_params.job_no : 1, \ 87 (t) ? t->rt_param.job_params.job_no : 1, \
@@ -115,7 +109,6 @@ static int cpu_lower_prio(struct bheap_node *a, struct bheap_node *b)
115 second = b->value; 109 second = b->value;
116 first_link = first->linked; 110 first_link = first->linked;
117 second_link = second->linked; 111 second_link = second->linked;
118
119 if (!first->usable || !second->usable) { 112 if (!first->usable || !second->usable) {
120 return second->usable && first->usable; 113 return second->usable && first->usable;
121 } else if (!first_link || !second_link) { 114 } else if (!first_link || !second_link) {
@@ -134,7 +127,6 @@ static int cpu_lower_prio(struct bheap_node *a, struct bheap_node *b)
134static noinline int mc_preempt_needed(domain_t *dom, struct task_struct* curr) 127static noinline int mc_preempt_needed(domain_t *dom, struct task_struct* curr)
135{ 128{
136 struct task_struct *next = dom->peek_ready(dom); 129 struct task_struct *next = dom->peek_ready(dom);
137
138 if (!next || !curr) { 130 if (!next || !curr) {
139 return next && !curr; 131 return next && !curr;
140 } else { 132 } else {
@@ -150,8 +142,7 @@ static noinline int mc_preempt_needed(domain_t *dom, struct task_struct* curr)
150static inline crit_entry_t* lowest_prio_cpu(domain_t *dom) 142static inline crit_entry_t* lowest_prio_cpu(domain_t *dom)
151{ 143{
152 struct bheap *heap = domain_data(dom)->heap; 144 struct bheap *heap = domain_data(dom)->heap;
153 struct bheap_node* hn; 145 struct bheap_node* hn = bheap_peek(cpu_lower_prio, heap);
154 hn = bheap_peek(cpu_lower_prio, heap);
155 return (hn) ? hn->value : NULL; 146 return (hn) ? hn->value : NULL;
156} 147}
157 148
@@ -161,11 +152,9 @@ static inline crit_entry_t* lowest_prio_cpu(domain_t *dom)
161 */ 152 */
162static void update_ghost_time(struct task_struct *p) 153static void update_ghost_time(struct task_struct *p)
163{ 154{
164 u64 delta, clock; 155 u64 clock = litmus_clock();
165 156 u64 delta = clock - p->se.exec_start;
166 BUG_ON(!is_ghost(p)); 157 BUG_ON(!is_ghost(p));
167 clock = litmus_clock();
168 delta = clock - p->se.exec_start;
169 if (unlikely ((s64)delta < 0)) { 158 if (unlikely ((s64)delta < 0)) {
170 delta = 0; 159 delta = 0;
171 TRACE_TASK(p, "WARNING: negative time delta"); 160 TRACE_TASK(p, "WARNING: negative time delta");
@@ -236,7 +225,6 @@ static void link_task_to_crit(crit_entry_t *ce,
236} 225}
237 226
238static void check_for_preempt(domain_t*); 227static void check_for_preempt(domain_t*);
239
240/** 228/**
241 * job_arrival() - Called when a task re-enters the system. 229 * job_arrival() - Called when a task re-enters the system.
242 * Caller must hold no locks. 230 * Caller must hold no locks.
@@ -247,7 +235,6 @@ static void job_arrival(struct task_struct *task)
247 235
248 TRACE_TASK(task, "Job arriving"); 236 TRACE_TASK(task, "Job arriving");
249 BUG_ON(!task); 237 BUG_ON(!task);
250
251 raw_spin_lock(dom->lock); 238 raw_spin_lock(dom->lock);
252 if (can_requeue(task)) { 239 if (can_requeue(task)) {
253 dom->requeue(dom, task); 240 dom->requeue(dom, task);
@@ -271,16 +258,16 @@ static void job_arrival(struct task_struct *task)
271 */ 258 */
272static void link_task_to_cpu(cpu_entry_t *entry, struct task_struct *task) 259static void link_task_to_cpu(cpu_entry_t *entry, struct task_struct *task)
273{ 260{
274 int i; 261 int i = entry_level(entry);
275 TRACE_TASK(task, "Linking to P%d", entry->cpu); 262 TRACE_TASK(task, "Linking to P%d", entry->cpu);
276 BUG_ON(task && tsk_rt(task)->linked_on != entry->cpu); 263 BUG_ON(task && tsk_rt(task)->linked_on != entry->cpu);
277 BUG_ON(task && is_ghost(task)); 264 BUG_ON(task && is_ghost(task));
278 265
279 i = entry_level(entry);
280 if (task){ 266 if (task){
281 set_rt_flags(task, RT_F_RUNNING); 267 set_rt_flags(task, RT_F_RUNNING);
282 } 268 }
283 entry->linked = task; 269 entry->linked = task;
270 /* Higher criticality crit entries are now usable */
284 for (; i < entry_level(entry) + 1; i++) { 271 for (; i < entry_level(entry) + 1; i++) {
285 TRACE_CRIT_ENTRY(&entry->crit_entries[i], "now usable"); 272 TRACE_CRIT_ENTRY(&entry->crit_entries[i], "now usable");
286 entry->crit_entries[i].usable = 1; 273 entry->crit_entries[i].usable = 1;
@@ -295,9 +282,8 @@ static void link_task_to_cpu(cpu_entry_t *entry, struct task_struct *task)
295 * Caller must hold the lock for @dom and @ce's CPU lock. Returns 1 if 282 * Caller must hold the lock for @dom and @ce's CPU lock. Returns 1 if
296 * a physically preemption occurred. 283 * a physically preemption occurred.
297 */ 284 */
298static int preempt(domain_t *dom, crit_entry_t *ce) 285static void preempt(domain_t *dom, crit_entry_t *ce)
299{ 286{
300 int rv = 0;
301 struct task_struct *task = dom->take_ready(dom); 287 struct task_struct *task = dom->take_ready(dom);
302 cpu_entry_t *entry = crit_cpu(ce); 288 cpu_entry_t *entry = crit_cpu(ce);
303 289
@@ -309,14 +295,11 @@ static int preempt(domain_t *dom, crit_entry_t *ce)
309 dom->requeue(dom, ce->linked); 295 dom->requeue(dom, ce->linked);
310 } 296 }
311 link_task_to_crit(ce, task); 297 link_task_to_crit(ce, task);
312
313 /* Preempt actual execution if this is a running task */ 298 /* Preempt actual execution if this is a running task */
314 if (!is_ghost(task)) { 299 if (!is_ghost(task)) {
315 link_task_to_cpu(entry, task); 300 link_task_to_cpu(entry, task);
316 preempt_if_preemptable(entry->scheduled, entry->cpu); 301 preempt_if_preemptable(entry->scheduled, entry->cpu);
317 rv = 1;
318 } 302 }
319 return rv;
320} 303}
321 304
322/** 305/**
@@ -335,7 +318,6 @@ static void update_crit_levels(cpu_entry_t *entry)
335 for (i = level + 1; i < NUM_CRIT_LEVELS; i++) { 318 for (i = level + 1; i < NUM_CRIT_LEVELS; i++) {
336 ce = &entry->crit_entries[i]; 319 ce = &entry->crit_entries[i];
337 tasks[i] = ce->linked; 320 tasks[i] = ce->linked;
338 TRACE_CRIT_ENTRY(ce, "not usable");
339 ce->usable = 0; 321 ce->usable = 0;
340 if (ce->linked) { 322 if (ce->linked) {
341 link_task_to_crit(ce, NULL); 323 link_task_to_crit(ce, NULL);
@@ -380,7 +362,6 @@ static void check_for_preempt(domain_t *dom)
380 } else /* Partitioned */ { 362 } else /* Partitioned */ {
381 ce = domain_data(dom)->crit_entry; 363 ce = domain_data(dom)->crit_entry;
382 entry = crit_cpu(ce); 364 entry = crit_cpu(ce);
383
384 raw_spin_lock(&entry->lock); 365 raw_spin_lock(&entry->lock);
385 if (ce->usable && dom->preempt_needed(dom, ce->linked)) { 366 if (ce->usable && dom->preempt_needed(dom, ce->linked)) {
386 preempt(dom, ce); 367 preempt(dom, ce);
@@ -406,11 +387,12 @@ static void remove_from_all(struct task_struct* task)
406 BUG_ON(!task); 387 BUG_ON(!task);
407 388
408 raw_spin_lock(dom->lock); 389 raw_spin_lock(dom->lock);
390
409 if (task->rt_param.linked_on != NO_CPU) { 391 if (task->rt_param.linked_on != NO_CPU) {
410 entry = cpus[task->rt_param.linked_on]; 392 entry = cpus[task->rt_param.linked_on];
411
412 raw_spin_lock(&entry->lock); 393