5 c语言调用Linux的sleepy函数,Linux设备驱动程序学习( 四 )


void( file *,*,*);
2. 返回一个位掩码:描述可能不必阻塞就立刻进行的操作,几个标志(通过 定义)用来指示可能的操作:
标志
含义
如果设备无阻塞的读,就返回该值
通常的数据已经准备好,可以读了,就返回该值 。通常的做法是会返回(|)
如果可以从设备读出带外数据,就返回该值,它只可在linux内核的某些网络代码中使用,通常不用在设备驱动程序中
如果可以无阻塞的读取高优先级(带外)数据,就返回该值,返回该值会导致报告文件发生异常,以为八带外数据当作异常处理
当读设备的进程到达文件尾时,驱动程序必须返回该值,依照的功能描述,调用的进程被告知进程时可读的 。
如果设备发生错误,就返回该值 。
如果设备可以无阻塞地些,就返回该值
设备已经准备好,可以写了,就返回该值 。通常地做法是(|)
于类似
考虑 poll 方法的实现:
int ( file *filp,*wait)
*dev = filp->;
int mask = 0;
/*
* Theis ; it isfull
* if "wp" is right"rp" and empty if the
* two are equal.
*/
down(&dev->sem);
(filp, &dev->inq, wait);
(filp, &dev->outq, wait);
if (dev->rp != dev->wp)
mask |=| ; /**/
if ((dev))
mask |=| ; /**/
up(&dev->sem);
mask;
与read 和write 的交互
正确实现poll调用的规则:
从设备读取数据:
(1)如果在输入缓冲中有数据,read 调用应当立刻返回,即便数据少于应用程序要求的,并确保其他的数据会很快到达 。如果方便,可一直返回小于请求的数据,但至少返回一个字节 。在这个情况下,poll 应当返回 | 。
(2)如果在输入缓冲中无数据,read默认必须阻塞直到有一个字节 。若 被置位,read 立刻返回 -EAGIN。在这个情况下,poll 必须报告这个设备是不可读(清零|)的直到至少一个字节到达 。
(3)若处于文件尾,不管是否阻塞,read 应当立刻返回0,且poll 应该返回 。
向设备写数据
(1)若输出缓冲有空间,write 应立即返回 。它可接受小于调用所请求的数据,但至少必须接受一个字节 。在这个情况下,poll应返回 | 。
(2)若输出缓冲是满的,write默认阻塞直到一些空间被释放 。若被设置,write 立刻返回一个 - 。在这些情况下, poll 应当报告文件是不可写的(清零|). 若设备不能接受任何多余数据,不管是否设置了,write 应返回 -("设备上没有空间") 。
(3)永远不要让write在返回前等待数据的传输结束,即使 被清除 。若程序想保证它加入到输出缓冲中的数据被真正传送, 驱动必须提供一个 fsync 方法 。
刷新待处理输出
若一些应用程序需要确保数据被发送到设备,就实现必须fsync 方法 。对 fsync 的调用只在设备被完全刷新时(即输出缓冲为空)才返回,不管是否被设置,即便这需要一些时间 。其原型是:
int (*fsync) ( file *file,*, int );
底层数据结构
只要用户应用程序调用 poll、、或,内核就会调用这个系统调用所引用的所有文件的 poll 方法,并向他们传递同一个 。结构只是构成实际数据结构的简单封装: ;/*
*andfor f_op->poll
*/
void (*)( file *,*,*);
{
qproc;
} ;
对于 poll和 系统调用,是一个包含结构内存页链表 。{
file * filp;
wait;
* ;
};
对的调用有时还会将进程添加到给定的等待队列 。整个的结构必须由内核维护,在 poll 或者返回前,进程可从所有的队列中去除, .
如果被轮询的驱动没有一个驱动程序指明可进行非阻塞I/O,poll 调用会简单地睡眠,直到一个它所在的等待队列(可能许多)唤醒它.