world leader in high performance signal processing
Trace: » wait_queues

Wait Queues

The Wait Queue mechanism is the main method for one process to tell another process that it can continue running.

For example An I/O Read Process is waiting for data to arrive. It suspends itself on a wait queue. When the I/O Device receives data it wakes up any tasks waiting for the data.

If you have more than one task waiting for the data then you have to stop one task “stealing” data for the other task.

Most device drivers use this process to handle I/O events.

Here is an example of setting up, suspending and waking a task on a wait queue

#include <linux/wait.h>
 
// wait queues
static wait_queue_head_t myreadq;
static wait_queue_head_t mywriteq;
 
 
 
    // inside the module_init function
    init_waitqueue_head(&myreadq); 
    init_waitqueue_head(&mywriteq);
................................................................. 
   //inside the read function
   ...
   if ( wait_event_interruptible( myreadq, (bytes_read <= bytes_in))) {
            printk(" read signal ...\n");
            return -ERESTARTSYS;
        }
    // read count bytes from the device                         
    space_left+=count;
    bytes_read+=count;
 
    //wake up any writers we now have space
    wake_up_interruptible(&mywriteq);
 
................................................................. 
    //inside the write function
    if ( wait_event_interruptible( mywriteq, (bytes_in >= space_left))) {
            return -ERESTARTSYS;
        }
    // once we have space write bytes
    space_left-=count;
    bytes_in+=count;
 
    //wake up any readers 
    wake_up_interruptible(&myreadq);
 
................................................................. 
    // or if data arrives via an Interrupt
 
    space_left-=count;
    bytes_in+=count;
 
 
    //wake up any readers 
    wake_up_interruptible(&myreadq);

Exclusive Functions

When a wait queue is “woken up” all tasks on the wait queue are enabled for the scheduler. If a task is added to a wait queue using an exclusive function then the wake up call will only wake up one exclusive task leaving the others still waiting. If a mixture of exclusive tasks and non exclusive tasks are added to the queue then the wake up function will wake up any non exclusive tasks until it wakes up the exclusive task. The wakeup order is normally the reverse of the order in which tasks are added to the queue.

Bit Functions

These functions allow the user to wait / wake up on the value of a designated bit in a word. The combination of the word address plus the bit number is used to pick a queue from a hash tabel for the task to wait on. The corresponding wake up call only needs to refer to the word address and the bit. The bit should be cleared before the wakeup will succeed.

Sync Functions

Thes options can be used when you do not want the scheduler called when waking up the task. The rules are that you can wake up “sync” but you have to agree to call the scheduler yourself.

Interruptible Functions

These do NOT refer to interrupts. An UNINTERRUPTIBLE task will not respond to signals whereas an INTERRUPTIBLE task will return early from a wait request should it get a signal.

Out of Line Functions

A lot of kernel functions are inserted inline into the calling function. Out of Line functions are avaialble should you wish to explicitly call the function.

Other Kernel wait queue functions

add_wait_queue_exclusive
remove_wait_queue
prepare_to_waithelper function to set up a process to wait for a condition
prepare_to_wait_exclusive
finish_waitclean up after a prepare_to_wait
wait_on_bitgiven a word and a bit number wait until the bit is cleared
out_of_line_wait_on_bitsame but not inlined
wait_on_bit_lock
out_of_line_wait_on_bit_lock
wake_up_bitwake up a task waiting on a bit
wake_up_exclusivewake all the non-exclusive tasks and one exclusive task