Board logo

标题: 驱动中poll_wait()函数的疑问 [打印本页]

作者: luanjian    时间: 2006-7-19 10:44     标题: 驱动中poll_wait()函数的疑问

应用程序的select()系统调用,调用驱动中的poll()方法。
不理解的是在下面的poll()方法实现中,首先调用poll_wait将等待队列添加到wait结构中,接下来是个判断语句  
if (dev->rp != dev->wp)
                mask |= POLLIN | POLLRDNORM;  /* readable */
只考虑可读情况。如果这个if语句的条件不满足,那么就不会返回可读,也就是返回0。那么在这里怎么实现阻塞的呢?也就是说如果在应用的select()系统中,指定一个等待时间,在这个等待时间里如果没有描述符可读,就一直阻塞。那个这个等待时间是怎么和驱动中的poll()方法联系起来的呢?如果要修改这个poll()方法怎么修改呢?还有在poll()方法中,怎么指定描述符集中的哪一个是可读的呢?简单的返回POLLIN | POLLRDNORM,是无法指定是哪一个描述符可读的呀?
               
static unsigned int scull_p_poll(struct file *filp, poll_table *wait)
{
        struct scull_pipe *dev = filp->private_data;
        unsigned int mask = 0;

        /*
        * The buffer is circular; it is considered full
        * if "wp" is right behind "rp" and empty if the
        * two are equal.
        */
        down(&dev->sem);
        poll_wait(filp, &dev->inq,  wait);
       // poll_wait(filp, &dev->outq, wait);
        if (dev->rp != dev->wp)
                mask |= POLLIN | POLLRDNORM;  /* readable */
        //if (spacefree(dev))
        //        mask |= POLLOUT | POLLWRNORM;  /* writable */
        up(&dev->sem);
        return mask;
}

作者: linuxarm    时间: 2006-7-20 15:08

你仔细研究下这段代码就清楚了.poll select之类的,都差不多.
int do_select(int n, fd_set_bits *fds, long *timeout)
{
poll_table table, *wait;
int retval, i, off;
long __timeout = *timeout;

read_lock(¤t->files->file_lock);
retval = max_select_fd(n, fds);
read_unlock(¤t->files->file_lock);

if (retval < 0)
return retval;
n = retval;

poll_initwait(&table);
wait = &table;
if (!__timeout)
wait = NULL;
retval = 0;
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
for (i = 0 ; i < n; i++) {
unsigned long bit = BIT(i);
unsigned long mask;
struct file *file;

off = i / __NFDBITS;
if (!(bit & BITS(fds, off)))
continue;
file = fget(i);
mask = POLLNVAL;
if (file) {
mask = DEFAULT_POLLMASK;
if (file->f_op && file->f_op->poll)
mask = file->f_op->poll(file, wait);
fput(file);
}
if ((mask & POLLIN_SET) && ISSET(bit, __IN(fds,off))) {
SET(bit, __RES_IN(fds,off));
retval++;
wait = NULL;
}
if ((mask & POLLOUT_SET) && ISSET(bit, __OUT(fds,off))) {
SET(bit, __RES_OUT(fds,off));
retval++;
wait = NULL;
}
if ((mask & POLLEX_SET) && ISSET(bit, __EX(fds,off))) {
SET(bit, __RES_EX(fds,off));
retval++;
wait = NULL;
}
}
wait = NULL;
if (retval || !__timeout || signal_pending(current))
break;
if(table.error) {
retval = table.error;
break;
}
__timeout = schedule_timeout(__timeout);
}
current->state = TASK_RUNNING;

poll_freewait(&table);

/*
* Up-to-date the caller timeout.
*/
*timeout = __timeout;
return retval;
}

循环调用你设备的poll函数,如果你的状态没有改变,就返回0,所有它监测的设备都返回0,那么break需要的条件不会满足(retval 始终是 0).那么就不会返回,而会去调度走.

这个函数和sleep_on的实现其实比较类似,可以理解为集体睡眠函数,唤醒还是用wake_up.




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0