Linux wait queue details

Source: Internet
Author: User
#include <linux/wait.h> typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key);struct __wait_queue_head {    spinlock_t lock;    struct list_head task_list;};typedef struct __wait_queue_head wait_queue_head_t; #define __WAITQUEUE_INITIALIZER(name, tsk) {                \    .private    = tsk,                        \    .func        = default_wake_function,            \    .task_list    = { NULL, NULL } } #define DECLARE_WAITQUEUE(name, tsk)                    \    wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) #define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                \    .lock        = __SPIN_LOCK_UNLOCKED(name.lock),        \    .task_list    = { &(name).task_list, &(name).task_list } } #define DECLARE_WAIT_QUEUE_HEAD(name) \    wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) #define __WAIT_BIT_KEY_INITIALIZER(word, bit)                \    { .flags = word, .bit_nr = bit, } extern void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *); #define init_waitqueue_head(q)                \    do {                        \        static struct lock_class_key __key;    \                            \        __init_waitqueue_head((q), &__key);    \    } while (0) void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *key){    spin_lock_init(&q->lock);    lockdep_set_class(&q->lock, key);    INIT_LIST_HEAD(&q->task_list);} 

Operation:

1. Define "waiting queue Header"

wait_queue_head_t my_queue;

2. initialize "waiting queue Header"

init_waitqueue_head(&my_queue);

In addition, the declare_wait_queue_head (name) macro can define and initialize the waiting queue header.

#define DECLARE_WAIT_QUEUE_HEAD(name) \    wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                \    .lock        = __SPIN_LOCK_UNLOCKED(name.lock),        \    .task_list    = { &(name).task_list, &(name).task_list } }

3. Define a waiting queue

DECLARE_WAITQUEUE(name, tsk)

Tsk is currently in progress. This macro defines and initializes a waiting queue named name.

#define DECLARE_WAITQUEUE(name, tsk)                    \    wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)#define __WAITQUEUE_INITIALIZER(name, tsk) {                \    .private    = tsk,                        \    .func        = default_wake_function,            \    .task_list    = { NULL, NULL } }

In this case, private will be used in wake_up () and its variants, and the default_wake_function () function will be called by default. This function is actually try_to_wake_up (curr-> private, mode, wake_flags );

/*** * try_to_wake_up - wake up a thread * @p: the to-be-woken-up thread * @state: the mask of task states that can be woken * @sync: do a synchronous wakeup? * * Put it on the run-queue if it's not already there. The "current" * thread is always on the run-queue (except when the actual * re-schedule is in progress), and as such you're allowed to do * the simpler "current->state = TASK_RUNNING" to mark yourself * runnable without the overhead of this. * * returns failure only if the task is already active. */static int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags);

4. Add/delete a waiting queue

void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);

5. Wait for the event

wait_event(wq, condition)wait_event_timeout(wq, condition, timeout)wait_event_interruptible(wq, condition)wait_event_interruptible_timeout(wq, condition, timeout)

6. Wake up the waiting queue

#define wake_up(x)            __wake_up(x, TASK_NORMAL, 1, NULL)#define wake_up_nr(x, nr)        __wake_up(x, TASK_NORMAL, nr, NULL)#define wake_up_all(x)            __wake_up(x, TASK_NORMAL, 0, NULL)#define wake_up_locked(x)        __wake_up_locked((x), TASK_NORMAL) #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)#define wake_up_interruptible_sync(x)    __wake_up_sync((x), TASK_INTERRUPTIBLE, 1) /** * __wake_up - wake up threads blocked on a waitqueue. * @q: the waitqueue * @mode: which threads * @nr_exclusive: how many wake-one or wake-many threads to wake up * @key: is directly passed to the wakeup function * * It may be assumed that this function implies a write memory barrier before * changing the task state if and only if any tasks are woken up. */void __wake_up(wait_queue_head_t *q, unsigned int mode,            int nr_exclusive, void *key){    unsigned long flags;     spin_lock_irqsave(&q->lock, flags);    __wake_up_common(q, mode, nr_exclusive, 0, key);    spin_unlock_irqrestore(&q->lock, flags);}

7. Waiting for sleep in the queue

void __sched sleep_on(wait_queue_head_t *q)long __sched sleep_on_timeout(wait_queue_head_t *q, long timeout);void __sched interruptible_sleep_on(wait_queue_head_t *q);long __sched interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout);#define __sched        __attribute__((__section__(".sched.text")))

Sleep_on () function should be used in pairs with wake_up (), and interrupt_sleep_on () should be used in pairs with wake_up_interruptible ()

#include <linux/wait.h> 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.