歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux源碼分析:completion的解讀

Linux源碼分析:completion的解讀

日期:2017/2/28 15:56:12   编辑:Linux教程
  1. /**
  2. * wait_for_completion: - waits for completion of a task
  3. * @x: holds the state of this particular completion
  4. *
  5. * This waits to be signaled for completion of a specific task. It is NOT
  6. * interruptible and there is no timeout.
  7. *
  8. * See also similar routines (i.e. wait_for_completion_timeout()) with timeout
  9. * and interrupt capability. Also see complete().
  10. */
  11. void __sched wait_for_completion(struct completion *x)
  12. {
  13. wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
  14. }
[cpp]
  1. static long __sched
  2. wait_for_common(struct completion *x, long timeout, int state)
  3. {
  4. might_sleep();
  5. spin_lock_irq(&x->wait.lock);
  6. timeout = do_wait_for_common(x, timeout, state);
  7. spin_unlock_irq(&x->wait.lock);
  8. return timeout;
  9. }

注意:spin_lock_irq(&x->wait.lock)和spin_unlock_irq(&x->wait.lock)並非真正對應的一對自旋鎖,因為在自旋鎖保護中是不允許休眠和調度的。與他們相對應的解鎖和上鎖操作在do_wait_for_common(x, timeout, state)函數內部。

[cpp]
  1. static inline long __sched
  2. do_wait_for_common(struct completion *x, long timeout, int state)
  3. {
  4. if (!x->done) {
  5. DECLARE_WAITQUEUE(wait, current);
  6. wait.flags |= WQ_FLAG_EXCLUSIVE;
  7. __add_wait_queue_tail(&x->wait, &wait);
  8. do {
  9. if (signal_pending_state(state, current)) {
  10. timeout = -ERESTARTSYS;
  11. break;
  12. }
  13. __set_current_state(state);
  14. spin_unlock_irq(&x->wait.lock);
  15. timeout = schedule_timeout(timeout);
  16. spin_lock_irq(&x->wait.lock);
  17. } while (!x->done && timeout);
  18. __remove_wait_queue(&x->wait, &wait);
  19. if (!x->done)
  20. return timeout;
  21. }
  22. x->done--;
  23. return timeout ?: 1;
  24. }
Copyright © Linux教程網 All Rights Reserved