当前位置: 首页 > 图文教程 > 网络编程 > PHP > 深入浅出分析Linux设备驱动程序中断 (1)(3)

PHP
基于HTTP长连接的"服务器推"技术的php 简易聊天室
PHP 程序员应该使用的10个组件
phpmailer 中文使用说明(简易版)
php 调用远程url的六种方法小结
PHP+XML 制作简单的留言本 图文教程
PHP+MySQL 制作简单的留言本
初学CAKEPHP 基础教程
网页游戏开发入门教程二(游戏模式+系统)
网页游戏开发入门教程三(简单程序应用)
PHP 向右侧拉菜单实现代码,测试使用中
PHP 压缩文件夹的类代码
PHP CKEditor 上传图片实现代码
php 将excel导入mysql
php 向访客和爬虫显示不同的内容
php实现网站插件机制的方法
PHP 远程关机实现代码
超级简单的php+mysql留言本源码
PHP 面向对象实现代码
php 分库分表hash算法
计算一段日期内的周末天数的php代码(星期六,星期日总和)

PHP 中的 深入浅出分析Linux设备驱动程序中断 (1)(3)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 291 ::
收藏到网摘: n/a

六、中断处理程序的不可重入性

上一节中我们提到有时候需要屏蔽中断,可是为什么要将这个中断屏蔽掉呢?这并不是因为技术上实现不了同一中断例程的并行,而是出于管理上的考虑。之所以在中断处理的过程中要屏蔽同一IRQ来的新中断,是因为中断处理程序是不可重入的,所以不能并行执行同一个中断处理程序。在这里我们举一个例子,从这里子例中可以看出如果一个中断处理程序是可以并行的话,那么很有可能会发生驱动程序锁死的情况。当驱动程序锁死的时候,你的操作系统并不一定会崩溃,但是锁死的驱动程序所支持的那个设备是不能再使用了--设备驱动程序死了,设备也就死了。

其中激发PS1的事件会使A1产生一个中断,然后B1去读R1中已有的数据,然后代码C1向R2中写数据。而激发PS2的事件会使A2产生一个中断,然后B2删除R1中的数据,然后C2读去R2中的数据。

如果PS1先产生,且当他执行到A1和B1之间的时候,如果PS2产生了,这是A2会产生一个中断,将PS2中断掉(挂到任务队列的尾部),然后删除了R1的内容。当PS2运行到C2时,由于C1还没有向R2中写数据,所以C2将会在这里被挂起,PS2就睡眠在代码C2上,直到有数据可读的时候被信号唤醒。这是由于PS1中的B2原先要读的R1中的数据被PS2中的B2删除了,所以PS1页会睡眠在B1上,直到有数据可读的时候被信号唤醒。这样一来,唤醒PS1和PS2的事件就永远不会发生了,因此PS1和PS2之间就锁死了。

由于设备驱动程序要和设备的寄存器打交道,所以很难写出可以重入的代码来,因为设备寄存器就是全局变量。因此,最简洁的办法就是禁止同一设备的中断处理程序并行,即设备的中断处理程序是不可重入的。

有一点一定要清楚:在2.0版本以后的Linux kernel中,所有的上半部都是不可中断的(上半部的操作是原子性的);不同设备的下半部可以互相中断,但一个特定的下半部不能被它自己所中断(即同一个下半部不能并行)。

由于中断处理程序要求不可重入,所以程序员也不必为编写可重入的代码而头痛了。以我的经验,编写可重入的设备驱动程序是可以的,编写可重入的中断处理程序是非常难得,几乎不可能。

七、避免竞争条件的出现

我们都知道,一旦竞争条件出现了,就有可能会发生死锁的情况,严重时可能会将整个系统锁死。所以一定要避免竞争条件的出现。这里我不多说,大家只要注意一点:绝大多数由于中断产生的竞争条件,都是在带有中断的内核进程被睡眠造成的。所以在实现中断的时候,一定要相信谨慎的让进程睡眠,必要的时候可以使用cli、sti或者save_flag、restore_flag。具体细节请参看本文指定参考书。

八、实现

如何实现驱动程序的中断例程,是各位读者的事情了。只要你们仔细的阅读short例程的源代码,搞清楚编写驱动程序中断例程的规则,就可以编写自己的中断例程了。只要概念正确,在正确的规则下编写你的代码,那就是符合道理的东西。我始终强调,概念是第一位的,能编多少代码是很其次的,我们一定要概念正确,才能进行正确的思考。

(T114)