Linux waitqueues

In kernel 2.4.0-test11-pre3 the waitqueues and wakeup mechanisms were redesigned to remove the TASK_EXCLUSIVE bit from task_struct.state.  This was a good move, as that bit was inappropriate and led to various scenarios where wakeups could be lost.

There are still some shortcomings in the current design:
 

Initial measurements indicate that changing the accept() system call to use LIFO can speed up Apache by 5%-10%.

The approach taken in thes patches is to split the waitqueues by putting an extra list_head into the waitqueue structure.  So the waitqueue ring has two halves: exclusive tasks on the right, non-exclusive on the left. This adds another eight bytes to struct page, which takes it over 64 bytes.  That is a big problem.

This provides a good deal of symmetry, leading to the following API:

add_wait_queue_lifo(wait_queue_head_t *q, wait_queue_t * wait);

Adds a task non-exclusively to the wait queue.  It will receive LIFO semantics on wakeup.
add_wait_queue_fifo(wait_queue_head_t *q, wait_queue_t * wait);
Adds a task non-exclusively to the wait queue.  It will receive FIFO semantics on wakeup.
add_wait_queue_exclusive_lifo(wait_queue_head_t *q, wait_queue_t * wait);
Adds a task exclusively to the wait queue.  It will receive LIFO semantics on wakeup.
add_wait_queue_exclusive_fifo(wait_queue_head_t *q, wait_queue_t * wait);
Adds a task exclusively to the wait queue.  It will receive FIFO semantics on wakeup.
And, for existing "legacy" code:

#define add_wait_queue add_wait_queue_fifo
#define add_wait_queue_exclusive add_wait_queue_exclusive_fifo

This patch also cleans up a lot of cruft in wait.h and sched.c

Patches:

2.4.0-test11-pre3-task_exclusive.patch



AKPM Home
Andrew Morton, 12 Nov 2000