Chapter 14: Kernel Activities
list_add(&new->task_list, &head->task_list);
}
Nothing more need be done than to add the new task to the wait list using the standardlist_addlist
function.
add_wait_queue_exclusiveis also available. It works in the same way asadd_wait_queuebut inserts
the process at the queue tail and also sets its flag toWQ_EXCLUSIVE(what is behind this flag is discussed
below).
Another method to put a process to sleep on a wait queue isprepare_to_wait. In addition to the param-
eters required byadd_wait_queue, a task state is required as well:
kernel/wait.c
void fastcall
prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
{
unsigned long flags;
wait->flags &= ~WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
if (list_empty(&wait->task_list))
__add_wait_queue(q, wait);
...
set_current_state(state);
spin_unlock_irqrestore(&q->lock, flags);
}
After calling__add_wait_queueas discussed above, the kernel sets the current state of the process to the
state passed toprepare_to_wait.
prepare_to_wait_exclusiveis a variant that sets theWQ_FLAG_EXCLUSIVEflag and appends the wait
queue element to the queue tail.
Two standard methods are available to initialize a wait queue entry:
- init_waitqueue_entryinitializes a dynamically allocated instance ofwait_queue_t:
static inline void init_waitqueue_entry(wait_queue_t *q,
struct task_struct *p)
{
q->flags = 0;
q->private = p;
q->func = default_wake_function;
}
default_wake_functionis just a parameter conversion front end that attempts to wake the
process using thetry_to_wake_upfunction described in Chapter 2.