从 sleep_on() 到 wait_event()?

From sleep_on() to wait_event()?

我正在将遗留代码从 Linux 3.14 移植到 4.1。我需要将许多对 sleep_on() 函数的调用转换为对 wait_event() 函数的调用:

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

sleep_on() 函数已在内核 3.15 中删除,因为它们会导致竞争条件。

我的问题是理解使用 sleep_on() 函数的棘手代码并进行适当的更改、测试等需要花费很多时间,我需要尽快发布至少一个原型可能的。考虑一下我是一个 Linux 设备驱动程序新手。

您是否知道我可以使用一种模式将对 sleep_on() 函数的调用替换为对 wait_event() 函数的调用?例如,如果我只是将 sleep_on(&wait_queue) 替换为 wait_event(wait_queue, false),与遗留代码相比会有什么影响?结果会和遗留代码一样糟糕(可能有竞争条件),还是更糟?

提前感谢您的建议。

您可以定义 sleep_on 函数,因为它已在 3.15 之前的内核中定义。像这样:

void
sleep_on(wait_queue_head_t *q)
{
    unsigned long flags;
    wait_queue_t wait;

    init_waitqueue_entry(&wait, current);

    __set_current_state(TASK_UNINTERRUPTIBLE);

    spin_lock_irqsave(&q->lock, flags);
    __add_wait_queue(q, &wait);
    spin_unlock(&q->lock);
    schedule();
    spin_lock_irq(&q->lock);
    __remove_wait_queue(q, &wait);
    spin_unlock_irqrestore(&q->lock, flags);
}

(源自 sleep_on_common 的代码,但删除了超时内容。)

对于那些想在 kernel.org 上查看原始代码的人,请参阅 sleep_on_common() 并在 2014 年 4 月提交 32d01dc7be4e725ab85ce1d74e8f4adc02ad68dd(在删除该功能的前几天)。


至于wait_event()和朋友,使用常量条件是错误的:

  • 'true'永不眠
  • 'false'永远不会醒来