中斷屏蔽,正如其名,屏蔽掉CPU的中斷響應(yīng)功能,解決并發(fā)引起的競(jìng)態(tài)問(wèn)題。
在進(jìn)入臨界區(qū)前屏蔽中斷,這么做有什么好處,以及有什么弊端?
好處在于:
弊端在于:
Linux內(nèi)核中,除了系統(tǒng)進(jìn)程調(diào)度依賴中斷,還有一些異步I/O等眾多操作都依賴中斷,因此長(zhǎng)時(shí)間屏蔽中斷是很危險(xiǎn)的,會(huì)對(duì)系統(tǒng)造成嚴(yán)重影響,因此也要求臨界區(qū)代碼要簡(jiǎn)短。CPU內(nèi)部的,對(duì)于SMP對(duì)稱多處理器,仍然不可避免的會(huì)收到其他CPU的中斷。因此,并不能解決SMP多CPU引發(fā)的競(jìng)態(tài)因此,單獨(dú)使用中斷屏蔽通常不是一種值得推薦的避免競(jìng)態(tài)的方法
?
關(guān)于中斷屏蔽,
Linux內(nèi)核所提供的接口如下:
local_irq_enable()????//?使能本CPU的中斷
local_irq_disable()????//?禁止本CPU的中斷
local_irq_save(flags)???//?禁止本CPU的中斷,并保存CPU中斷位的信息
local_irq_restore(flags)??//?使能本CPU的中斷,并恢復(fù)CPU中斷位的信息
local_bh_disable(void)???//?禁止本CPU底半部中斷
local_bh_enable(void)??????//?使能本CPU底半部中斷
?
因?yàn)橹袛嗥帘闻c底層芯片架構(gòu)有關(guān),不同架構(gòu)處理方式不同,我們以
ARM為例
#define?local_irq_enable()?do?{?raw_local_irq_enable();?}?while?(0)
#define?raw_local_irq_enable()??arch_local_irq_enable()
#define?arch_local_irq_enable?arch_local_irq_enable
static?inline?void?arch_local_irq_enable(void)
{
?asm?volatile(
??"?cpsie?i???@?arch_local_irq_enable"
??:
??:
??:?"memory",?"cc");
}
函數(shù)介紹:local_irq_enable函數(shù)用于將CPSR寄存器中的中斷使能位設(shè)為1,從而使得CPU能夠響應(yīng)中斷。
相關(guān)實(shí)現(xiàn):
asm:聲明一個(gè)內(nèi)聯(lián)匯編表達(dá)式
cpsie i:匯編指令,設(shè)置CPSR寄存器的I位,來(lái)允許本CPU響應(yīng)中斷。
memory:向匯編說(shuō)明,此處內(nèi)存發(fā)生了更改,類似于內(nèi)存屏障的作用
cc:表示可能會(huì)修改條件碼的標(biāo)志
匯編代碼語(yǔ)法:https://www.jianshu.com/p/57fef17149ae
?
#define?arch_local_irq_disable?arch_local_irq_disable
static?inline?void?arch_local_irq_disable(void)
{
?asm?volatile(
??"?cpsid?i???@?arch_local_irq_disable"
??:
??:
??:?"memory",?"cc");
}
函數(shù)介紹:arch_local_irq_disable函數(shù)用于將CPSR寄存器中的中斷使能位設(shè)為0,從而禁止CPU響應(yīng)中斷。
相關(guān)實(shí)現(xiàn):同上
cpsid:是匯編指令,用于清除CPSR寄存器的中斷標(biāo)志,以禁止中斷!?
#define?arch_local_irq_save?arch_local_irq_save
static?inline?unsigned?long?arch_local_irq_save(void)
{
?unsigned?long?flags;
?asm?volatile(
??"?mrs?%0,?"?IRQMASK_REG_NAME_R?"?@?arch_local_irq_save\n"
??"?cpsid?i"
??:?"=r"?(flags)?:?:?"memory",?"cc");
?return?flags;
}
函數(shù)介紹:arch_local_irq_save函數(shù),用于保存當(dāng)前中斷狀態(tài)并禁用中斷。
相關(guān)實(shí)現(xiàn):
mrs %0 IRQMASK_REG_NAME_R:mrs指令將由IRQMASK_REG_NAME_R宏指定的IRQMASK寄存器的值移動(dòng)到flags變量中。?
/*
?*?restore?saved?IRQ?&?FIQ?state
?*/
#define?arch_local_irq_restore?arch_local_irq_restore
static?inline?void?arch_local_irq_restore(unsigned?long?flags)
{
?asm?volatile(
??"?msr?"?IRQMASK_REG_NAME_W?",?%0?@?local_irq_restore"
??:
??:?"r"?(flags)
??:?"memory",?"cc");
}
函數(shù)介紹:arch_local_irq_restore函數(shù),用于恢復(fù)當(dāng)前中斷狀態(tài)并打開(kāi)中斷。
相關(guān)實(shí)現(xiàn):同上
關(guān)于
local_bh_disable和local_bh_enable兩個(gè)接口,涉及到中斷底半部機(jī)制,內(nèi)容較為復(fù)雜,放在后面單獨(dú)拆解!
?
該篇文章,主要了解以下幾點(diǎn):
Linux內(nèi)核提供的中斷屏蔽接口?

