From 12487168052ed51bb516ecc7d42be19f8eae420a Mon Sep 17 00:00:00 2001 From: Glenn Elliott Date: Mon, 12 Jul 2010 15:44:38 -0400 Subject: P-EDF updated to use the generic pi framework. 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. --- litmus/sched_psn_edf.c | 65 +++++++++++++++++++++++++++++++------------------- 1 file 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 @@ #include #include +#ifdef CONFIG_FMLP +#include +#endif typedef struct { rt_domain_t domain; @@ -307,9 +310,10 @@ static void psnedf_task_exit(struct task_struct * t) } #ifdef CONFIG_FMLP -static long psnedf_pi_block(struct pi_semaphore *sem, - struct task_struct *new_waiter) +static long psnedf_fmlp_pi_block(struct pi_semaphore *_sem, + struct task_struct *new_waiter) { + struct fmlp_semaphore *sem = to_fmlp(_sem); psnedf_domain_t* pedf; rt_domain_t* edf; struct task_struct* t; @@ -317,7 +321,7 @@ static long psnedf_pi_block(struct pi_semaphore *sem, BUG_ON(!new_waiter); - if (edf_higher_prio(new_waiter, sem->hp.cpu_task[cpu])) { + if (edf_higher_prio(new_waiter, sem->pi.hp.cpu_task[cpu])) { TRACE_TASK(new_waiter, " boosts priority\n"); pedf = task_pedf(new_waiter); edf = task_edf(new_waiter); @@ -326,11 +330,13 @@ static long psnedf_pi_block(struct pi_semaphore *sem, raw_spin_lock(&pedf->slock); /* store new highest-priority task */ - sem->hp.cpu_task[cpu] = new_waiter; + sem->pi.hp.cpu_task[cpu] = new_waiter; if (sem->holder && get_partition(sem->holder) == get_partition(new_waiter)) { + /* let holder inherit */ - sem->holder->rt_param.inh_task = new_waiter; + sem->holder->rt_param.eff_priority = new_waiter; + t = sem->holder; if (is_queued(t)) { /* queued in domain*/ @@ -354,21 +360,28 @@ static long psnedf_pi_block(struct pi_semaphore *sem, return 0; } -static long psnedf_inherit_priority(struct pi_semaphore *sem, - struct task_struct *new_owner) +static long psnedf_fmlp_inherit_priority(struct pi_semaphore *_sem, + struct task_struct *new_owner) { + struct fmlp_semaphore *sem = to_fmlp(_sem); int cpu = get_partition(new_owner); - new_owner->rt_param.inh_task = sem->hp.cpu_task[cpu]; - if (sem->hp.cpu_task[cpu] && new_owner != sem->hp.cpu_task[cpu]) { + if (sem->pi.hp.cpu_task[cpu] && new_owner != sem->pi.hp.cpu_task[cpu]) { + new_owner->rt_param.eff_priority = sem->pi.hp.cpu_task[cpu]; TRACE_TASK(new_owner, "inherited priority from %s/%d\n", - sem->hp.cpu_task[cpu]->comm, - sem->hp.cpu_task[cpu]->pid); - } else + sem->pi.hp.cpu_task[cpu]->comm, + sem->pi.hp.cpu_task[cpu]->pid); + } + else + { + /* inherit "self" to remain consistent with pi_sem_stack model. */ + new_owner->rt_param.eff_priority = new_owner; TRACE_TASK(new_owner, "cannot inherit priority: " "no higher priority job waits on this CPU!\n"); + } + /* make new owner non-preemptable as required by FMLP under * PSN-EDF. */ @@ -380,8 +393,9 @@ static long psnedf_inherit_priority(struct pi_semaphore *sem, /* This function is called on a semaphore release, and assumes that * the current task is also the semaphore holder. */ -static long psnedf_return_priority(struct pi_semaphore *sem) +static long psnedf_fmlp_return_priority(struct pi_semaphore *_sem) { + struct fmlp_semaphore* sem = to_fmlp(_sem); struct task_struct* t = current; psnedf_domain_t* pedf = task_pedf(t); rt_domain_t* edf = task_edf(t); @@ -389,13 +403,12 @@ static long psnedf_return_priority(struct pi_semaphore *sem) int cpu = get_partition(current); int still_np; - /* Find new highest-priority semaphore task * if holder task is the current hp.cpu_task[cpu]. * * Calling function holds sem->wait.lock. */ - if (t == sem->hp.cpu_task[cpu]) + if (t == sem->pi.hp.cpu_task[cpu]) edf_set_hp_cpu_task(sem, cpu); still_np = take_np(current); @@ -404,12 +417,16 @@ static long psnedf_return_priority(struct pi_semaphore *sem) * should always be zero */ BUG_ON(still_np); - if (current->rt_param.inh_task) { + + if (current->rt_param.eff_priority && + (current->rt_param.eff_priority != current)) { TRACE_CUR("return priority of %s/%d\n", - current->rt_param.inh_task->comm, - current->rt_param.inh_task->pid); - } else + current->rt_param.eff_priority->comm, + current->rt_param.eff_priority->pid); + } + else { TRACE_CUR(" no priority to return %p\n", sem); + } /* Always check for delayed preemptions that might have become @@ -417,8 +434,8 @@ static long psnedf_return_priority(struct pi_semaphore *sem) */ raw_spin_lock(&pedf->slock); - /* Reset inh_task to NULL. */ - current->rt_param.inh_task = NULL; + /* Reset eff_priority to NULL since we don't hold the lock. */ + current->rt_param.eff_priority = NULL; /* check if we need to reschedule */ if (edf_preemption_needed(edf, current)) @@ -452,9 +469,9 @@ static struct sched_plugin psn_edf_plugin __cacheline_aligned_in_smp = { .task_block = psnedf_task_block, #ifdef CONFIG_FMLP .fmlp_active = 1, - .pi_block = psnedf_pi_block, - .inherit_priority = psnedf_inherit_priority, - .return_priority = psnedf_return_priority, + .fmlp_pi_block = psnedf_fmlp_pi_block, + .fmlp_inherit_priority = psnedf_fmlp_inherit_priority, + .fmlp_return_priority = psnedf_fmlp_return_priority, #endif .admit_task = psnedf_admit_task }; -- cgit v1.2.2