Wait Queue:
In Linux driver programming, waiting queues can be used to implement blocking of processes.
The wait queue can be thought of as a container for the save process, and the process is placed in a wait queue when the process is blocked;
When the process is awakened, the process is fetched from the wait queue.
waiting for the definition and initialization of the queue wait_queue_head_t Declare_wait_queue_head:
The Linux 2.6 kernel provides the following actions on waiting queues:
1, define the wait queue.
wait_queue_head_t My_queue
2, initialize the wait queue.
Init_waitqueue_head (&my_queue)
3, define and initialize the wait queue.
Declare_wait_queue_head (My_queue)
wait for the queue's sleep wait_event_interruptible: Conditional sleep:
1, wait_event (queue, condition)
When condition (a Boolean expression) is true, immediately returns; otherwise let the process enter the task_uninterruptible mode
Sleep and hangs on the wait queue specified by the queue parameter.
2, wait_event_interruptible (queue, condition)
When condition (a Boolean expression) is true, immediately returns; otherwise let the process enter the task_interruptible mode
Sleep and hangs on the wait queue specified by the queue parameter.
3, int wait_event_killable (wait_queue_t queue, condition)
When condition (a Boolean expression) is true, immediately returns; otherwise let the process enter the task_killable mode
Sleep and hangs on the wait queue specified by the queue parameter.
Unconditional sleep:
(old version, not recommended)
sleep_on (wait_queue_head_t *q)
Let the process into an uninterrupted sleep and put it into the wait queue Q.
interruptible_sleep_on (wait_queue_head_t *q)
Let the process into interruptible sleep and put it into the wait queue Q.
wait in queue to wake process wake_up:
WAKE_UP (wait_queue_t *q)
wake-up status from wait queue Q is taskuninterruptible, task_interruptible, task_killable
of all processes.
Wake_up_interruptible (wait_queue_t *q)
The process that wakes the state as task_interruptible from the wait queue Q.
Instance---key driver optimization:
An example is listed below to facilitate understanding and the use of wait queues:
For example, when we write the key driver, our application uses while (1) to read the key value , so that the CPU consumption is too large;
So we use the wait queue to optimize the key driver:
first define and initialize the wait queue:
Define and initialize the wait queue Declare_wait_queue_head at the beginning of the program:
Static Declare_wait_queue_head (BUTTON_WAITQ);
and define a static volatile variable:
static volatile int ev_press = 0;
then wait for the queue to sleep in the Read method:
When the button is pressed, read the key value;
Wait for queue sleep sleep wait_event_interruptible when no key is pressed :
static int tq2440_irq_read (struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
unsigned long err;< C5/>if (!ev_press)
{
if (Filp->f_flags & O_nonblock)
Return-eagain;
else
wait_event_interruptible (BUTTON_WAITQ, ev_press);
}
ev_press = 0;
Err = Copy_to_user (buff, (const void *) key_values, min (sizeof (key_values), count));
return err? -efault:min (sizeof (key_values), count);
}
to wake up the wait queue in the Interrupt service program:
Wake up wait queue wake_up_interruptible in Interrupt service program:
When the key is pressed, enter the interrupt service program, which will wait for the queue to wake up:
static irqreturn_t irq_interrupt (int irq, void *dev_id)
{
struct button_irq_desc *button_irqs = (struct button_ Irq_desc *) dev_id;
int down;
Down =!s3c2410_gpio_getpin (button_irqs->pin);
if (Down!= (Key_values[button_irqs->number] & 1))
{
Key_values[button_irqs->number] = ' 0 ' + down;
ev_press = 1;
Wake_up_interruptible (&BUTTON_WAITQ);
}
Return Irq_retval (irq_handled);
}
determine whether the wait queue is sleep or read the key value immediately by judging the value of the static volatile int ev_press variable.
To Test---key driver: 1,insmod Drive;
2, run the test application in the background:
3,ps command to view application status:
Buttons stat state for sleep;
4,cat/proc/interrupts orders to see whether interrupts are applied:
See the interruption of each key has not been applied key1-4:
5, test key: