Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 14: Kernel Activities


When the condition if fulfilled,finish_waitsets the task state back toTASK_RUNNINGand removes the
entry from the wait queue list.^18

In addition towait_event, the kernel defines several other functions to place the current process in a
wait queue. Their implementation is practically identical to that ofsleep_on:

<wait.h>
#define wait_event_interruptible(wq, condition)
#define wait_event_timeout(wq, condition, timeout) { ... }
#define wait_event_interruptible_timeout(wq, condition, timeout)

❑ wait_event_interruptibleuses theTASK_INTERRUPTIBLEtask state. The sleeping process can
therefore be woken up by receiving a signal.

❑ wait_event_timeoutwaits for the specified condition to be fulfilled, but stops waiting after a
time-out specified in jiffies. This prevents a process from sleeping for ever.

❑ wait_event_interruptible_timeoutputs the process to sleep so that it can be woken up by
receiving a signal. It also registers a time-out. Kernel nomenclature is usually not a place for
surprises!

Additionally the kernel defines a number of deprecated functions (sleep_on,sleep_on_timeout,
interruptible_sleep_on,andinterruptible_sleep_on_timeout) that are deprecated and not
supposed to be used in new code anymore. They still sit around for compatibility purposes.

Waking Processes


The kernel defines a series of macros that are used to wake the processes in a wait queue. They are all
based on the same function:


#define wake_up(x) __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, NULL)
#define wake_up_nr(x, nr) __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr, NULL)
#define wake_up_all(x) __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0, NULL)
#define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
#define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL)
#define wake_up_interruptible_all(x) __wake_up(x, TASK_INTERRUPTIBLE, 0, NULL)
__wake_updelegates work to__wake_up_commonafter acquiring the necessary lock of the wait queue
head.

kernel/sched.c
static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, int sync, void *key)
{
wait_queue_t *curr, *next;
...

(^18) However, some care is required when doing this becausefinished_waitis invoked from many places and the task could have
been removed by the wake-up function. However, the kernel manages to get everything right by careful manipulation of the list
elements.

Free download pdf