diff options
| author | Rusty Russell <rusty@rustcorp.com.au> | 2002-06-05 19:30:17 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-06-05 19:30:17 -0700 |
| commit | 8a9b07a2a23851c8207a25e9dcb2dfd91fed3230 (patch) | |
| tree | 80c1748c655558ece8f30f54e7fd55f029b59722 /kernel/futex.c | |
| parent | 5a13e2bf1acb12cbe27b6ee02198ef444e01a49b (diff) | |
[PATCH] Futex update IV: use a waitqueue.
This turns the simple task pointer into a waitqueue, which is
needed for the poll() patch.
Diffstat (limited to 'kernel/futex.c')
| -rw-r--r-- | kernel/futex.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index a91d8ee276a4..bdff307969ef 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -45,7 +45,7 @@ the relevent ones (hashed queues may be shared) */ struct futex_q { struct list_head list; - struct task_struct *task; + wait_queue_head_t waiters; /* Page struct and offset within it. */ struct page *page; unsigned int offset; @@ -65,6 +65,11 @@ static inline struct list_head *hash_futex(struct page *page, return &futex_queues[hash_long(h, FUTEX_HASHBITS)]; } +static inline void tell_waiter(struct futex_q *q) +{ + wake_up_all(&q->waiters); +} + static int futex_wake(struct list_head *head, struct page *page, unsigned int offset, @@ -79,7 +84,7 @@ static int futex_wake(struct list_head *head, if (this->page == page && this->offset == offset) { list_del_init(i); - wake_up_process(this->task); + tell_waiter(this); num_woken++; if (num_woken >= num) break; } @@ -90,11 +95,12 @@ static int futex_wake(struct list_head *head, /* Add at end to avoid starvation */ static inline void queue_me(struct list_head *head, + wait_queue_t *wait, struct futex_q *q, struct page *page, unsigned int offset) { - q->task = current; + add_wait_queue(&q->waiters, wait); q->page = page; q->offset = offset; @@ -146,10 +152,11 @@ static int futex_wait(struct list_head *head, { int curval; struct futex_q q; + DECLARE_WAITQUEUE(wait, current); int ret = 0; set_current_state(TASK_INTERRUPTIBLE); - queue_me(head, &q, page, offset); + queue_me(head, &wait, &q, page, offset); /* Page is pinned, but may no longer be in this address space. */ if (get_user(curval, uaddr) != 0) { |
