2017-06-30 43 views
0

我將從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),與傳統代碼相比會有什麼影響?結果會和遺留代碼一樣糟糕嗎(可能有競爭條件),或者更糟?

在此先感謝您的建議。

回答

1

您可以定義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()和朋友,用一定的條件是錯誤的:

  • '真' 永遠不會睡覺
  • '假' 永遠不會醒來