查看: 3145|回复: 0

[原创] poll内核源码分析

[复制链接]
  • TA的每日心情

    2018-6-5 13:21
  • 签到天数: 13 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2016-3-19 16:42:36 | 显示全部楼层 |阅读模式
    分享到:

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


    回复

    使用道具 举报

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

    本版积分规则

    关闭

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



    手机版|小黑屋|与非网

    GMT+8, 2024-4-19 09:02 , Processed in 0.103970 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.