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:
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