From 0f6a8e02773f8c23b5b6a3dbfa044e50c9d7d811 Mon Sep 17 00:00:00 2001 From: Glenn Elliott Date: Thu, 31 Mar 2011 10:47:01 -0400 Subject: Improve FMLP queue management. The next owner of a FMLP-protected resource is dequeued from the FMLP FIFO queue by unlock() (when the resource is freed by the previous owner) instead of performing the dequeue by the next owner immediately after it has been woken up. This simplifies the code a little bit and also reduces potential spinlock contention. --- include/litmus/litmus.h | 2 +- litmus/locking.c | 12 +++++++----- litmus/sched_gsn_edf.c | 4 +--- litmus/sched_psn_edf.c | 6 +----- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index 94086e2b38db..e7769ca36ec0 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h @@ -26,7 +26,7 @@ static inline int in_list(struct list_head* list) ); } -struct task_struct* waitqueue_first(wait_queue_head_t *wq); +struct task_struct* __waitqueue_remove_first(wait_queue_head_t *wq); #define NO_CPU 0xffffffff diff --git a/litmus/locking.c b/litmus/locking.c index 728b56835cf7..2693f1aca859 100644 --- a/litmus/locking.c +++ b/litmus/locking.c @@ -107,16 +107,18 @@ asmlinkage long sys_litmus_unlock(int lock_od) return err; } -struct task_struct* waitqueue_first(wait_queue_head_t *wq) +struct task_struct* __waitqueue_remove_first(wait_queue_head_t *wq) { - wait_queue_t *q; + wait_queue_t* q; + struct task_struct* t = NULL; if (waitqueue_active(wq)) { q = list_entry(wq->task_list.next, wait_queue_t, task_list); - return (struct task_struct*) q->private; - } else - return NULL; + t = (struct task_struct*) q->private; + __remove_wait_queue(wq, q); + } + return(t); } diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c index c5c9600c33d8..08b8847ede97 100644 --- a/litmus/sched_gsn_edf.c +++ b/litmus/sched_gsn_edf.c @@ -776,8 +776,6 @@ int gsnedf_fmlp_lock(struct litmus_lock* l) * ->owner. We can thus check it without acquiring the spin * lock. */ BUG_ON(sem->owner != t); - - remove_wait_queue(&sem->wait, &wait); } else { /* it's ours now */ sem->owner = t; @@ -803,7 +801,7 @@ int gsnedf_fmlp_unlock(struct litmus_lock* l) } /* check if there are jobs waiting for this resource */ - next = waitqueue_first(&sem->wait); + next = __waitqueue_remove_first(&sem->wait); if (next) { /* next becomes the resouce holder */ sem->owner = next; diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c index abb06fa53e3a..71c02409efa2 100644 --- a/litmus/sched_psn_edf.c +++ b/litmus/sched_psn_edf.c @@ -442,10 +442,6 @@ int psnedf_fmlp_lock(struct litmus_lock* l) * ->owner. We can thus check it without acquiring the spin * lock. */ BUG_ON(sem->owner != t); - - /* FIXME: could we punt the dequeuing to the previous job, - * which is holding the spinlock anyway? */ - remove_wait_queue(&sem->wait, &wait); } else { /* it's ours now */ sem->owner = t; @@ -478,7 +474,7 @@ int psnedf_fmlp_unlock(struct litmus_lock* l) unboost_priority(t); /* check if there are jobs waiting for this resource */ - next = waitqueue_first(&sem->wait); + next = __waitqueue_remove_first(&sem->wait); if (next) { /* boost next job */ boost_priority(next); -- cgit v1.2.2