為了實(shí)現(xiàn)對(duì)臨界資源的有效管理,應(yīng)用層的程序有原子變量,條件變量,信號(hào)量來(lái)控制并發(fā),同樣的問(wèn)題也存在與驅(qū)動(dòng)開(kāi)發(fā)中,比如一個(gè)驅(qū)動(dòng)同時(shí)被多個(gè)應(yīng)用層程序調(diào)用,此時(shí)驅(qū)動(dòng)中的全局變量會(huì)同時(shí)屬于多個(gè)應(yīng)用層進(jìn)程的進(jìn)程空間,這種情況下也要使用一些技術(shù)來(lái)實(shí)現(xiàn)對(duì)并發(fā)的控制。本文將討論內(nèi)核中下述并發(fā)控制技術(shù)的技術(shù)特點(diǎn)和應(yīng)用場(chǎng)景。

  1. 中斷屏蔽

  2. 原子操作

    1. 原子變量操作

    2. 原子位操作

  3. 自旋鎖

    1. 傳統(tǒng)自旋鎖

    2. 讀寫(xiě)自旋鎖

    3. 順序鎖

    4. RCU

  4. 信號(hào)量

    1. 傳統(tǒng)信號(hào)量

    2. 讀寫(xiě)信號(hào)量

    3. 完成量

  5. 互斥量

中斷屏蔽

顧名思義,就是屏蔽所有的中斷。在嵌入式系統(tǒng),中斷屏蔽可以有三級(jí),1. 硬件接口的屏蔽,2. 硬件GIC的屏蔽,3. CPU(內(nèi)核)的屏蔽。如果在接口處屏蔽了,那么中斷來(lái)了就丟了,根本找不到。如果在GIC處屏蔽了,那么在屏蔽期間如果來(lái)了irq_1,irq_2,irq_3個(gè)中斷,因?yàn)橹挥幸粋€(gè)pending標(biāo)志位,所以最后irq_3來(lái)的時(shí)候會(huì)將pending置位,之后解除屏蔽了,CPU發(fā)現(xiàn)pending有置位,還是會(huì)處理,但是1,2就肯定丟了。在ARM處的屏蔽,即內(nèi)核中的屏蔽,看怎么設(shè)置了,如果就是local_irq_disable,那么丟了就是丟了,和在接口處屏蔽一樣,如果是local_irq_save就和第二種一樣,追到最后一個(gè)中斷,內(nèi)核也有相應(yīng)的機(jī)制進(jìn)行中斷計(jì)數(shù),知道這期間來(lái)了多少個(gè)中斷,但是實(shí)際操作中,大部分情況我們都不會(huì)追著執(zhí)行錯(cuò)過(guò)的中斷,除非這個(gè)中斷非常重要。

我們這里討論的,就是在內(nèi)核中進(jìn)行中斷屏蔽。由于內(nèi)核中很多重要的操作都要依賴于中斷,所以屏蔽所有的中斷是十分危險(xiǎn)的,里面執(zhí)行的代碼要盡可能的快,而且,由于內(nèi)核的進(jìn)程調(diào)度也是由中斷驅(qū)動(dòng)的,所以中斷屏蔽中不能有可能引發(fā)休眠的代碼,否則無(wú)法被喚醒。注意,中斷屏蔽只是屏蔽了本CPU的中斷,所以并不能解決SMP引發(fā)的競(jìng)泰問(wèn)題,通常,中斷屏蔽要和自旋鎖聯(lián)合使用,用于防止訪問(wèn)自旋鎖保護(hù)的臨界區(qū)時(shí)被中斷打斷

普通的中斷屏蔽

local_irq_disable();    //屏蔽中斷//或local_irq_save(flags);  //屏蔽中斷并保存目前CPU中的中斷位信息/* 臨界區(qū) */local_irq_enable();     //解除屏蔽//或local_irq_restore(flags);   //解除屏蔽并恢復(fù)中斷位信息

底半部的中斷屏蔽

local_bh_disable();     //屏蔽中斷,bh版本的本質(zhì)是屏蔽了這個(gè)CPU上的軟中斷

/* 臨界區(qū) */local_bh_enable();

網(wǎng)友評(píng)論