进程调度API之__wake_up

void __wake_up(wait_queue_head_t *q, unsigned int mode,	int nr_exclusive, void *key)
这个函数用于wakeup 阻塞在waittqueue上的thread。从解释这里看,就知道__wake_up 会和waitqueue
配合来使用.
其使用的例子如下:
struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
{

#初始化等待队列clp->cl_lock_waitq
	init_waitqueue_head(&clp->cl_lock_waitq);


}

static int
nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
{

	wait_queue_head_t *q = &clp->cl_lock_waitq;
#定义wait,给wait.func 赋值为nfs4_wake_lock_waiter,这样当thread 被wakeup的时候就会执行wait.func
	wait_queue_t wait;

	init_wait(&wait);
	wait.private = &waiter;
	wait.func = nfs4_wake_lock_waiter;
#将这个wait 添加到wait_queue_head_t 中
	add_wait_queue(q, &wait);

	while(!signalled()) {

		status = -ERESTARTSYS;
		spin_lock_irqsave(&q->lock, flags);
		if (waiter.notified) {
			spin_unlock_irqrestore(&q->lock, flags);
			continue;
		}
#将系统设置为可以中断的sleep后,系统就会进入sleep状态,等待被wakeup
		set_current_state(TASK_INTERRUPTIBLE);
#被nfs4_callback_notify_lock 中的__wake_up 后,系统就从这里开始执行
		spin_unlock_irqrestore(&q->lock, flags);

		freezable_schedule_timeout_interruptible(NFS4_LOCK_MAXTIMEOUT);
	}
#结束等待wait
	finish_wait(q, &wait);
	return status;
}

__be32 nfs4_callback_notify_lock(struct cb_notify_lock_args *args, void *dummy,
				 struct cb_process_state *cps)
{
	/* Don't wake anybody if the string looked bogus */
	if (args->cbnl_valid)
		__wake_up(&cps->clp->cl_lock_waitq, TASK_NORMAL, 0, args);

}
这个例子其实可以看到__wake_up 使用的整个过程。
__wake_up的源码分析如下:

void __wake_up(wait_queue_head_t *q, unsigned int mode,
			int nr_exclusive, void *key)
{
	unsigned long flags;
#wait_queue_head_t 中必须提供spin lock所锁
	spin_lock_irqsave(&q->lock, flags);
	__wake_up_common(q, mode, nr_exclusive, 0, key);
	spin_unlock_irqrestore(&q->lock, flags);
}

static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
			int nr_exclusive, int wake_flags, void *key)
{
	wait_queue_t *curr, *next;
#可以看到这里会遍历q->task_list,然后执行curr->func。这里的curr的类型是wait_queue_t,
本例子中就是wait_queue_t wait;
	list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
		unsigned flags = curr->flags;

		if (curr->func(curr, mode, wake_flags, key) &&
				(flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
			break;
	}
}
这个例子不仅了解了__wake_up的具体实现,也了解了wait_queue_head_t的用法.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值