linux驱动异步通知,linux驱动编程--异步通知与异步I/O

In a general way, there are two methods for process control: synchronizationand asynchronization.

synchronization  is involves block(阻塞) , no-block(轮询) ( poll ). it just like anti-asynchronization.

asynchronization is include signal(信号) and asynchronization I/O( 异步I/O). the kernel is do as they arrived.(随到随做). 信号和异步通知的有一些实现上的不同。

信号的逻辑模型是:进程做自己的事->信号来了,跳过去执行信号处理函数->跳回来继续执行;

异步I/O的逻辑模型是:进程做自己的事->抛出一个I/O请求->继续做自己的事->要用到数据了,再去查询别人是不是已经把I/O请求->继续做事

Asynchronous  notification (异步通知)

@signal for software is equal to @interrupt for hardware.(信号是软件上对于中断的模拟)

service mode is based on the fellowing theory: one signal is corressponds to a slot-function. just like the interrupt do.(相当于中断)

//应用层

fcntl( STDIN_FILENO, F_SETOWN, getpid()); //设置文件的拥有者。在驱动发送的信号会传输给拥有者

oflag = fcntl( STDIN_FILENO, FGETFL);

fcntl( STDIN_FILENO, FSETFL, oflag|FASYNC); //设置异步通知

signal( SIGIO, handler); //设置信号处理函数,一个萝卜一个坑

//驱动层

fasync_helper(int fd,struct file * filp,int on,struct fasync_struct * * fapp);

kill_fasync(struct fasync_struct * * fp,int sig,int band);

the most important thing is what @fasync_helper()and @kill_saync()do. @fasync_helper()will add those information, from upper layer, to a list. @kill_fasync()will check the list and send signal. The fellowing is the reason that i suppose.

/*

* fasync_helper() is used by almost all character device drivers

* to set up the fasync queue. It returns negative on error, 0 if it did

* no changes and positive if it added/deleted the entry.

*/

int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)

{

struct fasync_struct *fa, **fp;

struct fasync_struct *new = NULL;

int result = 0;

if (on) {

new = kmem_cache_alloc(fasync_cache, GFP_KERNEL);

if (!new)

return -ENOMEM;

}

/*

* We need to take f_lock first since it's not an IRQ-safe

* lock.

*/

spin_lock(&filp->f_lock);

write_lock_irq(&fasync_lock);

for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {//检查异步链表是否该文件对应的信息已经存在

if (fa->fa_file == filp) {//假如该file已经被添加过了

if(on) {

fa->fa_fd = fd;

kmem_cache_free(fasync_cache, new);

} else {

*fp = fa->fa_next;

kmem_cache_free(fasync_cache, fa);

result = 1;

}

goto out;

}

}

//假如不存在就添加进去

if (on) {

new->magic = FASYNC_MAGIC;

new->fa_file = filp;

new->fa_fd = fd;

new->fa_next = *fapp;

*fapp = new;

result = 1;

}out:

if (on)

filp->f_flags |= FASYNC;

else

filp->f_flags &= ~FASYNC;

write_unlock_irq(&fasync_lock);

spin_unlock(&filp->f_lock);

return result;

}

the blue code is try to add information to the list. the next one is @kill_fasync().

kill_fasync(struct fasync_struct * * fp,int sig,int band);

/*

fp--异步对象链表

sig--通知的信号类型

band--POLL_IN, POLL_OUT

*/

void kill_fasync(struct fasync_struct **fp, int sig, int band)

{

/* First a quick test without locking: usually

* the list is empty.

*/

if (*fp) {

read_lock(&fasync_lock);

/* reread *fp after obtaining the lock */

__kill_fasync(*fp, sig, band);

read_unlock(&fasync_lock);

}

}

void __kill_fasync(struct fasync_struct *fa, int sig, int band)

{

while (fa) {//会通知所有的注册进程

struct fown_struct * fown;

if (fa->magic != FASYNC_MAGIC) {

printk(KERN_ERR "kill_fasync: bad magic number in "

"fasync_struct!\n");

return;

}

fown = &fa->fa_file->f_owner;//找到文件拥有者的进程ID

/* Don't send SIGURG to processes which have not set a

queued signum: SIGURG has its own default signalling

mechanism. */

if (!(sig == SIGURG && fown->signum == 0))

send_sigio(fown, fa->fa_fd, band);//fa_fd为文件描述符

fa = fa->fa_next;

}}

check those blue code, it is sending signal to some process.

Asynchronous I/O (异步I/O)

//添加I/O请求

aio_read();

aio_write();         //I/O请求执行结果

aio_error(); //查询

aio_return(); //获取

aio_suspend();//阻塞直到请求完成

aio_cancel();         //批量管理I/O请求

lio_listio();

(没找到源码,且使用较少,暂时放弃分析)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值