从sleep_on()到wait_event()?
问题描述:
我将从Linux 3.14移植到4.1的遗留代码。有几十个电话来sleep_on()
功能,我需要转换为调用wait_event()
功能:从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设备驱动程序新手。
您是否知道我可以用来通过调用wait_event()
函数来替换对sleep_on()
函数调用的模式?例如,如果我只用wait_event(wait_queue, false)
替换sleep_on(&wait_queue)
,与传统代码相比会有什么影响?结果会和遗留代码一样糟糕吗(可能有竞争条件),或者更糟?
在此先感谢您的建议。
答
您可以定义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()
和朋友,用一定的条件是错误的:
- '真' 永远不会睡觉
- '假' 永远不会醒来