diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2010-07-12 15:44:38 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2010-08-03 12:43:00 -0400 |
commit | 12487168052ed51bb516ecc7d42be19f8eae420a (patch) | |
tree | 222e10e42e0802036b70d64028b1ea2738948ae8 | |
parent | 75c3c9401c855904f03f224edc362c9f195ad951 (diff) |
P-EDF updated to use the generic pi framework.wip-prio-inh
Updated P-EDF to use the restructured pi_semaphore/fmlp_semaphore from
7ef1e106db5a061682028fdc4d8ffd131729868a. Changes are mainly limited to
updating the FMLP-Long implementation to use fmlp_semaphore.
-rw-r--r-- | litmus/sched_psn_edf.c | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c index e50b27391d21..8148c9cb0c33 100644 --- a/litmus/sched_psn_edf.c +++ b/litmus/sched_psn_edf.c | |||
@@ -20,6 +20,9 @@ | |||
20 | #include <litmus/sched_plugin.h> | 20 | #include <litmus/sched_plugin.h> |
21 | #include <litmus/edf_common.h> | 21 | #include <litmus/edf_common.h> |
22 | 22 | ||
23 | #ifdef CONFIG_FMLP | ||
24 | #include <litmus/prio_sem.h> | ||
25 | #endif | ||
23 | 26 | ||
24 | typedef struct { | 27 | typedef struct { |
25 | rt_domain_t domain; | 28 | rt_domain_t domain; |
@@ -307,9 +310,10 @@ static void psnedf_task_exit(struct task_struct * t) | |||
307 | } | 310 | } |
308 | 311 | ||
309 | #ifdef CONFIG_FMLP | 312 | #ifdef CONFIG_FMLP |
310 | static long psnedf_pi_block(struct pi_semaphore *sem, | 313 | static long psnedf_fmlp_pi_block(struct pi_semaphore *_sem, |
311 | struct task_struct *new_waiter) | 314 | struct task_struct *new_waiter) |
312 | { | 315 | { |
316 | struct fmlp_semaphore *sem = to_fmlp(_sem); | ||
313 | psnedf_domain_t* pedf; | 317 | psnedf_domain_t* pedf; |
314 | rt_domain_t* edf; | 318 | rt_domain_t* edf; |
315 | struct task_struct* t; | 319 | struct task_struct* t; |
@@ -317,7 +321,7 @@ static long psnedf_pi_block(struct pi_semaphore *sem, | |||
317 | 321 | ||
318 | BUG_ON(!new_waiter); | 322 | BUG_ON(!new_waiter); |
319 | 323 | ||
320 | if (edf_higher_prio(new_waiter, sem->hp.cpu_task[cpu])) { | 324 | if (edf_higher_prio(new_waiter, sem->pi.hp.cpu_task[cpu])) { |
321 | TRACE_TASK(new_waiter, " boosts priority\n"); | 325 | TRACE_TASK(new_waiter, " boosts priority\n"); |
322 | pedf = task_pedf(new_waiter); | 326 | pedf = task_pedf(new_waiter); |
323 | edf = task_edf(new_waiter); | 327 | edf = task_edf(new_waiter); |
@@ -326,11 +330,13 @@ static long psnedf_pi_block(struct pi_semaphore *sem, | |||
326 | raw_spin_lock(&pedf->slock); | 330 | raw_spin_lock(&pedf->slock); |
327 | 331 | ||
328 | /* store new highest-priority task */ | 332 | /* store new highest-priority task */ |
329 | sem->hp.cpu_task[cpu] = new_waiter; | 333 | sem->pi.hp.cpu_task[cpu] = new_waiter; |
330 | if (sem->holder && | 334 | if (sem->holder && |
331 | get_partition(sem->holder) == get_partition(new_waiter)) { | 335 | get_partition(sem->holder) == get_partition(new_waiter)) { |
336 | |||
332 | /* let holder inherit */ | 337 | /* let holder inherit */ |
333 | sem->holder->rt_param.inh_task = new_waiter; | 338 | sem->holder->rt_param.eff_priority = new_waiter; |
339 | |||
334 | t = sem->holder; | 340 | t = sem->holder; |
335 | if (is_queued(t)) { | 341 | if (is_queued(t)) { |
336 | /* queued in domain*/ | 342 | /* queued in domain*/ |
@@ -354,21 +360,28 @@ static long psnedf_pi_block(struct pi_semaphore *sem, | |||
354 | return 0; | 360 | return 0; |
355 | } | 361 | } |
356 | 362 | ||
357 | static long psnedf_inherit_priority(struct pi_semaphore *sem, | 363 | static long psnedf_fmlp_inherit_priority(struct pi_semaphore *_sem, |
358 | struct task_struct *new_owner) | 364 | struct task_struct *new_owner) |
359 | { | 365 | { |
366 | struct fmlp_semaphore *sem = to_fmlp(_sem); | ||
360 | int cpu = get_partition(new_owner); | 367 | int cpu = get_partition(new_owner); |
361 | 368 | ||
362 | new_owner->rt_param.inh_task = sem->hp.cpu_task[cpu]; | 369 | if (sem->pi.hp.cpu_task[cpu] && new_owner != sem->pi.hp.cpu_task[cpu]) { |
363 | if (sem->hp.cpu_task[cpu] && new_owner != sem->hp.cpu_task[cpu]) { | 370 | new_owner->rt_param.eff_priority = sem->pi.hp.cpu_task[cpu]; |
364 | TRACE_TASK(new_owner, | 371 | TRACE_TASK(new_owner, |
365 | "inherited priority from %s/%d\n", | 372 | "inherited priority from %s/%d\n", |
366 | sem->hp.cpu_task[cpu]->comm, | 373 | sem->pi.hp.cpu_task[cpu]->comm, |
367 | sem->hp.cpu_task[cpu]->pid); | 374 | sem->pi.hp.cpu_task[cpu]->pid); |
368 | } else | 375 | } |
376 | else | ||
377 | { | ||
378 | /* inherit "self" to remain consistent with pi_sem_stack model. */ | ||
379 | new_owner->rt_param.eff_priority = new_owner; | ||
369 | TRACE_TASK(new_owner, | 380 | TRACE_TASK(new_owner, |
370 | "cannot inherit priority: " | 381 | "cannot inherit priority: " |
371 | "no higher priority job waits on this CPU!\n"); | 382 | "no higher priority job waits on this CPU!\n"); |
383 | } | ||
384 | |||
372 | /* make new owner non-preemptable as required by FMLP under | 385 | /* make new owner non-preemptable as required by FMLP under |
373 | * PSN-EDF. | 386 | * PSN-EDF. |
374 | */ | 387 | */ |
@@ -380,8 +393,9 @@ static long psnedf_inherit_priority(struct pi_semaphore *sem, | |||
380 | /* This function is called on a semaphore release, and assumes that | 393 | /* This function is called on a semaphore release, and assumes that |
381 | * the current task is also the semaphore holder. | 394 | * the current task is also the semaphore holder. |
382 | */ | 395 | */ |
383 | static long psnedf_return_priority(struct pi_semaphore *sem) | 396 | static long psnedf_fmlp_return_priority(struct pi_semaphore *_sem) |
384 | { | 397 | { |
398 | struct fmlp_semaphore* sem = to_fmlp(_sem); | ||
385 | struct task_struct* t = current; | 399 | struct task_struct* t = current; |
386 | psnedf_domain_t* pedf = task_pedf(t); | 400 | psnedf_domain_t* pedf = task_pedf(t); |
387 | rt_domain_t* edf = task_edf(t); | 401 | rt_domain_t* edf = task_edf(t); |
@@ -389,13 +403,12 @@ static long psnedf_return_priority(struct pi_semaphore *sem) | |||
389 | int cpu = get_partition(current); | 403 | int cpu = get_partition(current); |
390 | int still_np; | 404 | int still_np; |
391 | 405 | ||
392 | |||
393 | /* Find new highest-priority semaphore task | 406 | /* Find new highest-priority semaphore task |
394 | * if holder task is the current hp.cpu_task[cpu]. | 407 | * if holder task is the current hp.cpu_task[cpu]. |
395 | * | 408 | * |
396 | * Calling function holds sem->wait.lock. | 409 | * Calling function holds sem->wait.lock. |
397 | */ | 410 | */ |
398 | if (t == sem->hp.cpu_task[cpu]) | 411 | if (t == sem->pi.hp.cpu_task[cpu]) |
399 | edf_set_hp_cpu_task(sem, cpu); | 412 | edf_set_hp_cpu_task(sem, cpu); |
400 | 413 | ||
401 | still_np = take_np(current); | 414 | still_np = take_np(current); |
@@ -404,12 +417,16 @@ static long psnedf_return_priority(struct pi_semaphore *sem) | |||
404 | * should always be zero */ | 417 | * should always be zero */ |
405 | BUG_ON(still_np); | 418 | BUG_ON(still_np); |
406 | 419 | ||
407 | if (current->rt_param.inh_task) { | 420 | |
421 | if (current->rt_param.eff_priority && | ||
422 | (current->rt_param.eff_priority != current)) { | ||
408 | TRACE_CUR("return priority of %s/%d\n", | 423 | TRACE_CUR("return priority of %s/%d\n", |
409 | current->rt_param.inh_task->comm, | 424 | current->rt_param.eff_priority->comm, |
410 | current->rt_param.inh_task->pid); | 425 | current->rt_param.eff_priority->pid); |
411 | } else | 426 | } |
427 | else { | ||
412 | TRACE_CUR(" no priority to return %p\n", sem); | 428 | TRACE_CUR(" no priority to return %p\n", sem); |
429 | } | ||
413 | 430 | ||
414 | 431 | ||
415 | /* Always check for delayed preemptions that might have become | 432 | /* Always check for delayed preemptions that might have become |
@@ -417,8 +434,8 @@ static long psnedf_return_priority(struct pi_semaphore *sem) | |||
417 | */ | 434 | */ |
418 | raw_spin_lock(&pedf->slock); | 435 | raw_spin_lock(&pedf->slock); |
419 | 436 | ||
420 | /* Reset inh_task to NULL. */ | 437 | /* Reset eff_priority to NULL since we don't hold the lock. */ |
421 | current->rt_param.inh_task = NULL; | 438 | current->rt_param.eff_priority = NULL; |
422 | 439 | ||
423 | /* check if we need to reschedule */ | 440 | /* check if we need to reschedule */ |
424 | if (edf_preemption_needed(edf, current)) | 441 | if (edf_preemption_needed(edf, current)) |
@@ -452,9 +469,9 @@ static struct sched_plugin psn_edf_plugin __cacheline_aligned_in_smp = { | |||
452 | .task_block = psnedf_task_block, | 469 | .task_block = psnedf_task_block, |
453 | #ifdef CONFIG_FMLP | 470 | #ifdef CONFIG_FMLP |
454 | .fmlp_active = 1, | 471 | .fmlp_active = 1, |
455 | .pi_block = psnedf_pi_block, | 472 | .fmlp_pi_block = psnedf_fmlp_pi_block, |
456 | .inherit_priority = psnedf_inherit_priority, | 473 | .fmlp_inherit_priority = psnedf_fmlp_inherit_priority, |
457 | .return_priority = psnedf_return_priority, | 474 | .fmlp_return_priority = psnedf_fmlp_return_priority, |
458 | #endif | 475 | #endif |
459 | .admit_task = psnedf_admit_task | 476 | .admit_task = psnedf_admit_task |
460 | }; | 477 | }; |