Linux源码分析:completion的解读

字体大小: 中小 标准 ->行高大小: 标准
  1. /**   * wait_for_completion: - waits for completion of a task 
  2.  * @x:  holds the state of this particular completion   * 
  3.  * This waits to be signaled for completion of a specific task. It is NOT   * interruptible and there is no timeout. 
  4.  *   * See also similar routines (i.e. wait_for_completion_timeout()) with timeout 
  5.  * and interrupt capability. Also see complete().   */  
  6. void __sched wait_for_completion(struct completion *x)   {  
  7.     wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);   }  
[cpp]
  1. static long __sched   wait_for_common(struct completion *x, long timeout, int state)  
  2. {       might_sleep();  
  3.        spin_lock_irq(&x->wait.lock);  
  4.     timeout = do_wait_for_common(x, timeout, state);       spin_unlock_irq(&x->wait.lock);  
  5.     return timeout;   }  

注意: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   do_wait_for_common(struct completion *x, long timeout, int state)  
  2. {       if (!x->done) {  
  3.         DECLARE_WAITQUEUE(wait, current);     
  4.         wait.flags |= WQ_FLAG_EXCLUSIVE;           __add_wait_queue_tail(&x->wait, &wait);  
  5.         do {               if (signal_pending_state(state, current)) {  
  6.                 timeout = -ERESTARTSYS;                   break;  
  7.             }               __set_current_state(state);  
  8.             spin_unlock_irq(&x->wait.lock);               timeout = schedule_timeout(timeout);  
  9.             spin_lock_irq(&x->wait.lock);           } while (!x->done && timeout);  
  10.         __remove_wait_queue(&x->wait, &wait);           if (!x->done)  
  11.             return timeout;       }  
  12.     x->done--;       return timeout ?: 1;  
  13. }  

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/57697.html