wait queue 4

来源:互联网 发布:建造者模式知乎 编辑:程序博客网 时间:2024/05/12 08:34
还有一种wait queue是用来判断某个bit是否为0,我们以下面的函数为例
static void __inode_wait_for_writeback(struct inode *inode)
    __releases(inode->i_lock)
    __acquires(inode->i_lock)
{
    DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC);
    wait_queue_head_t *wqh;

    wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
    while (inode->i_state & I_SYNC) {
        spin_unlock(&inode->i_lock);
        __wait_on_bit(wqh, &wq, bit_wait,
                  TASK_UNINTERRUPTIBLE);
        spin_lock(&inode->i_lock);
    }
}
首先定义DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC);
然后得到wait_queue_head_t
    wait_queue_head_t *wqh;

    wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
最后就等待这个__I_SYNC 变为0
    while (inode->i_state & I_SYNC) {
        spin_unlock(&inode->i_lock);
        __wait_on_bit(wqh, &wq, bit_wait,
                  TASK_UNINTERRUPTIBLE);
        spin_lock(&inode->i_lock);
    }
 
int __sched
__wait_on_bit(wait_queue_head_t *wq, struct wait_bit_queue *q,
          wait_bit_action_f *action, unsigned mode)
{
    int ret = 0;

    do {
        prepare_to_wait(wq, &q->wait, mode);
        if (test_bit(q->key.bit_nr, q->key.flags))
            ret = (*action)(&q->key, mode);
    } while (test_bit(q->key.bit_nr, q->key.flags) && !ret);
    finish_wait(wq, &q->wait);
    return ret;
}
以__wait_on_bit 为例,就是判断inode->i_state的bit7 是否为0,如果为1,就继续执行action函数后继续等待,而这里的action函数
__sched int bit_wait(struct wait_bit_key *word, int mode)
{
    schedule();
    if (signal_pending_state(mode, current))
        return -EINTR;
    return 0;
}
可以看出只是让出cpu,且不处理signal.
后面需要通过wake_up_bit(&inode->i_state, __I_SYNC); 来wakeup task.
void wake_up_bit(void *word, int bit)
{
    __wake_up_bit(bit_waitqueue(word, bit), word, bit);
}
__wake_up_bit 就会调用__wake_up 函数,就和前面讲的wait queue flow是一样的了
void __wake_up_bit(wait_queue_head_t *wq, void *word, int bit)
{
    struct wait_bit_key key = __WAIT_BIT_KEY_INITIALIZER(word, bit);
    if (waitqueue_active(wq))
        __wake_up(wq, TASK_NORMAL, 1, &key);
}

这里额外提一下    struct wait_bit_key key = __WAIT_BIT_KEY_INITIALIZER(word, bit);
所谓的wait_bit_key中的flag就是要监控的变量,bit_nr 就是这个变量的某个bit,以int为例就是要监控32 bit中的第7个bit是否为0(假定bit_nr==7)
#define __WAIT_BIT_KEY_INITIALIZER(word, bit)                \
    { .flags = word, .bit_nr = bit, }

0 0
原创粉丝点击