如果进程和软中断可能访问同一个对象, 那么进程和软中断需要互斥, 进程需要禁止软中断。
如果进程只需要和本处理器的软中断互斥,那么进程只需要禁止本处理器的软中断;如果进程要和所有处理器的软中断互斥,那么进程需要禁止本处理器的软中断,还要使用自旋锁和其他处理器的软中断互斥。
每个进程的 thread_info 结构体有一个抢占计数器“ int preempt_count”,其中第 8~15位是软中断计数。
禁止软中断的时候把当前进程的软中断计数加 2,开启软中断的时候把当前进程的软中断计数减 2。
禁止软中断的接口是 local_bh_disable()。
注意:这个接口只能禁止本处理器的软中断,不能禁止其他处理器的软中断。 bh 表示“ bottom half”,即下半部,软中断是中断处理程序的下半部。
开启软中断的接口是 local_bh_enable()。
把当前进程的软中断计数减 2,如果软中断计数、硬中断计数和不可屏蔽中断计数都是 0,并且有软中断需要处理,那么执行软中断。
注意:local_bh_enable() 在硬中断或者关闭硬中断时使用有可能出现问题,会有警告提醒。
如果进程和硬中断可能访问同一个对象, 那么进程和硬中断需要互斥, 进程需要禁止硬中断。
如果进程只需要和本处理器的硬中断互斥,那么进程只需要禁止本处理器的硬中断;如果进程要和所有处理器的硬中断互斥,那么进程需要禁止本处理器的硬中断,还要使用自旋锁和其他处理器的硬中断互斥。
禁止硬中断的接口如下。
(1) local_irq_disable()。
(2) local_irq_save(flags):首先把硬中断状态保存在参数 flags 中,然后禁止硬中断。这两个接口只能禁止本处理器的硬中断,不能禁止其他处理器的硬中断。禁止硬中断以后,处理器不会响应中断请求。
开启硬中断的接口如下。
(1) local_irq_enable()。
(2) local_irq_restore(flags):恢复本处理器的硬中断状态。
注意:local_irq_disable()和 local_irq_enable()实现内部并没有做count计数,那么不管我之前做了多少次local_irq_disable, 只需要做一次local_irq_enab,所以不能嵌套使用。可使用local_irq_save(flags)来嵌套使用。
local_irq_disable()
local_irq_save()
local_irq_restore()
//中断仍为关闭状态
local_irq_enable()