首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

驱动中poll_wait()函数的疑问

驱动中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;
}
你仔细研究下这段代码就清楚了.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.
51 c8051f(f020,f040) msp430 arm(2410,2510) fpga(xc3s4000) dsp(5116 dm642) keilc vc++ matlab linux protel Ten_layerPCB mpegx h.26x Rscode Turbocode ofdm VideoBroadcasting ldpc_code(now!)
返回列表