- /** * wait_for_completion: - waits for completion of a task
- * @x: holds the state of this particular completion *
- * This waits to be signaled for completion of a specific task. It is NOT * interruptible and there is no timeout.
- * * See also similar routines (i.e. wait_for_completion_timeout()) with timeout
- * and interrupt capability. Also see complete(). */
- void __sched wait_for_completion(struct completion *x) {
- wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE); }
- static long __sched wait_for_common(struct completion *x, long timeout, int state)
- { might_sleep();
- spin_lock_irq(&x->wait.lock);
- timeout = do_wait_for_common(x, timeout, state); spin_unlock_irq(&x->wait.lock);
- return timeout; }
注意:spin_lock_irq(&x->wait.lock)和spin_unlock_irq(&x->wait.lock)并非真正对应的一对自旋锁,因为在自旋锁保护中是不允许休眠和调度的。与他们相对应的解锁和上锁操作在do_wait_for_common(x, timeout, state)函数内部。
[cpp]- static inline long __sched do_wait_for_common(struct completion *x, long timeout, int state)
- { if (!x->done) {
- DECLARE_WAITQUEUE(wait, current);
- wait.flags |= WQ_FLAG_EXCLUSIVE; __add_wait_queue_tail(&x->wait, &wait);
- do { if (signal_pending_state(state, current)) {
- timeout = -ERESTARTSYS; break;
- } __set_current_state(state);
- spin_unlock_irq(&x->wait.lock); timeout = schedule_timeout(timeout);
- spin_lock_irq(&x->wait.lock); } while (!x->done && timeout);
- __remove_wait_queue(&x->wait, &wait); if (!x->done)
- return timeout; }
- x->done--; return timeout ?: 1;
- }