TA的每日心情 | 衰 2018-6-5 13:21 |
---|
签到天数: 13 天 连续签到: 1 天 [LV.3]偶尔看看II
|
app : poll
kernel :sys_poll
do_sys_poll(ufds, nfds, &timeout_jiffies);
poll_initwait(&table); //poll_initwait函数注册一下回调函数__pollwait,它就是我们的驱动程序执行poll_wait时,真正被调用的函数。
init_poll_funcptr(&pwq->pt, __pollwait); > pt->qproc = __pollwait;
do_poll(nfds, head, &table, timeout);
for (;;) {
//函数do_pollfd里就会使用file->f_op->poll(file, pwait)调用驱动里的poll函数
if (do_pollfd(pfd, pt)) { > mask = file->f_op->poll(file, pwait); return mask;
//驱动的poll函数:
poll_wait(file, &button_waitq, wait); //把当前进程挂到button_waitq队列里去,不会立即休眠;
p->qproc(filp, &button_waitq, p); 也就是__pollwait(filp, &button_waitq, p);//__pollwait函数就是把当前进程挂到button_waitq队列里去,并不会立即休眠;
count++; //如果驱动的poll函数返回非零值,那么count++
pt = NULL;
}
//break 的条件:count 非零, 超时 ,有信号等待处理
if (count || !*timeout || signal_pending(current))
break;
//休眠__timeout
__timeout = schedule_timeout(__timeout);
}
现在来总结一下poll机制:
1. poll > sys_poll > do_sys_poll > poll_initwait,
poll_initwait函数注册一下回调函数__pollwait,它就是我们的驱动程序执行poll_wait时,真正被调用的函数。
2. 接下来执行file->f_op->poll,即我们驱动程序里自己实现的poll函数
它会调用poll_wait把自己挂入某个队列,这个队列也是我们的驱动自己定义的;
它还判断一下设备是否就绪。
3. 如果设备未就绪,do_sys_poll里会让进程休眠一定时间
4. 进程被唤醒的条件有2:一是上面说的“一定时间”到了,二是被驱动程序唤醒。
驱动程序发现条件就绪时,就把“某个队列”上挂着的进程唤醒,这个队列,就是前面通过poll_wait把本进程挂过去的队列。
5. 如果驱动程序没有去唤醒进程,那么chedule_timeout(__timeou)超时后,会重复2、3动作,直到应用程序的poll调用传入的时间到达。
|
|