X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fwait.c;h=5cdf169d7c2317ff05298c7aa329bb6766554277;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=59a82f63275df037dd5bfb1062cffe317a698383;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/kernel/wait.c b/kernel/wait.c index 59a82f632..5cdf169d7 100644 --- a/kernel/wait.c +++ b/kernel/wait.c @@ -3,6 +3,7 @@ * * (C) 2004 William Irwin, Oracle */ +#include #include #include #include @@ -10,14 +11,6 @@ #include #include -void init_waitqueue_head(wait_queue_head_t *q) -{ - spin_lock_init(&q->lock); - INIT_LIST_HEAD(&q->task_list); -} - -EXPORT_SYMBOL(init_waitqueue_head); - void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) { unsigned long flags; @@ -40,13 +33,35 @@ void fastcall add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait) } EXPORT_SYMBOL(add_wait_queue_exclusive); -void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) +int fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) { unsigned long flags; + struct list_head *list; + int seen, retval; spin_lock_irqsave(&q->lock, flags); - __remove_wait_queue(q, wait); + list = &q->task_list; + seen = 0; + retval = -1; + + do { + struct list_head *next; + if (list == &wait->task_list) + seen++; + next = list->next; + if (next->prev != list) { + seen += 2; + break; + } + list = next; + } while (list != &q->task_list); + + if (seen == 1) { + __remove_wait_queue(q, wait); + retval = 0; + } spin_unlock_irqrestore(&q->lock, flags); + return retval; } EXPORT_SYMBOL(remove_wait_queue);