【问题标题】:Why only __add_wait_queue(q, wait) when wait is empty?为什么等待为空时只有 __add_wait_queue(q, wait) ?
【发布时间】:2020-12-07 04:46:40
【问题描述】:

https://elixir.bootlin.com/linux/v4.5/source/kernel/sched/wait.c#L172

void 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);
}

在上面的代码中,我们可以看到 __add_wait_queue(q, wait) 仅在 list_empty(&wait->task_list) 为真时执行。

为什么当&wait->task_list不为空时,那么wait就不需要加到q(wait_queue_head_t)了?

这是否意味着如果 wait (wait_queue_t) 已经在 q (wait_queue_head_t) 中,则不要更改它?

【问题讨论】:

    标签: linux kernel driver


    【解决方案1】:

    这是否意味着如果 wait (wait_queue_t) 已经在 q (wait_queue_head_t) 中,那么不要更改它?

    是的,分店

    if (list_empty(&wait->task_list))
        __add_wait_queue(q, wait);
    

    意味着,仅当 wait 不属于任何队列时,wait 才会添加到等待队列 @9​​87654325@。

    否则,如果确定wait已经属于(一些)等待队列,则假定wait具体属于q,不再添加。


    为一个对象调用list_empty 函数有一些特殊之处,它可以是列表的元素(不是列表的头部)。

    list_empty 总是返回 false,如果对象属于一个列表。

    但如果对象不属于任何列表,则返回值通常是未指定(大多数情况下也是false)。

    Exception 是一个对象,使用INIT_LIST_HEAD 函数或LIST_HEAD_INIT 宏初始化或使用list_del_init 函数从列表中删除:在这种情况下list_empty 返回true 并保证。 p>

    如果在wait.h标头中查找INIT_LIST_HEADLIST_HEAD_INITlist_del_init的用法,则可以发现prepare_to_wait函数允许仅适用于@987654341 @对象:

    1. 使用DEFINE_WAIT 宏或DEFINE_WAIT_* 宏之一创建。
    2. 使用init_wait 函数初始化,例如调用来自wait_event_* 宏之一。
    3. 已传递给finish_wait 函数。

    但是prepare_to_wait函数不能用于wait对象,用DECLARE_WAITQUEUE宏创建:这个宏用{NULL, NULL}初始化task_list字段,所以list_empty会为它返回 false(就好像等待对象已经添加到等待队列中一样)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 1970-01-01
      • 2022-01-21
      相关资源
      最近更新 更多