文獻(xiàn)標(biāo)識(shí)碼: A
DOI:10.16157/j.issn.0258-7998.172506
中文引用格式: 李亞爽,姬希娜,王振,等. Nucleus PLUS自旋鎖測(cè)試方法研究[J].電子技術(shù)應(yīng)用,2018,44(1):37-40.
英文引用格式: Li Yashuang,Ji Xina,Wang Zhen,et al. Study on spin lock test in Nucleus PLUS[J]. Application of Electronic Technique,2018,44(1):37-40.
0 引言
Nucleus PLUS是美國(guó)源代碼操作系統(tǒng)商品ATI公司推出的新一代搶先式多任務(wù)嵌入式操作系統(tǒng),具有高移植性,并能夠支持大多數(shù)類型的處理器[1]。對(duì)稱多處理器是指一個(gè)計(jì)算機(jī)上有多個(gè)處理器,各處理器共享內(nèi)存子系統(tǒng)以及總線結(jié)構(gòu)[2]。與傳統(tǒng)操作系統(tǒng)不同的是,嵌入式操作系統(tǒng)對(duì)系統(tǒng)響應(yīng)時(shí)間的實(shí)時(shí)性要求非常高。在對(duì)稱多處理器環(huán)境下,同步、互斥、中斷都非常重要,為解決資源的競(jìng)爭(zhēng)、共享問題,提出了典型自旋鎖等機(jī)制來保證同步問題。
在電力設(shè)備產(chǎn)品中使用的操作系統(tǒng)大多是Nucleus嵌入式操作系統(tǒng),在產(chǎn)品運(yùn)行過程中出現(xiàn)過產(chǎn)品死鎖現(xiàn)象,經(jīng)過問題查找發(fā)現(xiàn)是自旋鎖的使用不當(dāng)造成的死鎖。因此針對(duì)自旋鎖的使用展開了重點(diǎn)測(cè)試。
通過詳細(xì)分析自旋鎖代碼及實(shí)現(xiàn)機(jī)制,對(duì)自旋鎖如何進(jìn)行測(cè)試提供了詳細(xì)的測(cè)試思路及測(cè)試方法。
1 Nucleus PLUS內(nèi)核簡(jiǎn)介
Nucleus PLUS內(nèi)核是操作系統(tǒng)的核心,主要負(fù)責(zé)管理實(shí)時(shí)任務(wù)之間的競(jìng)爭(zhēng)運(yùn)行、系統(tǒng)內(nèi)存的分配以及如何回收等,同時(shí)對(duì)外部事件必須保持快速響應(yīng),以實(shí)現(xiàn)其實(shí)時(shí)性,保證系統(tǒng)的性能和穩(wěn)定性。Nucleus PLUS的系統(tǒng)結(jié)構(gòu)如圖1所示。
線程控制部件用來管理實(shí)時(shí)任務(wù)和高級(jí)中斷服務(wù)的執(zhí)行,它是Nucleus嵌入式實(shí)時(shí)操作系統(tǒng)最核心的部分。在系統(tǒng)任務(wù)控制方面,根據(jù)優(yōu)先級(jí)及時(shí)間片共享處理器。通過任務(wù)之間的同步和互斥來選擇不同的通信機(jī)制。內(nèi)存機(jī)制采用了兩種方法:動(dòng)態(tài)內(nèi)存和分區(qū)內(nèi)存。Nucleus PLUS將這些組件稱為軟件組件,并提供了很多系統(tǒng)調(diào)用方法。
2 Nucleus PLUS自旋鎖機(jī)制
2.1 自旋鎖簡(jiǎn)介
對(duì)于單處理器來說,防止中斷處理中的并發(fā)可簡(jiǎn)單采用關(guān)閉中斷的方式,即在標(biāo)志寄存器中關(guān)閉/打開中斷標(biāo)志位,不需要自旋鎖。而對(duì)于多處理器環(huán)境下,為了解決同一時(shí)刻多任務(wù)同時(shí)訪問內(nèi)核和其他資源,保證內(nèi)核、進(jìn)程及其他資源有秩序、正確地執(zhí)行,引入新的一種鎖的機(jī)制,即“自旋鎖”。自旋鎖是專為防止多處理器并發(fā)而引入的一種鎖,它在內(nèi)核中大量應(yīng)用于中斷處理,以及解決多處理器環(huán)境下不同處理器之間存在的同步與互斥問題。
2.2 自旋鎖與信號(hào)量對(duì)比
自旋鎖和信號(hào)量都是解決互斥問題的基本手段,屬于不同層次的互斥手段。自旋鎖與信號(hào)量相似,都用于互斥訪問臨界資源,但是自旋鎖不會(huì)引起調(diào)用者睡眠,不需要進(jìn)入等待隊(duì)列。如果自旋鎖已經(jīng)被別的任務(wù)所持有,調(diào)用者就一直循環(huán)檢測(cè)直至自旋鎖的持有者釋放該自旋鎖,節(jié)省了任務(wù)從睡眠狀態(tài)到喚醒之間內(nèi)核會(huì)產(chǎn)生的消耗,在加鎖時(shí)間短暫的情況下會(huì)大大提高處理器的使用效率。表1列出了兩者之間的不同點(diǎn)。
自旋鎖在使用中,無論自旋鎖還是信號(hào)量,任何時(shí)刻最多只能有一個(gè)持有者。自旋鎖提供的是一種低開銷加鎖選擇,避免了信號(hào)量中任務(wù)阻塞或喚醒時(shí)任務(wù)情景切換而產(chǎn)生的開銷,更適用于中斷服務(wù)處理和任務(wù)之間共享同一資源的情況。
3 Nucleus PLUS自旋鎖測(cè)試
3.1 測(cè)試環(huán)境
測(cè)試環(huán)境由PC、仿真器、目標(biāo)系統(tǒng)組成。測(cè)試環(huán)境構(gòu)成如圖2所示。
編程環(huán)境采用Sourcery CodeBench集成開發(fā)環(huán)境,將編譯好的目標(biāo)文件通過TFTP方式下載到目標(biāo)機(jī)上。PC通過網(wǎng)口或者串口與仿真器連接,實(shí)現(xiàn)與目標(biāo)板卡之間的通信及監(jiān)測(cè)數(shù)據(jù)。仿真器與目標(biāo)機(jī)通過JTAG接口連接,目標(biāo)板卡采用雙核ARM9處理器。
測(cè)試驅(qū)動(dòng)在整個(gè)測(cè)試過程中很關(guān)鍵,經(jīng)過對(duì)自旋鎖機(jī)制深刻研究,編寫出用于控制測(cè)試用例執(zhí)行的驅(qū)動(dòng)程序,如圖3所示。
驅(qū)動(dòng)程序主要包含:測(cè)試用例數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì),如何調(diào)用自旋鎖相關(guān)代碼的接口,返回自旋鎖相關(guān)函數(shù)的返回值,各種全局變量信息以及輸出信息數(shù)據(jù)結(jié)構(gòu)的打印。測(cè)試用例數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)的好壞將直接影響測(cè)試用例的執(zhí)行效率。輸出的數(shù)據(jù)結(jié)構(gòu)信息可以在用例執(zhí)行過程中實(shí)時(shí)觀察數(shù)據(jù)變化信息,幫助記錄任務(wù)執(zhí)行某個(gè)運(yùn)行節(jié)點(diǎn)下的內(nèi)核對(duì)象狀態(tài),便于監(jiān)測(cè)測(cè)試結(jié)果的正確性,從而快速地對(duì)問題進(jìn)行準(zhǔn)確定位及回歸測(cè)試。
3.2 測(cè)試思路
在Nucleus PLUS中,自旋鎖是一個(gè)互斥設(shè)備,只有加鎖和解鎖兩個(gè)狀態(tài)。任務(wù)或中斷處理程序請(qǐng)求自旋鎖時(shí),如果該鎖為解鎖狀態(tài),則嘗試將該自旋鎖置為加鎖狀態(tài),如果加鎖成功,代碼繼續(xù)進(jìn)入臨界區(qū)。如果該鎖為加鎖狀態(tài),則代碼進(jìn)入忙循環(huán),此狀態(tài)不是休眠,并重復(fù)檢查這個(gè)鎖,直到該鎖可用為止。即使多個(gè)任務(wù)在某時(shí)間內(nèi)自旋,也只有一個(gè)任務(wù)能夠獲取該鎖[3]。
在設(shè)計(jì)測(cè)試用例時(shí),主要就是如何設(shè)計(jì)任務(wù)和中斷之間在不同優(yōu)先級(jí)、不同時(shí)間段申請(qǐng)和釋放自旋鎖。下面設(shè)計(jì)了幾種綜合的用例場(chǎng)景,要注意任務(wù)、中斷在不同的執(zhí)行順序下結(jié)果是不同的。
(1)用例場(chǎng)景1:當(dāng)多任務(wù)同時(shí)申請(qǐng)自旋鎖,無中斷任務(wù)申請(qǐng)自旋鎖情況下,每個(gè)任務(wù)執(zhí)行順序如圖4所示。這種情況下在任務(wù)1申請(qǐng)自旋鎖成功后可重復(fù)申請(qǐng)此自旋鎖,也只有在任務(wù)1重復(fù)釋放此自旋鎖后,其他任務(wù)才可以申請(qǐng)自旋鎖成功。
(2)用例場(chǎng)景2:當(dāng)任務(wù)采用試探性try方式申請(qǐng)自旋鎖,并且此自旋鎖處于加鎖狀態(tài),那么任務(wù)不再忙等。執(zhí)行過程如圖5所示。
當(dāng)任務(wù)采用可被中斷方式申請(qǐng)自旋鎖時(shí),根據(jù)任務(wù)和中斷是否在同一個(gè)處理器上,所產(chǎn)生的結(jié)果是不同的。
(3)用例場(chǎng)景3:當(dāng)任務(wù)和中斷在不同CPU上,采用可被中斷方式申請(qǐng)自旋鎖時(shí),中斷申請(qǐng)自旋鎖成功。如圖6所示。
(4)用例場(chǎng)景4:當(dāng)任務(wù)和中斷在同一CPU上,采用可被中斷方式申請(qǐng)自旋鎖時(shí),由于任務(wù)無法釋放自旋鎖,中斷一直忙等,最終產(chǎn)生死鎖現(xiàn)象。如圖7所示。
當(dāng)任務(wù)采用“關(guān)中斷”方式申請(qǐng)自旋鎖時(shí),就會(huì)在申請(qǐng)自旋鎖前先把中斷關(guān)閉,不會(huì)產(chǎn)生死鎖現(xiàn)象。
對(duì)自旋鎖的測(cè)試可以按照這種用例設(shè)計(jì)場(chǎng)景的方式,將自旋鎖的所有函數(shù)的正常、異常及邊界功能測(cè)試完整。
3.3 測(cè)試用例設(shè)計(jì)
整個(gè)測(cè)試過程采用單元測(cè)試、集成測(cè)試相結(jié)合的方法進(jìn)行,采用最常用的等價(jià)類劃分、邊界值等方法對(duì)自旋鎖進(jìn)行白盒測(cè)試。隨著自旋鎖的創(chuàng)建、申請(qǐng)、釋放、刪除等操作的發(fā)生,自旋鎖的狀態(tài)也在不斷變化。也可采用有限狀態(tài)機(jī)對(duì)自旋鎖建立模型,提取路徑設(shè)計(jì)用例,充分地對(duì)自旋鎖的實(shí)現(xiàn)機(jī)制進(jìn)行測(cè)試。同時(shí)也要對(duì)接口的一些異常輸入或者邊界環(huán)境條件下能保持正常工作的情況進(jìn)行測(cè)試,從而保證對(duì)接口能夠進(jìn)行全面化的測(cè)試。
在設(shè)計(jì)測(cè)試用例過程中,首先要設(shè)計(jì)正常功能的測(cè)試用例,然后設(shè)計(jì)異常測(cè)試用例,觀察函數(shù)內(nèi)部是否進(jìn)行了異常判斷,最后集成幾個(gè)接口配合進(jìn)行整體功能測(cè)試,檢查接口之間的相互操作是否正確。下面列出對(duì)自旋鎖相關(guān)接口設(shè)計(jì)的測(cè)試用例。
(1)自旋鎖創(chuàng)建及刪除接口。
正常創(chuàng)建自旋鎖,創(chuàng)建一個(gè)已經(jīng)創(chuàng)建的自旋鎖,異常創(chuàng)建。
(2)自旋鎖申請(qǐng)及釋放接口。
分多種用例場(chǎng)景進(jìn)行測(cè)試,主要考慮表2所示幾個(gè)方面。
(3)自旋鎖“關(guān)中斷”方式申請(qǐng)、釋放與自旋鎖的申請(qǐng)、釋放功能類似,測(cè)試過程中除了要把功能相似的用例執(zhí)行一遍,還要把功能不同點(diǎn)重點(diǎn)測(cè)試。不同之處表現(xiàn)在以下幾點(diǎn):
①在獲取鎖之前關(guān)中斷,釋放鎖后將中斷狀態(tài)恢復(fù)至原來狀態(tài)。
②不支持同一任務(wù)多次加鎖同一個(gè)鎖。
③線程在被自旋鎖保護(hù)的臨界區(qū)不會(huì)被打斷,避免了死鎖。
(4)試探性自旋鎖的申請(qǐng)、釋放與自旋鎖不同的是,申請(qǐng)加鎖時(shí)如果鎖的狀態(tài)時(shí)是“加鎖”,則不再忙等。
(5)“關(guān)中斷”試探性自旋鎖的申請(qǐng)、釋放與試探性自旋鎖不同的是,申請(qǐng)鎖時(shí)會(huì)保存中斷狀態(tài),如果請(qǐng)求失敗,會(huì)恢復(fù)原來的中斷狀態(tài)。
(6)返回自旋鎖創(chuàng)建個(gè)數(shù)函數(shù)、自旋鎖信息函數(shù)、返回自旋鎖指針函數(shù):
①創(chuàng)建多個(gè)自旋鎖,查看返回自旋鎖個(gè)數(shù)、自旋鎖的信息及自旋鎖指針的正確性。
②刪除某個(gè)自旋鎖后,查看返回自旋鎖個(gè)數(shù)、自旋鎖的信息及自旋鎖指針的正確性。
③創(chuàng)建0個(gè)自旋鎖、無效自旋鎖等異常測(cè)試用例設(shè)計(jì)。
3.4 自旋鎖測(cè)試效果
使用上述測(cè)試策略對(duì)自旋鎖所有接口函數(shù)進(jìn)行了白盒測(cè)試,測(cè)試效果很顯著,不僅對(duì)自旋鎖的基本功能進(jìn)行了驗(yàn)證,還對(duì)異常、死鎖情況進(jìn)行分析,實(shí)現(xiàn)了功能、代碼語句全覆蓋。
測(cè)試過程中也發(fā)現(xiàn)一些問題,以及某些接口在使用過程需要注意的事項(xiàng),避免因使用不當(dāng)產(chǎn)生死鎖等問題,造成應(yīng)用平臺(tái)功能不可用。下面列出了幾條自旋鎖使用中的注意事項(xiàng)。
(1)自旋鎖申請(qǐng)、釋放函數(shù)接口的使用是不安全的,容易導(dǎo)致死鎖[3]。由于這個(gè)接口在使用時(shí)是不關(guān)閉中斷,使用時(shí)應(yīng)注意以下幾點(diǎn):使用自旋鎖進(jìn)行同步的多個(gè)任務(wù)不要綁定到一個(gè)處理器上,臨界區(qū)盡可能小,臨界區(qū)不要睡眠,任務(wù)的優(yōu)先級(jí)不宜有差別。
(2)使用關(guān)中斷的自旋鎖在釋放時(shí),傳入的中斷狀態(tài)應(yīng)設(shè)置為申請(qǐng)自旋鎖之前的中斷狀態(tài),而不應(yīng)簡(jiǎn)單通過傳入0值去開中斷。否則在嵌套使用自旋鎖時(shí)會(huì)導(dǎo)致死鎖。申請(qǐng)自旋鎖時(shí),關(guān)中斷僅僅關(guān)閉了本處理器的中斷,另一個(gè)處理器上的中斷仍然產(chǎn)生。
(3)試探性方式申請(qǐng)自旋鎖時(shí),應(yīng)根據(jù)返回值來做相應(yīng)的處理。當(dāng)返回值為此自旋鎖已被占用時(shí),不能訪問被保護(hù)的臨界資源。
4 結(jié)論
本文重點(diǎn)研究了在Nucleus PLUS對(duì)稱多處理機(jī)嵌入式操作系統(tǒng)的環(huán)境下,運(yùn)用多種測(cè)試方法設(shè)計(jì)全面測(cè)試用例,對(duì)自旋鎖組件進(jìn)行白盒測(cè)試。在測(cè)試過程中發(fā)現(xiàn)了在何種情況下自旋鎖會(huì)發(fā)生死鎖現(xiàn)象,同時(shí)詳細(xì)介紹了自旋鎖組件在使用過程中的注意事項(xiàng)。整體測(cè)試效果良好,對(duì)操作系統(tǒng)其他組件的測(cè)試有著較高的借鑒價(jià)值。
參考文獻(xiàn)
[1] 魏振華.嵌入式實(shí)時(shí)操作系統(tǒng)Nucleus中線程控制部件的實(shí)現(xiàn)方法[J].計(jì)算機(jī)應(yīng)用研究,2003(4):97-100.
[2] 彭正文.基于SMP的Linux內(nèi)核自旋鎖分析[J].江西教育學(xué)院學(xué)報(bào)(綜合),2005,26(3):23-28.
[3] 張文盛.一種Linux內(nèi)核自旋鎖死鎖監(jiān)測(cè)機(jī)制的設(shè)計(jì)與實(shí)現(xiàn)[J].合肥學(xué)院學(xué)報(bào),2012,22(2):31-35.
[4] 徐宇柘.Nucleus實(shí)時(shí)操作系統(tǒng)在繼電保護(hù)系統(tǒng)中的實(shí)時(shí)性研究[J].電腦知識(shí)與技術(shù),2007(13):3-5.
[5] 吳雨俊.實(shí)時(shí)操作系統(tǒng)Nucleus的中斷處理機(jī)制研究[J].福建電腦,2012(3):95-96.
[6] 王繼剛.嵌入式操作系統(tǒng)異常處理框架設(shè)計(jì)與實(shí)現(xiàn)[J].電子技術(shù)應(yīng)用,2017,43(5):60-63,66.
[7] 李建軍.國(guó)產(chǎn)化嵌入式操作系統(tǒng)軟件測(cè)試方法研究[J].微型機(jī)與應(yīng)用,2016(24):22-24.