进程调度API之completion_done

bool completion_done(struct completion *x)
用于判断是否还有wait等待在completion *x 这个完成量上,然后true 表示没有等待,false 表示有wait在等待
其源码分析如下:
bool completion_done(struct completion *x)
{
	if (!READ_ONCE(x->done))
		return false;

	/*
	 * If ->done, we need to wait for complete() to release ->wait.lock
	 * otherwise we can end up freeing the completion before complete()
	 * is done referencing it.
	 *
	 * The RMB pairs with complete()'s RELEASE of ->wait.lock and orders
	 * the loads of ->done and ->wait.lock such that we cannot observe
	 * the lock before complete() acquires it while observing the ->done
	 * after it's acquired the lock.
	 */
	smp_rmb();
	spin_unlock_wait(&x->wait.lock);
	return true;
}
判断的核心是x->done 是否等于零。如果为零,则说明没有wait再等待了。
为什么这么说呢,因为完成量等待完成量的函数do_wait_for_common 中会对x->done 做减件操作
do_wait_for_common(struct completion *x,
		   long (*action)(long), long timeout, int state)
{
	if (x->done != UINT_MAX)
		x->done--;
	return timeout ?: 1;
}
而在释放完成量的函数complete 中会做加加操作
void complete(struct completion *x)
{
	unsigned long flags;

	spin_lock_irqsave(&x->wait.lock, flags);
	if (x->done != UINT_MAX)
		x->done++;
	__wake_up_locked(&x->wait, TASK_NORMAL, 1);
	spin_unlock_irqrestore(&x->wait.lock, flags);
}

并且这两者是可以嵌套配对的
所以当x->done 为零时,说明没有人操作完成量了.

你可能感兴趣的:(Linux,源码分析,kernel常用API源码分析)