进程调度API之wait_for_completion_x

来源:互联网 发布:长江大数据交易所 编辑:程序博客网 时间:2024/06/05 23:46
wait_for_completion_x 是一系列函数用于等待完成量释放task,这里以常见的wait_for_completion为例void __sched wait_for_completion(struct completion *x){wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);}继续调用wait_for_commonstatic inline long __sched__wait_for_common(struct completion *x,  long (*action)(long), long timeout, int state){// 这里不能sleep,如果sleep的话,might_sleep 会打印callstack,这个函数的作用之前博文分析过might_sleep();//核心是调用do_wait_for_commonspin_lock_irq(&x->wait.lock);timeout = do_wait_for_common(x, action, timeout, state);spin_unlock_irq(&x->wait.lock);return timeout;}static inline long __scheddo_wait_for_common(struct completion *x,   long (*action)(long), long timeout, int state){// 如果x->done 不是零,说明do_wait_for_common 已经被调用过一次了,从这里也可以看出完成量是可以嵌套的if (!x->done) {//定义一个wait,将当前进程current加进去DECLARE_WAITQUEUE(wait, current);//将wait添加到完成量的队列中__add_wait_queue_tail_exclusive(&x->wait, &wait);do {// 看有没有pending的信号没有处理if (signal_pending_state(state, current)) {timeout = -ERESTARTSYS;break;}//设定当前task的状态为形参state,本例中为TASK_UNINTERRUPTIBLE__set_current_state(state);spin_unlock_irq(&x->wait.lock);// 开始执行action函数,这里的action为schedule_timeouttimeout = action(timeout);spin_lock_irq(&x->wait.lock);// 这个循环退出的条件就是x->done 为0 ,表示没有task再使用这个完成量,或者schedule_timeout//函数超时退出} while (!x->done && timeout);//从完成量中删除wait__remove_wait_queue(&x->wait, &wait);//程序运行到这里说明已经退出前面的while循环,这里判断是否是timeout退出的if (!x->done)return timeout;}//变量减减.在complete函数中有加加操作.if (x->done != UINT_MAX)x->done--;return timeout ?: 1;}

原创粉丝点击