日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux kernel中的wait_for_completion和complete总结

發布時間:2025/3/21 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux kernel中的wait_for_completion和complete总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

快速鏈接:
.
👉👉👉 個人博客筆記導讀目錄(全部) 👈👈👈

文章目錄

        • 結構體
        • init_completion
        • complete
        • wait_for_completion
        • wait_for_completion的相關API

  • 在wait_for_completion時,先將x->wait加入到等待隊列,在檢查done的值,如果為0 ,則死循環卡住。推出循環后,則done–;
  • 在complete時,先done++,在wake_up(x->wait)等待隊列
    注意done–的最小值和done++的最大值都是(~0U)

結構體

struct completion {unsigned int done;wait_queue_head_t wait; };#define UINT_MAX (~0U)

init_completion

#define init_completion(x) __init_completion(x)static inline void __init_completion(struct completion *x) {x->done = 0;init_waitqueue_head(&x->wait); }

complete

void complete(struct completion *x) {unsigned long flags;spin_lock_irqsave(&x->wait.lock, flags);if (x->done != UINT_MAX)x->done++;__wake_up_locked(&x->wait, TASK_NORMAL, 1);spin_unlock_irqrestore(&x->wait.lock, flags); } EXPORT_SYMBOL(complete);

wait_for_completion

wait_for_completion --> wait_for_common --> do_wait_for_common

void __sched wait_for_completion(struct completion *x) {wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE); } EXPORT_SYMBOL(wait_for_completion);static long __sched wait_for_common(struct completion *x, long timeout, int state) {return __wait_for_common(x, schedule_timeout, timeout, state); }static inline long __sched __wait_for_common(struct completion *x,long (*action)(long), long timeout, int state) {might_sleep();complete_acquire(x);spin_lock_irq(&x->wait.lock);timeout = do_wait_for_common(x, action, timeout, state);spin_unlock_irq(&x->wait.lock);complete_release(x);return timeout; }static inline long __sched do_wait_for_common(struct completion *x,long (*action)(long), long timeout, int state) {if (!x->done) {DECLARE_WAITQUEUE(wait, current);__add_wait_queue_entry_tail_exclusive(&x->wait, &wait);do {if (signal_pending_state(state, current)) {timeout = -ERESTARTSYS;break;}__set_current_state(state);spin_unlock_irq(&x->wait.lock);timeout = action(timeout);spin_lock_irq(&x->wait.lock);} while (!x->done && timeout);__remove_wait_queue(&x->wait, &wait);if (!x->done)return timeout;}if (x->done != UINT_MAX)x->done--;return timeout ?: 1; }

wait_for_completion的相關API

wait_for_completion
wait_for_completion_timeout
wait_for_completion_interruptible
wait_for_completion_killable
wait_for_completion_killable_timeout
wait_for_completion_io
wait_for_common_io

TASK_UNINTERRUPTIBLE
TASK_INTERRUPTIBLE
TASK_KILLABLE

默認等待時間為MAX_SCHEDULE_TIMEOUT=LONG_MAX,也就是等于一個最大的數字((long)(~0UL >> 1)) = 9223372036854775807 void __sched wait_for_completion(struct completion *x) {wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE); }unsigned long __sched wait_for_completion_timeout(struct completion *x, unsigned long timeout) {return wait_for_common(x, timeout, TASK_UNINTERRUPTIBLE); }int __sched wait_for_completion_interruptible(struct completion *x) {long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);if (t == -ERESTARTSYS)return t;return 0; }long __sched wait_for_completion_interruptible_timeout(struct completion *x,unsigned long timeout) {return wait_for_common(x, timeout, TASK_INTERRUPTIBLE); }int __sched wait_for_completion_killable(struct completion *x) {long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_KILLABLE);if (t == -ERESTARTSYS)return t;return 0; }long __sched wait_for_completion_killable_timeout(struct completion *x,unsigned long timeout) {return wait_for_common(x, timeout, TASK_KILLABLE); }void __sched wait_for_completion_io(struct completion *x) {wait_for_common_io(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE); }unsigned long __sched wait_for_completion_io_timeout(struct completion *x, unsigned long timeout) {return wait_for_common_io(x, timeout, TASK_UNINTERRUPTIBLE); }

wait_for_common和wait_for_common_io的區別,區別在于schedule_timeout和io_schedule_timeout變量,這兩個變量是指向函數的指針

static long __sched wait_for_common(struct completion *x, long timeout, int state) {return __wait_for_common(x, schedule_timeout, timeout, state); }static long __sched wait_for_common_io(struct completion *x, long timeout, int state) {return __wait_for_common(x, io_schedule_timeout, timeout, state); }

下方的action(timeout),其實就是在調用schedule_timeout(xxx)或io_schedule_timeout(xxx)

static inline long __sched do_wait_for_common(struct completion *x,long (*action)(long), long timeout, int state) {if (!x->done) {DECLARE_WAITQUEUE(wait, current);__add_wait_queue_entry_tail_exclusive(&x->wait, &wait);do {if (signal_pending_state(state, current)) {timeout = -ERESTARTSYS;break;}__set_current_state(state);spin_unlock_irq(&x->wait.lock);timeout = action(timeout);spin_lock_irq(&x->wait.lock);} while (!x->done && timeout);__remove_wait_queue(&x->wait, &wait);if (!x->done)return timeout;}if (x->done != UINT_MAX)x->done--;return timeout ?: 1; }

總結

以上是生活随笔為你收集整理的linux kernel中的wait_for_completion和complete总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。