Linux0.11 临界区
在学习Linux驱动程序设计的过程中,最重要的是要学会临街区的使用,不睡眠的临界区保护主要是使用了禁用中断和自旋锁,为什么会产生临界区,是因为语句可能会被中断打断导致数据的错误或者不完整
例如如下语句
- int i
- void add()
- {
- i++;
- }
如上函数,一个全局变量i自加,假设有两个内核控制路径(进程上下文,中断,软中断)掉用了add函数,等执行完成后i的值是多少,我们首先分析当两个进程上下文中分析,在arm平台中,i++需要三步完成,mem表示i所在的地址
通过分析我们可以知道进程一中最后的i的值并不像预期的那样为2,而是为1,仅仅一个变量都会产生临界区的问题,何况比如链表等操作,因此,在Linux内核编程中需仔细分析临界区的问题,
如上所说,变量的访问可以在任何的内核控制路径下,在分析Linux0.11之前我们首先确认一点,Linux0.11的代码基于不可抢占内核和单核处理器上,基于以上两点Linux0.11的临界区访问就比较简单了,
首先如图所述的问题不会存在,因为是不可抢占内核所以进程1在执行的过程中不可能被进程2打断,但是如果进程2所在的路径为中断路径或者软中断路径呢
当进程1在执行的过程中,发生了一个硬件中断,此时硬件中断中也访问了进程1种的i变量也会导致进程1的执行完毕后虽然i加了两次但是结果为1的情况
在这种情况下只需要在进程1中在访问i的时候禁用中断即可
但是在Linux0.11中在访问全局变量的时候也没有禁用中断,这是为什么
原因主要有两点,第一是这个全局变量没有在中断程序中使用,第二是作者仔细分析虽然可能出现错误但是对系统没有影响,第三是Linux0.11只支持x86在x86架构下i++可能只被汇编为一条指令(不能打断),因此可不用禁用中断
虽然在Linux0.11中不需要深入分析临界区,但在Linux不断发展的过程中支持了更多的平台和多核心,在目前的Linux驱动编程中需仔细分析临界区