- 用户空间存在 select / poll / epoll 的系统调用, 这三种调用都需要驱动层的支持 即
uint (*poll)(struct file *filp, poll_table *poll_tbl);
poll_table 结构 , 驱动要增加一个等待队列到poll_table 结构要通过调用
void poll_wait(struct file *filp, wait_queue_head_t *wq, poll_table *poll_tbl);
- poll的实现步骤。
- 在一个或者多个等待队列wq上调用poll_wait, 当没有文件描述符fd 有数据用于IO操作时,则用户空间的进程被置于等待状态, 等待wq上所有的fd处于就位状态。
- 返回位掩码, 描述可能不必阻塞就立刻进行的操作。
POLLIN : 设备可被非阻塞读。
POLLRDNORM: 一个可读设备返回 POLLIN | POLLRDNORM
POLLRDBAND: 带外数据是否可读。
POLLPRI:带外数据可被非阻塞读取。(select会有问题,报告异常)
POLLUP:读设备的进程到了文件尾。
POLLERR:设备上发生了错误
POLLOUT:设备可被非阻塞写
POLLWRNORM: 一个可写设备应放回 POLLOUT | POLLWRNORM
POLLWRBAND:带有0优先级的数据可写入设备。即带外数据
- 范例
static uint scull_p_poll(struct file *filp, poll_table *tbl)
{
struct scull_pipe *dev = filp->private_data;
uint mask = 0;
down(&dev->sem);
//增加等待队列 inq, outq 到 poll_table
poll_wait(filp, &dev->irq, tbl);
poll_wait(filp, &dev->outq, tbl);
if (dev->rp != dev->wp)
mask |= POLLIN | POLLRDNORM; //readable
if (spacefree(dev))
mask |= POLLOUT | POLLWRNORM; //writable
//如果没有更多数据可用时(文件尾),应当返回POLLHUP.
up(&dev->sem);
return mask;
}
|
同步缓冲
int (*fsync)(struct file *filp, struct dentry *dentry, int datasync);
datasync 参数用来区分 fsync 和 fdatasync 系统调用
同步操作应当忽略O_NONBLOCK是否被设置,确认设备被完全刷新,即本函数的实现一定时阻塞的。
阅读(1624) | 评论(0) | 转发(0) |