回答

收藏

[原创] poll内核源码分析

嵌入式系统 嵌入式系统 3683 人阅读 | 0 人回复 | 2016-03-19


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调用传入的时间到达。


分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条