进程调度API之wait_for_completion_x

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_common
static 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_common
	spin_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 __sched
do_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_timeout
			timeout = 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;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值