wait_event

Linux中是怎样实现wait 一个事件的?

1】定义一个wait queue head

static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);


2】等待某个事件,当wakeup waitqueue时判断这个事件,也就是condition: a C expression for the event to wait for

struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
{
    struct tty_ldisc *ld;

    /* wait_event is a macro */
    wait_event(tty_ldisc_wait, (ld = tty_ldisc_try(tty)) != NULL);
    return ld;
}


3】唤醒waitqueue

void tty_ldisc_enable(struct tty_struct *tty)
{
    set_bit(TTY_LDISC, &tty->flags);
    clear_bit(TTY_LDISC_CHANGING, &tty->flags);
    wake_up(&tty_ldisc_wait);
}

wait event 实现的原理

/**
 * wait_event - sleep until a condition gets true
 * @wq: the waitqueue to wait on
 * @condition: a C expression for the event to wait for
 *
 * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the
 * @condition evaluates to true. The @condition is checked each time
 * the waitqueue @wq is woken up.
 *
 * wake_up() has to be called after changing any variable that could
 * change the result of the wait condition.
 */
#define wait_event(wq, condition)                     \
do {                                    \
    if (condition)                             \
        break;                            \
    __wait_event(wq, condition);                    \
} while (0)

#define __wait_event(wq, condition)                     \
do {                                    \
    DEFINE_WAIT(__wait);                        \
                                    \
    for (;;) {                            \
        prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
        if (condition)                        \
            break;                        \
        schedule();                        \
    }                                \
    finish_wait(&wq, &__wait);                    \
} while (0)



你可能感兴趣的:(wait_event)