嵌入式Linux實(shí)時(shí)技術(shù)改進(jìn)與實(shí)現(xiàn)
4、spinlock轉(zhuǎn)換成mutex
spinlock是一個(gè)高效的共享資源同步機(jī)制,在SMP(對(duì)稱多處理器Symmetric Multiple Proocessors)的情況下,它用于保護(hù)共享資源,如全局的數(shù)據(jù)結(jié)構(gòu)或一個(gè)只能獨(dú)占的硬件資源。但是spinlock保持期間將使搶占失效,用spinlock保護(hù)的區(qū)域稱為臨界區(qū)(Critical Section),在內(nèi)核中大量地使用了spinlock,有大量的臨界區(qū)存在,因此它們將嚴(yán)重地影響著系統(tǒng)的實(shí)時(shí)性。為此使用mutex來(lái)替換spinlock,它的意圖是讓spinlock可搶占,但是可搶占后將產(chǎn)生很多后續(xù)影響。
Spinlock失效搶占的目的是避免死鎖。Spinlock如果可搶占了,一個(gè)spinlock的競(jìng)爭(zhēng)者將可能搶占該spinlock的保持者來(lái)運(yùn)行,但是由于得不到spinlock將自旋在那里,如果競(jìng)爭(zhēng)者的優(yōu)先級(jí)高于保持者的優(yōu)先級(jí),將形成一種死鎖的局面,因?yàn)楸3终邿o(wú)法得到運(yùn)行而永遠(yuǎn)不能釋放spinlock,而競(jìng)爭(zhēng)者由于不能得到一個(gè)不可能釋放的spinlock而永遠(yuǎn)自旋在那里。
由于中斷處理函數(shù)也可以使用spinlock,如果它使用的spinlock已經(jīng)被一個(gè)進(jìn)程保持,中斷處理函數(shù)將無(wú)法繼續(xù)進(jìn)行,從而形成死鎖,這樣的spinlock在使用時(shí)應(yīng)當(dāng)中斷失效來(lái)避免這種死鎖的情況發(fā)生。標(biāo)準(zhǔn)linux內(nèi)核就是這么做的,中斷線程化之后,中斷失效就沒有必要,因?yàn)橛龅竭@種狀況后,中斷線程將掛在等待隊(duì)列上并放棄CPU讓別的線程或進(jìn)程來(lái)運(yùn)行。
等待隊(duì)列就是解決這種死鎖僵局的方法,讓每個(gè)spinlock都有一個(gè)等待隊(duì)列,該等待隊(duì)列是按進(jìn)程或線程的優(yōu)先級(jí)排隊(duì)的。如果一個(gè)進(jìn)程或線程競(jìng)爭(zhēng)的spinlock已經(jīng)被另一個(gè)線程保持,它將把自己掛在該spinlock的優(yōu)先級(jí)化的等待隊(duì)列上,然后發(fā)生調(diào)度把CPU讓給別的進(jìn)程或線程。
5、優(yōu)先級(jí)繼承和死鎖檢測(cè)
spinlock被mutex化后會(huì)產(chǎn)生優(yōu)先級(jí)逆轉(zhuǎn)(Priority Inversion)現(xiàn)象。所謂優(yōu)先級(jí)逆轉(zhuǎn),就是優(yōu)先級(jí)高的進(jìn)程由于優(yōu)先級(jí)低的進(jìn)程保持了競(jìng)爭(zhēng)資源被迫等待,而讓中間優(yōu)先級(jí)的進(jìn)程運(yùn)行,優(yōu)先級(jí)逆轉(zhuǎn)將導(dǎo)致高優(yōu)先級(jí)進(jìn)程的搶占延遲增大,中間優(yōu)先級(jí)的進(jìn)程的執(zhí)行時(shí)間的不確定性導(dǎo)致了高優(yōu)先級(jí)進(jìn)程搶占延遲的不確定性,因此為了保證實(shí)時(shí)性,必須消除優(yōu)先級(jí)逆轉(zhuǎn)現(xiàn)象。
優(yōu)先級(jí)繼承協(xié)議(Priority Inheritance Protocol)和優(yōu)先級(jí)頂棚協(xié)議(Priority Ceiling Protocol)就是專門針對(duì)優(yōu)先級(jí)逆轉(zhuǎn)問(wèn)題提出的解決辦法。
所謂優(yōu)先級(jí)繼承,就是spinlock的保持者將繼承高優(yōu)先級(jí)的競(jìng)爭(zhēng)者進(jìn)程的優(yōu)先級(jí),從而能先于中間優(yōu)先級(jí)進(jìn)程運(yùn)行,盡可能快地釋放鎖,這樣高優(yōu)先級(jí)進(jìn)程就能很快得到競(jìng)爭(zhēng)的spinlock,使得搶占延遲更確定,更短。
所謂優(yōu)先級(jí)頂棚,就是根據(jù)靜態(tài)分析確定一個(gè)spinlock的可能擁有者的最高優(yōu)先級(jí),然后把spinlock的優(yōu)先級(jí)頂棚設(shè)置為該確定的值,每次當(dāng)進(jìn)程獲得該spinlock后,就將該進(jìn)程的優(yōu)先級(jí)設(shè)置為spinlock的優(yōu)先級(jí)頂棚值。
Spinlock被mutex化后引入的另一個(gè)問(wèn)題就是死鎖,典型的死鎖有兩種:
一種為自鎖,即一個(gè)spinlock保持者試圖獲得它已經(jīng)保持的鎖,很顯然,這會(huì)導(dǎo)致該進(jìn)程無(wú)法運(yùn)行而死鎖。另一種為非順序鎖而導(dǎo)致的,即進(jìn)程P1已經(jīng)保持了spinlock LOCKA但是要獲得進(jìn)程P2已經(jīng)保持的spinlock LOCKB,而進(jìn)程P2要獲得進(jìn)程P1已經(jīng)保持的spinlock LOCKA,這樣進(jìn)程P1和P2都將因?yàn)樾枰玫綄?duì)方擁有的但永遠(yuǎn)不可能釋放的spinlock而死鎖。對(duì)這兩種情況都要進(jìn)行檢測(cè),一旦發(fā)生這種死鎖,內(nèi)核將輸出死鎖執(zhí)行路徑并panic。
大內(nèi)核鎖(BKL---Big Kernel Lock)實(shí)質(zhì)上也是spinlock,只是它一般用于保護(hù)整個(gè)內(nèi)核,該鎖的保持時(shí)間比較長(zhǎng),因此它對(duì)整個(gè)系統(tǒng)的實(shí)時(shí)性影響是非常大的,大內(nèi)核鎖使用了semaphore來(lái)實(shí)現(xiàn),如果內(nèi)核配置為前面三種搶占模式,struct semaphore是架構(gòu)相關(guān)的,如對(duì)于x86,結(jié)構(gòu)定義如下:
struct semaphore {
atomic_t count;
int sleepers;
wait_queue_head_t wait;
};
但對(duì)于第四種搶占模式,其結(jié)構(gòu)為:
struct semaphore {
atomic_t count;
struct rt_mutex lock;
};
注意新的spinlock定義也包含字段struct rt_mutex lock,因此可搶占大內(nèi)核鎖和新的spinlock共用了低層的處理代碼。使用semaphore之后,大內(nèi)核鎖就可搶占了。
7、結(jié)論
Linux實(shí)時(shí)性能的逐步完善,必將大大促進(jìn)嵌入式Linux在工業(yè)控制、后PC時(shí)代信息電器等領(lǐng)域的廣泛應(yīng)用,應(yīng)用的需要也會(huì)進(jìn)一步促進(jìn)大量新型實(shí)時(shí)算法的出現(xiàn)。通過(guò)對(duì)Linux的改動(dòng),就可以開發(fā)出一種可靠的且廉價(jià)的硬實(shí)時(shí)操作系統(tǒng),具有很好的發(fā)展和應(yīng)用前景。本文作者的創(chuàng)新點(diǎn):通過(guò)改進(jìn)延遲,優(yōu)先級(jí)繼承并增加搶占機(jī)制,改善了系統(tǒng)的實(shí)時(shí)性,為嵌入式系統(tǒng)開發(fā)打下了基礎(chǔ)。
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論