POLL 机制

static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)  //驱动中使用的函数
{
    if (p && wait_address)
        p->qproc(filp, wait_address, p);      // __pollwait((filp, wait_address, p);
}

/* Add a new entry */
static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
                poll_table *p)
{
    struct poll_table_entry *entry = poll_get_entry(p);
    if (!entry)
        return;
    get_file(filp);
    entry->filp = filp;
    entry->wait_address = wait_address;
    init_waitqueue_entry(&entry->wait, current);
    add_wait_queue(wait_address, &entry->wait);   //加入到等待队列中
}

poll_wait是 不等待的,只是加入到等待队列中。 在系统调用的时候会(会调用驱动中的poll函数)判断其返回值,(其过程是在for(;;)中是否被设置,如果设置了,就break,调用,没有设置的话,就休眠调用其他的进程   __timeout = schedule_timeout(__timeout);    // 或者 poll_schedule_timeout(&table, TASK_INTERRUPTIBLE, to, slack) //将进程状态设置成TASK_INTERRUPTIBLE,然后休眠

-----------------------------------------------------------------------------------------------------------

poll -> sys_poll

asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
            long timeout_msecs)

{

    timeout_jiffies = msecs_to_jiffies(timeout_msecs);

    ....

   return do_sys_poll(ufds, nfds, &timeout_jiffies);

}

-------------->

int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)

    poll_initwait(&table);

        --------------->>>>init_poll_funcptr(&pwq->pt, __pollwait);   ----> pt->qproc = qproc;   // 看最上面的开始

  ....

    fdcount = do_poll(nfds, head, &table, timeout);

         ----------------->>>>

 

static int do_poll(unsigned int nfds,  struct poll_list *list,
           struct poll_wqueues *wait, s64 *timeout)

for (;;) {
        struct poll_list *walk;
        long __timeout;

        set_current_state(TASK_INTERRUPTIBLE);
        for (walk = list; walk != NULL; walk = walk->next) {
            struct pollfd * pfd, * pfd_end;

            pfd = walk->entries;
            pfd_end = pfd + walk->len;
            for (; pfd != pfd_end; pfd++) {
                /*
                 * Fish for events. If we found one, record it
                 * and kill the poll_table, so we don't
                 * needlessly register any other waiters after
                 * this. They'll get immediately deregistered
                 * when we break out and return.
                 */
                if (do_pollfd(pfd, pt)) {     /// ------>mask = file->f_op->poll(file, pwait);  return mask;  // 也就是说驱动中的poll函数  只要不 return 0 ;count 就++
                    count++;                                                                                                                         
                    pt = NULL;
                }
            }
        }
        /*
         * All waiters have already been registered, so don't provide
         * a poll_table to them on the next loop iteration.
         */
        pt = NULL;
        if (count || !*timeout || signal_pending(current))    // count , timeout 不等于 0 就 不 break
            break;

        count = wait->error;
        if (count)
            break;

        if (*timeout < 0) {
            /* Wait indefinitely */
            __timeout = MAX_SCHEDULE_TIMEOUT;
        } else if (unlikely(*timeout >= (s64)MAX_SCHEDULE_TIMEOUT-1)) {
            /*
             * Wait for longer than MAX_SCHEDULE_TIMEOUT. Do it in
             * a loop
             */
            __timeout = MAX_SCHEDULE_TIMEOUT - 1;
            *timeout -= __timeout;
        } else {
            __timeout = *timeout;
            *timeout = 0;
        }

        __timeout = schedule_timeout(__timeout);    // 等待
        if (*timeout >= 0)
            *timeout += __timeout;
    }

 

 

----------------------------------------------------------------------------

驱动中的使用

static unsigned forth_drv_poll(struct file *file, poll_table *wait)
{
    unsigned int mask = 0;
    poll_wait(file, &button_waitq, wait);

    if (ev_press)
        mask |= POLLIN | POLLRDNORM;
    
    return mask;
}

static struct file_operations fourth_drv_fops = {
    .poll  = forth_drv_poll,
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值