非阻塞型IO操作使用poll,select,epoll等系统调用,来实现查询设备是否可以被非阻塞的执行某种操作。select调用比较常用,这个系统调用用法大致是:
int select(int numfds,fd_set *readfds,fd_set *writefds,fd_set *exeptfds,struct timeval *timeout)
在一个或多个设备描述符上,查询是否有操作可以被执行,如果有则返回,否则等待或等待timeout个时间。然后程序可以使用FD_ISSET这样的宏判断是什么类型的操作可以被非阻塞的执行,具体使用方法可以在资料上查到,就不过多讨论用户空间的使用方法。但是一定是要先会用才能理解驱动程序实现的原理。
还是以scull_p_poll为例
- 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,epoll系统调用,都是关联到这个函数,在file_operations结构中要设置.poo=scull_p_poll。scull_p_poll函数在驱动层做的事其实很简单,首先将所有操作可能引发等待的等待队列,添加进poll_table类型的参数中。其次,根据具体驱动程序的情况判断读写的条件,返回表示可以进行的操作的标识。
系统调用的功能的大部分都是由内核来做的,驱动程序只需要在scull_p_poll这样的函数中做上述两件事情就可以了。
阅读(1531) | 评论(0) | 转发(1) |