进程调度API之__wake_up

来源:互联网 发布:阿里云 华北5 速度 编辑:程序博客网 时间:2024/05/17 07:31
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_waitqinit_waitqueue_head(&clp->cl_lock_waitq);}static intnfs4_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.funcwait_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状态,等待被wakeupset_current_state(TASK_INTERRUPTIBLE);#被nfs4_callback_notify_lock 中的__wake_up 后,系统就从这里开始执行spin_unlock_irqrestore(&q->lock, flags);freezable_schedule_timeout_interruptible(NFS4_LOCK_MAXTIMEOUT);}#结束等待waitfinish_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的用法.

原创粉丝点击