基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法
【專利摘要】本發(fā)明公開了一種基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,實施步驟為:為各處理器建立各自的局部隊列、搶先計數(shù)器、搶先允許狀態(tài),搶先允許狀態(tài)反映處理器的中斷/搶先的開放/禁止情況;為全系統(tǒng)建立全局隊列;為任務(wù)創(chuàng)建搶先列表;被喚醒任務(wù)先存于全局隊列,再為其尋找局部隊列,若找到的處理器已臨時關(guān)閉搶先,則增加其搶先計數(shù)器,并將其加入此任務(wù)的搶先列表,否則將任務(wù)移入相應(yīng)局部隊列;處理器在調(diào)度時根據(jù)其搶先計數(shù)器狀態(tài)決定候選任務(wù)來自哪些隊列;若被調(diào)度執(zhí)行的任務(wù)搶先列表非空,則減少該表所登記處理器的搶先計數(shù)器。本發(fā)明能夠防止操作系統(tǒng)決定搶先“不能馬上實施搶先的優(yōu)先權(quán)”,具有調(diào)度合理、可靠性好、執(zhí)行效率高的優(yōu)點。
【專利說明】基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及計算機操作系統(tǒng)領(lǐng)域,具體涉及一種操作系統(tǒng)用來決定在哪個處理器上運行實時任務(wù)的基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法。
【背景技術(shù)】
[0002]操作系統(tǒng)是計算機系統(tǒng)的基礎(chǔ)軟件。計算機系統(tǒng)開機后,首先執(zhí)行的軟件就是操作系統(tǒng)。操作系統(tǒng)首先會進行系統(tǒng)的初始化(包括啟動各個處理器),然后創(chuàng)建默認要創(chuàng)建的任務(wù)(如各種服務(wù))。在系統(tǒng)運行過程中,用戶還可以動態(tài)要求系統(tǒng)新創(chuàng)建一些任務(wù)。
[0003]由于系統(tǒng)中同時存在的任務(wù)數(shù)量一般會超過處理器數(shù)量,故這些任務(wù)需要按照某種方式來共享使用有限的物理處理器。在計算機系統(tǒng)中,由操作系統(tǒng)的調(diào)度算法來決定“某個處理器當(dāng)前應(yīng)該執(zhí)行哪個任務(wù)”和“某個任務(wù)應(yīng)該由哪個處理器運行”。當(dāng)外部中斷發(fā)生、或當(dāng)前執(zhí)行的任務(wù)主動放棄使用處理器時,調(diào)度算法決定“當(dāng)前處理器應(yīng)運行哪個任務(wù)”,在當(dāng)前正執(zhí)行的任務(wù)通知操作系統(tǒng)“另外某個任務(wù)現(xiàn)在可以運行了”時,調(diào)度算法決定由哪個處理器運行這個剛剛可以運行的任務(wù)。
[0004]任務(wù)在運行時,用戶應(yīng)用邏輯所需要的某些功能(如獲取當(dāng)前時間、打開一個文件、從網(wǎng)絡(luò)接收數(shù)據(jù)),需要通過執(zhí)行操作系統(tǒng)代碼完成。操作系統(tǒng)在為任務(wù)執(zhí)行某些功能時,會要求暫時禁止處理器響應(yīng)外部中斷(后文稱作disablejntr),或暫時禁止“操作系統(tǒng)將當(dāng)前任務(wù)換下去,由另外一個任務(wù)使用當(dāng)前處理器”(后文稱作preempt_disable)。
[0005]在實時計算機系統(tǒng)中,用戶期望任務(wù)能夠在預(yù)期的時刻按照自己預(yù)期的方式執(zhí)行。由于用戶對不同任務(wù)的執(zhí)行時間、執(zhí)行速度的預(yù)期不同,當(dāng)在某個時刻同時有多個任務(wù)需要運行時,需要有一種方法保證系統(tǒng)行為盡可能地符合用戶的預(yù)期。基于實時優(yōu)先權(quán)的調(diào)度就是這樣一種方式。為說明方便,下文假設(shè)實時優(yōu)先權(quán)的取值為整數(shù),且兩個不同的實時優(yōu)先權(quán)在數(shù)值上最少相差1,且當(dāng)兩個任務(wù)同時競爭同一個處理器資源時,操作系統(tǒng)認為高實時優(yōu)先權(quán)的任務(wù)應(yīng)獲得處理器。
[0006]在基于實時優(yōu)先權(quán)調(diào)度的系統(tǒng)中,操作系統(tǒng)實現(xiàn)的調(diào)度器會盡力按照任務(wù)實時優(yōu)先權(quán)的高低來決定哪個任務(wù)先運行。考慮如下情形:T0時刻高實時優(yōu)先權(quán)任務(wù)TASKhigh(以下簡稱TASKhigh)等待接收某事件event,低實時優(yōu)先權(quán)任務(wù)TASKlw (以下簡稱TASKltJ滿足運行條件,故調(diào)度器決定運行任務(wù)TASK1ot ;在晚于TO的某時刻Tl,發(fā)生了事件event,但此時TASKlw仍在運行。在Tl時刻,因需要運行TASKhigh,按照實時系統(tǒng)對用戶的保證,調(diào)度器應(yīng)剝奪實時優(yōu)先權(quán)低于TASKhigh的任務(wù)所擁有的處理器資源,讓TASKhigh任務(wù)運行。比如:調(diào)度器可能會決定剝奪Tasklmt的執(zhí)行權(quán),由TASKhigh使用處理器。若調(diào)度器做出了這樣的決定,則稱作TASKhigh搶先TASK1ot運行,或者說,TASKlow被TASKhigh搶先運行。
[0007]在邏輯上,搶先一般被分為兩步來完成:
[0008]步驟一:將高實時優(yōu)先權(quán)任務(wù)放入待運行隊列,并通知期望運行此任務(wù)的處理器執(zhí)行步驟二(若是本處理器,則無需通知,本處理器會在合適的時機自行執(zhí)行步驟二);
[0009]步驟二:綜合考慮本處理器當(dāng)前正在運行任務(wù)和本處理器對應(yīng)的待運行隊列中的所有任務(wù),選取一個當(dāng)前最應(yīng)該在本處理器上執(zhí)行的任務(wù)。
[0010]在一般實現(xiàn)搶先時,只會有一個處理器會執(zhí)行上述的步驟二,以運行我們關(guān)心的高實時優(yōu)先權(quán)任務(wù)。而步驟一的功能是:決定需要在哪個處理器上執(zhí)行步驟二。
[0011]在一個計算機系統(tǒng)中,很可能會同時運行多個具有不同實時優(yōu)先權(quán)的任務(wù)。當(dāng)上一個任務(wù)TASK_(以下簡稱TASKpH。)由“不需要運行”變?yōu)椤靶枰\行”時,步驟一會試圖找出符合條件CONDA的某個低實時優(yōu)先權(quán)任務(wù)TASKlwest (以下簡稱TASKlwest),然后讓TASKprio搶先TASKlwest。條件CONDA如下:①、當(dāng)前正在某個“允許TASKpH。使用”的處理器上運行、實時優(yōu)先權(quán)低于任務(wù)TASK#。的實時優(yōu)先權(quán)、在所有滿足性質(zhì)①和②的任務(wù)中,TASKlowest的實時優(yōu)先權(quán)最低。
[0012]在具體實現(xiàn)上,待運行任務(wù)隊列有全局隊列和局部隊列兩種實現(xiàn)形式。早期操作系統(tǒng)為全局隊列實現(xiàn)方式,所有的處理器都從單一的全局隊列中獲取任務(wù)運行。由于從全局任務(wù)隊列中獲取任務(wù)需要使用互斥操作,故此種實現(xiàn)方式在處理器數(shù)量較多時性能較差。當(dāng)前操作系統(tǒng)一般采用局部隊列。此時,每個處理器在本地都對應(yīng)一個局部隊列,處理器只從自己對應(yīng)的局部隊列中選取任務(wù)運行。
[0013]在多處理器系統(tǒng)上,這種實現(xiàn)方式有時會造成無效調(diào)度,影響任務(wù)及時運行。原因為:1、操作系統(tǒng)在實現(xiàn)上往往要求任務(wù)在執(zhí)行某段內(nèi)核代碼時不能被搶先;2、操作系統(tǒng)在執(zhí)行某些功能時會把中斷關(guān)閉。若低實時優(yōu)先權(quán)任務(wù)TASKlmrest在某處理器上執(zhí)行I或2對應(yīng)的代碼時,步驟一可能看到TASKlmrest符合條件C0NDA,決定讓高實時優(yōu)先權(quán)任務(wù)TASK#。搶先TASKlwest,而不會搶先實時優(yōu)先權(quán)低于TASKph。、但高于TASKlmtest、正在運行、且可立即被搶先的任務(wù)TASKeanp,。由于任務(wù)TASKpH。沒有被放入運行TASKeanp,的處理器的調(diào)度隊列中,這可能會造成TASKpH。被迫等待較長時間才能獲得運行。
【發(fā)明內(nèi)容】
[0014]本發(fā)明解決的技術(shù)問題是提供一種能夠防止操作系統(tǒng)決定搶先低實時優(yōu)先權(quán)任務(wù)執(zhí)行不能被搶先的代碼,調(diào)度合理、可靠性好、執(zhí)行效率高的基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法。
[0015]為了解決上述技術(shù)問題,本發(fā)明采用的技術(shù)方案為:
[0016]一種基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,其實施步驟如下:
[0017]I)在操作系統(tǒng)系統(tǒng)初始化啟動各個處理器時,為各個處理器建立用于存放確定將在該處理器上運行任務(wù)的局部隊列、用于記錄試圖被搶先次數(shù)的搶先計數(shù)器以及搶先允許狀態(tài),所述搶先允許狀態(tài)用于表示處理器的中斷或搶先的開放/禁止情況;建立用于存放暫時沒有找到合適處理器運行任務(wù)的全局隊列;
[0018]2)將新創(chuàng)建或剛被喚醒的當(dāng)前任務(wù)暫存到全局隊列中,在當(dāng)前任務(wù)在全局隊列被調(diào)度運行時遍歷所有的處理器選擇在哪個處理器上運行當(dāng)前任務(wù),且在選擇處理器時檢查用于記錄各個處理器的搶先允許狀態(tài),避開搶先允許狀態(tài)標(biāo)明中斷或搶先已禁止而不能馬上實施搶先的處理器,若能找到合適的處理器,則將當(dāng)前任務(wù)放入所找到處理器的局部隊列中并跳轉(zhuǎn)執(zhí)行步驟3);否則,將當(dāng)前任務(wù)繼續(xù)停留在全局調(diào)度隊列,并通過搶先計數(shù)器記錄不能馬上實施搶先的處理器的試圖被搶先次數(shù),然后等待下一次在全局隊列被調(diào)度運行;[0019]3)各個處理器分別執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù),在執(zhí)行任務(wù)過程中,如果遇到不允許插入執(zhí)行中斷處理程序的代碼,則通過執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已禁止,返回執(zhí)行所述不允許插入執(zhí)行中斷處理程序的代碼,最終通過執(zhí)行“打開對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已開放;如果遇到不允許插入執(zhí)行的代碼,則修改搶先允許狀態(tài)標(biāo)明搶先已禁止,返回執(zhí)行所述不允許插入執(zhí)行的代碼,最終修改搶先允許狀態(tài)標(biāo)明搶先已開放。
[0020]優(yōu)選地,所述步驟I)中建立用于存放暫時沒有找到合適處理器運行任務(wù)的全局隊列具體是指啟動一個虛擬處理器,針對該虛擬處理器建議一個用于緩存任務(wù)的任務(wù)調(diào)度隊列作為用于存放暫時沒有找到合適處理器運行任務(wù)的全局隊列。
[0021]優(yōu)選地,所述步驟I)中在操作系統(tǒng)系統(tǒng)初始化啟動各個處理器時,分別為每一個處理器分配 sched_cnt、sched_cnt_rwl> try_pr_cnt> pr_dis_cnt、intr_mask_st 信息的存儲空間,其中,schecLcnt用于記錄了從開機至今在此處理器上調(diào)度函數(shù)的執(zhí)行次數(shù),sched_cnt_rwl為一個讀寫鎖,處理器在修改自己對應(yīng)的sched_cnt信息前,需要以“寫”的方式獲得自己對應(yīng)的sched_cnt_rwl,處理器在查看其它處理器對應(yīng)的sched_cnt信息前,需要以“讀”的方式獲得相應(yīng)處理器對應(yīng)的sched_cnt_rwl ;try_pr_cnt用于記錄從本處理器上次執(zhí)行調(diào)度函數(shù)至今,中間有試圖搶先本處理器上的當(dāng)前任務(wù)的任務(wù)數(shù)量;pr_dis_cnt用于記錄此處理器上正在運行的任務(wù)目前凈累積的“禁止搶先請求”次數(shù),若任務(wù)先執(zhí)行了 N次“禁止搶先請求”,接下來執(zhí)行了 N-1次“允許搶先請求”,則此任務(wù)pr_dis_cnt的值為I ;若在pr_dis_cnt為O時,任務(wù)仍然執(zhí)行“允許搶先請求”,則pr_dis_cnt仍然為O ;intr_mask_st為一個枚舉類型變量,值域為{DIS,ΕΝΑ},其值僅受任務(wù)執(zhí)行時的“打開對中斷的響應(yīng)”、“關(guān)閉對中斷的響應(yīng)”兩類操作的影響,任務(wù)在本處理器上執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作后,則intr_mask_st值變?yōu)镈IS ;任務(wù)在本處理器上執(zhí)行“打開對中斷的響應(yīng)”操作后,則intr_mask_st值變?yōu)棣ウ ?br>
[0022]優(yōu)選地,所述步驟2)中將新創(chuàng)建或剛被喚醒的當(dāng)前任務(wù)暫存到全局隊列中之前,還包括為當(dāng)前任務(wù)初始化分配ctab、sched_lock, sched_st, vlistn信息的存儲空間的步驟;其中,ctab為一個列表,用于記錄本任務(wù)所試圖搶先、但因?qū)Ψ浇沽藫屜?,而沒有搶先成功的信息,由于系統(tǒng)中同時運行的任務(wù)個數(shù)不超過在線處理器的數(shù)量,故ctab最多包含的元素個數(shù)不大于在線處理器數(shù)量,ctab記錄的每一項可用<tried_cpu, snapshot〉來表示,其含義為此任務(wù)試圖搶先在處理器triecLcpu上運行的任務(wù),但搶先失敗了,且在失敗時處理器tried_cpu對應(yīng)的sched_cnt值為snapshot ;sched_lock為一個讀寫鎖,在需清除ctab中彳目息時,應(yīng)先獲得寫鎖;在需向ctab中添加彳目息時,應(yīng)先獲得讀鎖,在需為某任務(wù)尋找合適的處理器運行時,應(yīng)先獲得寫鎖;vlistn為一個指向全局隊列中下一個待調(diào)度任務(wù)的指針;SChed_St為一個枚舉類型的變量,用于描述此任務(wù)的執(zhí)行狀態(tài),其值域為{RUN, PRD, INL, ING, SLEP},其中RUN表示該任務(wù)正在運行,PRD表示該任務(wù)原本在運行,但剛剛被搶先,還未放入到待運行隊列中,INL表示該任務(wù)在局部隊列中等待調(diào)度運行,ING表示該任務(wù)在全局隊列中等待調(diào)度運行,SLEP表示該任務(wù)目前還在等待除CPU之外的其它運行條件獲得滿足,新創(chuàng)建的任務(wù)的schecLst默認為SLEP ;所述步驟2)的詳細步驟如下:
[0023]2.1)令預(yù)先建立的用于臨時存儲搶先列表ctab的臨時搶先列表R為空,令當(dāng)前任務(wù)T的搶先列表ctab為空,令變量first_try的值為true、變量low的值為系統(tǒng)所允許的最低優(yōu)先權(quán)、變量high的值為當(dāng)前任務(wù)T的實時優(yōu)先權(quán)減1,將當(dāng)前任務(wù)T對應(yīng)的schecLst信息設(shè)置為ING,其中變量firstjry用于指示是不是第一次就找到了被搶先任務(wù),若變量first_try為true,則說明第一次就找到的任務(wù)沒有禁止掉搶先,傳統(tǒng)的處理邏輯不會影響系統(tǒng)響應(yīng),若變量first_try為false,則說明是當(dāng)前正在運行的最低優(yōu)先級的任務(wù)禁止掉了搶先,系統(tǒng)決定搶先非最低優(yōu)先級任務(wù);變量low是本次循環(huán)中當(dāng)前任務(wù)T考慮可以搶先的任務(wù)最低應(yīng)具有優(yōu)先級;變量high是本次循環(huán)中當(dāng)前任務(wù)T考慮可以搶先的任務(wù)最高應(yīng)具有優(yōu)先級;設(shè)置用于指定執(zhí)行當(dāng)前任務(wù)T的處理器的變量proc的值為所述虛擬處理器;
[0024]2.2)將當(dāng)前任務(wù)T放入全局隊列中;
[0025]2.3)為當(dāng)前任務(wù)T在指定的處理器集合中篩選出所有可運行用戶任務(wù)的處理器集合S,并將篩選得到的處理器集合S保存;
[0026]2.4)判斷處理器集合S是否為空集,如果為空集則跳轉(zhuǎn)執(zhí)行步驟2.22);否則,跳轉(zhuǎn)執(zhí)行下一步;
[0027]2.5)獲得當(dāng)前任務(wù)T應(yīng)當(dāng)搶先的處理器,將得到的處理器放入變量proc中,然后獲得變量proc對應(yīng)處理器上當(dāng)前正在運行的任務(wù)X ;
[0028]2.6)試圖獲取當(dāng)前任務(wù)T對應(yīng)的sched_lock讀鎖,若獲取失敗,則令變量proc的值為虛擬處理器、臨時搶先列表R的值為空,跳轉(zhuǎn)執(zhí)行步驟2.22);否則跳轉(zhuǎn)執(zhí)行下一步;
[0029]2.7)獲取當(dāng)前任務(wù)T的sched_st信息,若當(dāng)前任務(wù)T對應(yīng)的sched_st不是ING,則首先令變量proc的值為虛擬處理器、變量first_try的值為true、臨時搶先列表R的值為空,然后跳轉(zhuǎn)執(zhí)行步驟2.15);否則,跳轉(zhuǎn)執(zhí)行下一步;
[0030]2.8)獲得變量proc對應(yīng)處理器的sched_cnt_rwl讀鎖;
[0031]2.9)讀取變量proc對應(yīng)處理器的sched_cnt信息,將讀取的sched_cnt信息、變量proc對應(yīng)處理器兩者作為一條記錄存入臨時搶先列表R ;
[0032]2.10)獲得變量proc對應(yīng)處理器的try_pr_cnt信息增I ;
[0033]2.11)釋放變量proc對應(yīng)處理器的sched_cnt_rwl讀鎖;
[0034]2.12)判斷變量proc對應(yīng)處理器的pr_dis_cnt信息為O、intr_mask_st信息為ENA兩個條件是否同時成立,如果同時成立則跳轉(zhuǎn)執(zhí)行步驟2.13);否則如果不能同時成立,則釋放當(dāng)前任務(wù)T對應(yīng)的sched_lock讀鎖,從處理器集合S中去掉變量proc對應(yīng)的處理器,然后判斷處理器集合S是否變?yōu)榭占绻幚砥骷蟂不是空集則跳轉(zhuǎn)執(zhí)行步驟2.5);如果處理器集合S是空集,則令變量first_try的值為false、變量low的值為變量proc對應(yīng)的處理器的當(dāng)前實時優(yōu)先權(quán)加1、變量proc的值為所述虛擬處理器,跳轉(zhuǎn)執(zhí)行步驟 2.3);
[0035]2.13)將當(dāng)前任務(wù)T對應(yīng)的sched_st信息設(shè)為INL ;
[0036]2.14)將當(dāng)前任務(wù)T從全局隊列中刪除,并將當(dāng)前任務(wù)T添加至變量proc對應(yīng)處理器的獨步隊列中;
[0037]2.15)釋放當(dāng)前任務(wù)T對應(yīng)的sched_lock讀鎖;
[0038]2.16)判斷變量first_try的值,若first_try的值為true,則跳轉(zhuǎn)執(zhí)行步驟2.22),否則跳轉(zhuǎn)執(zhí)行步驟2.17);
[0039]2.17)獲得變量proc對應(yīng)處理器上當(dāng)前正在運行的任務(wù)X對應(yīng)的sched_lock的讀鎖;[0040]2.18)檢查所述任務(wù)X的sched_st信息,若所述任務(wù)X對應(yīng)的sched_st信息不是RUN狀態(tài),則從處理器集合S中去掉變量proc對應(yīng)的處理器,然后判斷處理器集合S是否變?yōu)榭占?,如果處理器集合S不是空集則跳轉(zhuǎn)執(zhí)行步驟2.5);如果處理器集合S是空集,則令變量first_try的值為false、變量low的值為變量proc對應(yīng)的處理器的當(dāng)前實時優(yōu)先權(quán)加1、變量proc的值為所述虛擬處理器,跳轉(zhuǎn)執(zhí)行步驟2.3);若任務(wù)X對應(yīng)的sched_st信息是RUN狀態(tài),則跳轉(zhuǎn)執(zhí)行下一步;
[0041 ] 2.19)將所述任務(wù)X對應(yīng)的sched_st信息設(shè)為PRD狀態(tài);
[0042]2.20)將臨時搶先列表R的內(nèi)容填寫到所述任務(wù)X的搶先列表ctab中,再令臨時搶先列表R為空;
[0043]2.21)釋放所述任務(wù)X對應(yīng)的sched_lock讀鎖;
[0044]2.22)將臨時搶先列表R復(fù)制到當(dāng)前任務(wù)T的搶先列表ctab中,返回變量proc對應(yīng)處理器即為被選中用于運行當(dāng)前任務(wù)T的處理器。
[0045]優(yōu)選地,所述步驟3)中各個處理器分別選取在當(dāng)前處理器上運行的任務(wù)的詳細步驟如下:
[0046]3.1)獲得當(dāng)前處理器的sched_cnt_rwl寫鎖;
[0047]3.2)將當(dāng)前處理器的sched_cnt信息增1、try_pr_cnt信息設(shè)為O ;
[0048]3.3)釋放當(dāng)前處理器的sched_cnt_rwl寫鎖;
[0049]3.4)獲取當(dāng)前處理器本地的局部隊列中最高實時優(yōu)先權(quán)的任務(wù)放在變量next中,獲取當(dāng)前處理器上正在運行的任務(wù)放在變量curr中;
[0050]3.5)獲取變量curr對應(yīng)任務(wù)的sched_lock寫鎖;
[0051]3.6)判斷變量curr對應(yīng)任務(wù)的sched_st信息,若變量curr對應(yīng)任務(wù)的sched_st信息為PRD,則根據(jù)變量curr對應(yīng)任務(wù)從全局隊列中獲取一個任務(wù)Tg放在變量next中,且獲取的任務(wù)Tg滿足下述條件④?⑥,④任務(wù)Tg的實時優(yōu)先權(quán)高于變量curr對應(yīng)任務(wù)的實時優(yōu)先權(quán);⑤任務(wù)Tg的搶先列表ctab中,當(dāng)前處理器編號對應(yīng)的tried_cpu項中包含有效內(nèi)容;⑥在所有滿足條件④和⑤的所有任務(wù)中,任務(wù)Tg的實時優(yōu)先權(quán)最高;
[0052]3.7)判斷變量next和變量curr是否相同,若變量next和變量curr相同,貝U釋放變量curr對應(yīng)任務(wù)的sched_lock寫鎖,并返回繼續(xù)執(zhí)行變量curr對應(yīng)的任務(wù);否則跳轉(zhuǎn)執(zhí)行下一步;
[0053]3.8)判斷變量curr對應(yīng)任務(wù)的sched_st信息是否為PRD,若curr對應(yīng)任務(wù)的schecLst信息為PRD,則將變量curr對應(yīng)任務(wù)從當(dāng)前處理器的局部隊列中刪除,并將變量curr對應(yīng)任務(wù)添加至全局隊列,然后設(shè)置變量curr對應(yīng)任務(wù)的sched_st信息為ING ;
[0054]3.9)判斷變量curr對應(yīng)任務(wù)是否需要繼續(xù)運行,如果不需要繼續(xù)運行,則設(shè)置變量curr對應(yīng)任務(wù)的schecLst信息為SLEP,將變量curr對應(yīng)任務(wù)從當(dāng)前處理器的局部隊列中刪除,將變量curr對應(yīng)的任務(wù)作為待清除任務(wù),刪除待清除任務(wù)的相關(guān)記錄信息,然后跳轉(zhuǎn)執(zhí)行步驟3.10);如果需要繼續(xù)運行,則直接跳轉(zhuǎn)執(zhí)行步驟3.10);
[0055]3.10)設(shè)置當(dāng)前處理器正在運行的任務(wù)為變量next對應(yīng)的任務(wù);
[0056]3.11)釋放變量curr對應(yīng)任務(wù)的sched_lock寫鎖;
[0057]3.12)判斷變量next對應(yīng)任務(wù)當(dāng)前的sched_lock狀態(tài),若sched_lock狀態(tài)為無鎖或讀鎖,則跳轉(zhuǎn)執(zhí)行步驟3.13);否則,設(shè)置當(dāng)前處理器當(dāng)前運行的任務(wù)為空閑任務(wù),獲取當(dāng)前處理器本地的局部隊列中最高實時優(yōu)先權(quán)的任務(wù)放在變量next中,以變量next對應(yīng)的任務(wù)作為查找失敗的默認返回值從全局隊列中獲取一個任務(wù)Tg放在變量next中,且獲取的任務(wù)Tg滿足下述條件④?⑥,④任務(wù)Tg的實時優(yōu)先權(quán)高于變量curr對應(yīng)任務(wù)的實時優(yōu)先權(quán);⑤任務(wù)Tg的搶先列表ctab中,當(dāng)前處理器編號對應(yīng)的tried_cpu項中包含有效內(nèi)容;⑥在所有滿足條件④和⑤的所有任務(wù)中,任務(wù)Tg的實時優(yōu)先權(quán)最高;設(shè)置當(dāng)前運行的任務(wù)為變量next對應(yīng)的任務(wù),跳轉(zhuǎn)重新執(zhí)行步驟3.12);
[0058]3.13)試圖獲取變量next對應(yīng)任務(wù)的sched_lock寫鎖,若失敗則跳轉(zhuǎn)執(zhí)行步驟
3.12);否則,跳轉(zhuǎn)執(zhí)行步驟3.14);
[0059]3.14)讀取變量next對應(yīng)任務(wù)的sched_st信息,若變量next對應(yīng)任務(wù)的sched_st信息不是PRD,跳轉(zhuǎn)執(zhí)行步驟3.17),否則跳轉(zhuǎn)執(zhí)行步驟3.15);
[0060]3.15)判斷變量next對應(yīng)的任務(wù)是否在全局隊列中,如果在全局隊列中,則設(shè)置變量next對應(yīng)任務(wù)的sched_st信息為ING,否則設(shè)置變量next對應(yīng)任務(wù)的sched_st信息為 INL;
[0061]3.16)釋放變量next對應(yīng)任務(wù)的sched_lock寫鎖,跳轉(zhuǎn)執(zhí)行步驟3.12);
[0062]3.17)將變量next對應(yīng)的任務(wù)作為待清除任務(wù),刪除待清除任務(wù)的相關(guān)記錄信息;
[0063]3.18)判斷變量next對應(yīng)的任務(wù)是否在全局隊列中,如果在全局隊列中,則將變量next對應(yīng)的任務(wù)從全局隊列中刪除,并將變量next對應(yīng)的任務(wù)添加至當(dāng)前處理器的局部隊列,然后跳轉(zhuǎn)執(zhí)行步驟3.19);否則如果不在全局隊列中,則直接跳轉(zhuǎn)執(zhí)行步驟3.19);
[0064]3.19)設(shè)置變量next對應(yīng)的任務(wù)的sched_st信息為RUN ;
[0065]3.20)釋放變量next對應(yīng)的任務(wù)的sched_lock寫鎖,開始執(zhí)行變量next對應(yīng)的任務(wù)。
[0066]優(yōu)選地,所述步驟3.9)和步驟3.17)中刪除待清除任務(wù)的相關(guān)記錄信息的詳細步驟如下:
[0067]3.9.1)檢查待清除任務(wù)的搶先列表ctab中是否包含有效記錄,若待清除任務(wù)的搶先列表ctab中不包含有效記錄,則返回;否則,跳轉(zhuǎn)執(zhí)行步驟3.9.2);
[0068]3.9.2)獲取待清除任務(wù)的搶先列表ctab中的第一個有效記錄,首先將所述有效記錄刪除;
[0069]3.9.3)判斷已刪除有效記錄中的triecLcpu信息是否與本處理器相同,如果是則跳轉(zhuǎn)執(zhí)行步驟3.9.1);否則,跳轉(zhuǎn)執(zhí)行步驟3.9.4);
[0070]3.9.4)獲取已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的sched_cnt_rwl讀鎖;
[0071]3.9.5)讀取已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的sched_cnt信息,如果所述sched_cnt信息的值與已刪除有效記錄中的snapshot的值相同,則將已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的try_pr_cnt信息的值以原子方式減I ;
[0072]3.9.6)釋放已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的sched_cnt_rwl讀鎖;跳轉(zhuǎn)執(zhí)行步驟3.9.1)。
[0073]優(yōu)選地,所述步驟3)中通過執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已禁止的詳細步驟包括:[0074]3.21)將當(dāng)前處理器的intr_mask_st信息設(shè)置為DIS完成執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作,修改搶先允許狀態(tài)標(biāo)明中斷已禁止;
[0075]3.22)判斷當(dāng)前處理器的pr_dis_cnt信息為l、try_pr_cnt不為O兩個條件是否同時不成立,如果兩個條件不能同時成立,則關(guān)閉當(dāng)前處理器對物理中斷的響應(yīng),當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);否則如果兩個條件同時成立,則跳轉(zhuǎn)執(zhí)行下一步;
[0076]3.23)將當(dāng)前處理器的intr_mask_st信息設(shè)置為ENA完成執(zhí)行“打開對中斷的響應(yīng)”操作,修改搶先允許狀態(tài)標(biāo)明中斷已打開;
[0077]3.24)當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù),跳轉(zhuǎn)執(zhí)行步驟3.21);
[0078]優(yōu)選地,所述步驟3)中通過執(zhí)行“打開對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已開放的詳細步驟包括:
[0079]3.25)打開當(dāng)前處理器對物理中斷的響應(yīng);
[0080]3.26)將當(dāng)前處理器的intr_mask_st信息設(shè)置為ENA完成執(zhí)行“打開對中斷的響應(yīng)”操作,修改搶先允許狀態(tài)標(biāo)明中斷已打開;
[0081]3.27)判斷當(dāng)前處理器的pr_dis_cnt信息為0、try_pr_cnt不為O兩個條件是否同時不成立,如果兩個條件不能同時成立,當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);否則如果兩個條件同時成立,則當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù)。
[0082]優(yōu)選地,所述步驟3)中修改搶先允許狀態(tài)標(biāo)明搶先已禁止的詳細步驟如下:
[0083]3.28)將當(dāng)前處理器的pr_dis_cnt信息的值增I ;
[0084]3.29)判斷當(dāng)前處理器的pr_dis_cnt信息的值為1、try_pr_cnt信息的值不為
O、intr_mask_st信息的值為ENA三個條件是否同時成立,如果同時成立則跳轉(zhuǎn)執(zhí)行步驟
3.30);否則,當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);
[0085]3.30)將當(dāng)前處理器的pr_dis_cnt信息的值設(shè)置為O ;
[0086]3.31)當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù),跳轉(zhuǎn)執(zhí)行步驟3.28);
[0087]所述步驟3)中修改搶先允許狀態(tài)標(biāo)明搶先已開放的詳細步驟如下:
[0088]3.32)將當(dāng)前處理器的pr_dis_cnt信息的值減I ;
[0089]3.33)判斷當(dāng)前處理器的pr_dis_cnt信息的值為0、try_pr_cnt信息的值不為O、intr_mask_st信息的值為ENA三個條件是否同時成立,如果三個條件同時成立,貝U跳轉(zhuǎn)執(zhí)行步驟3.34);否則,當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);
[0090]3.34)當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù)。
[0091]本發(fā)明基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法具有下述技術(shù)效果:與傳統(tǒng)調(diào)度算法只有一個全局隊列或完全分布的局部隊列不同,本發(fā)明采取局部隊列與全局隊列相結(jié)合,各處理器對應(yīng)的局部隊列中存放確定將在該處理器上運行的任務(wù),全局隊列存放暫時沒有找到合適處理器運行的任務(wù),形成兩級混合任務(wù)調(diào)度,在此兩級混合任務(wù)調(diào)度的基礎(chǔ)上,根據(jù)搶先允許狀態(tài)為任務(wù)選擇處理器,各個處理器分別執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù),則根據(jù)處理器的搶先允許狀態(tài)以及任務(wù)的優(yōu)先級別等狀態(tài)信息對任務(wù)進行中斷或搶先操作,能夠防止操作系統(tǒng)決定搶先低實時優(yōu)先權(quán)任務(wù)執(zhí)行不能被搶先的代碼,具有調(diào)度合理、可靠性好、執(zhí)行效率高的優(yōu)點。
【專利附圖】
【附圖說明】[0092]圖1為本發(fā)明實施例方法的基本實施流程示意圖。
[0093]圖2為本發(fā)明實施例步驟2)的實施流程示意圖。
[0094]圖3為本發(fā)明實施例步驟3)中各個處理器執(zhí)行任務(wù)的實施流程示意圖。
[0095]圖4為本發(fā)明實施例中刪除待清除任務(wù)的相關(guān)記錄信息的實施流程示意圖。
[0096]圖5為本發(fā)明實施例中disable_intr函數(shù)的實施流程示意圖。
[0097]圖6為本發(fā)明實施例中enable_intr函數(shù)的實施流程示意圖。
[0098]圖7為本發(fā)明實施例中preempt_disable函數(shù)的實施流程示意圖。
[0099]圖8為本發(fā)明實施例中preempt_enable函數(shù)的實施流程示意圖。
[0100]圖9為本發(fā)明實施例中schecLst信息的狀態(tài)變遷示意圖。
[0101]圖10為本發(fā)明實施例中各個接口的調(diào)用流程示意圖。
【具體實施方式】
[0102]如圖1所示,本實施例基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法的實施步驟如下:
[0103]I)在操作系統(tǒng)系統(tǒng)初始化啟動各個處理器時,為各個處理器建立用于存放確定將在該處理器上運行任務(wù)的局部隊列、用于記錄試圖被搶先次數(shù)的搶先計數(shù)器以及搶先允許狀態(tài),所述搶先允許狀態(tài)用于表示處理器的中斷或搶先的開放/禁止情況;建立用于存放暫時沒有找到合適處理器運行任務(wù)的全局隊列;
[0104]2)將新創(chuàng)建或剛被喚醒的當(dāng)前任務(wù)暫存到全局隊列中,在當(dāng)前任務(wù)在全局隊列被調(diào)度運行時遍歷所有的處理器選擇在哪個處理器上運行當(dāng)前任務(wù),且在選擇處理器時檢查用于記錄各個處理器的搶先允許狀態(tài),避開搶先允許狀態(tài)標(biāo)明中斷或搶先已禁止而不能馬上實施搶先的處理器,若能找到合適的處理器,則將當(dāng)前任務(wù)放入所找到處理器的局部隊列中并跳轉(zhuǎn)執(zhí)行步驟3);否則,將當(dāng)前任務(wù)繼續(xù)停留在全局調(diào)度隊列,并通過搶先計數(shù)器記錄不能馬上實施搶先的處理器的試圖被搶先次數(shù),然后等待下一次在全局隊列被調(diào)度運行;
[0105]3)各個處理器分別執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù),在執(zhí)行任務(wù)過程中,如果遇到不允許插入執(zhí)行中斷處理程序的代碼,則通過執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已禁止,返回執(zhí)行所述不允許插入執(zhí)行中斷處理程序的代碼,最終通過執(zhí)行“打開對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已開放;如果遇到不允許插入執(zhí)行的代碼,則修改搶先允許狀態(tài)標(biāo)明搶先已禁止,返回執(zhí)行所述不允許插入執(zhí)行的代碼,最終修改搶先允許狀態(tài)標(biāo)明搶先已開放。
[0106]本實施例按照模塊包括初始化模塊、本地調(diào)度模塊,中斷狀態(tài)切換模塊,搶先狀態(tài)改變模塊,被搶先任務(wù)選取模塊。其中,初始化模塊包括提供init_cpu、init_rt_task、init_rt_intr三個接口,init_cpu接口供操作系統(tǒng)添加可用處理器資源時使用,init_rt_task供操作系統(tǒng)在創(chuàng)建實時任務(wù)、或?qū)⑷蝿?wù)從非實時任務(wù)改變?yōu)閷崟r任務(wù)時使用、init_rt_intr供用戶將實時相關(guān)中斷綁定到預(yù)留處理器上,這個處理器僅被用于響應(yīng)中斷信號,而不執(zhí)行用戶任務(wù)和中斷的具體處理邏輯。在一般的實現(xiàn)中,可以預(yù)留系統(tǒng)內(nèi)編號最大的處理器做此用途。系統(tǒng)為此處理器分配中斷完成緩沖區(qū),用于供其它處理器通知此處理器已處理完成的中斷。
[0107]本實施例中,init_rt_intr的處理流程為:步驟1、為本處理器安裝中斷轉(zhuǎn)發(fā)處理程序;步驟2、為本處理器安裝中斷完成處理程序;步驟3、調(diào)用操作系統(tǒng)功能,將物理中斷都綁定到被預(yù)留的處理器上。當(dāng)此處理器接收到外部設(shè)備的中斷后,執(zhí)行中斷轉(zhuǎn)發(fā)處理程序,其流程為:步驟1、關(guān)閉處理器對物理中斷的響應(yīng);步驟2、若中斷為電平式的,則在本處理器禁止此中斷源;步驟3、向用戶設(shè)定的處理器集合轉(zhuǎn)發(fā)此中斷;步驟4、開放處理器對物理中斷的響應(yīng)。當(dāng)其它處理器完成中斷處理后,執(zhí)行“中斷完成”通知流程:步驟1、向中斷完成緩沖區(qū)中寫入完成的中斷號;步驟2、向預(yù)留處理器發(fā)送“中斷處理完成”中斷。當(dāng)預(yù)留處理器接收到其它處理器發(fā)來的中斷處理完成中斷后,執(zhí)行中斷處理完成處理程序,其流程為:步驟1、關(guān)閉處理器對物理中斷的響應(yīng);步驟2、若中斷完成緩沖區(qū)為空,則轉(zhuǎn)到步驟6 ;步驟3、獲得一個已完成中斷號;步驟4、開放處理器對于此中斷號對應(yīng)中斷的響應(yīng);步驟
5、轉(zhuǎn)到步驟2 ;步驟6、放開處理器對物理中斷的響應(yīng);步驟7、處理結(jié)束。
[0108]本實施例中,步驟I)中具體是調(diào)用init_cpu、init_rt_intr兩個接口進行操作,用于對各個處理器進行初始化(init_cpu)、對實時中斷處理相關(guān)例程進行設(shè)置
intr)。步驟2)在通過調(diào)用init_rt_task接口完成,用于對實時任務(wù)進行初始化。init_cpu的處理流程為:步驟1、為本處理器分配sched_cnt、sched_cnt_rwl、try_pr_cnt、pr_dis_cnt、intr_mask_st信息的存儲空間;步驟2、將sched_cnt_rwl設(shè)置為“未上鎖”,將intr_mask_st 設(shè)置為 ΕΝΑ,將 sched_cnt、try_pr_cnt、pr_dis_cnt 均設(shè)置為 O ;步驟 3、返回。init_rt_task 的處理流程為:步驟 1、為本任務(wù)分配 ctab、sched_lock, sched_st, vlistn這些變量所需的空間;步驟2、將ctab初始化為“不包含任何有效記錄”,sched_lock設(shè)置為“未上鎖”,sched_st設(shè)置為SLEP, vlistn設(shè)置為空;步驟3:返回。
[0109]本實施例中,步驟I)中建立用于存放暫時沒有找到合適處理器運行任務(wù)的全局隊列具體是指啟動一個虛擬處理器,其編號為VIRT,針對該虛擬處理器建議一個用于緩存任務(wù)的任務(wù)調(diào)度隊列作為用于存放暫時沒有找到合適處理器運行任務(wù)的全局隊列virtual_q0全局隊列virtual_q為所有處理器都可以從中取任務(wù)的全局隊列,全局隊列初始不包含任何任務(wù)。
[0110]本實施例中,步驟I)中在操作系統(tǒng)系統(tǒng)初始化啟動各個處理器時,分別為每一個處理器分配 sched_cnt、sched_cnt_rwl > try_pr_cnt > pr_di s_cnt > intr_mask_st 信息的存儲空間,本實施例要求操作系統(tǒng)為每個處理器都維護上述信息并保持全系統(tǒng)可見,處理器通過訪問這些信息來獲得其他處理器的狀態(tài),并視情況修改其它處理器所對應(yīng)的信息,以影響其它處理器的調(diào)度行為。上述各個信息的說明如下:
[0111]1.1) schecLcnt用于記錄了從開機至今在此處理器上調(diào)度函數(shù)的執(zhí)行次數(shù)。本實施例中sched_cnt使用64位表示,當(dāng)使用64位表示此變量、且初始值設(shè)置為O時,可認為此變量具有單調(diào)遞增性質(zhì)。
[0112]1.2) sched_cnt_rwl為一個讀寫鎖,處理器在修改自己對應(yīng)的sched_cnt信息前,需要以“寫”的方式獲得自己對應(yīng)的sChed_Cnt_rwl,處理器在查看其它處理器對應(yīng)的sched_cnt信息前,需要以“讀”的方式獲得相應(yīng)處理器對應(yīng)的sched_cnt_rwl。
[0113]1.3) try_pr_cnt用于記錄從本處理器上次執(zhí)行調(diào)度函數(shù)至今,中間有試圖搶先本處理器上的當(dāng)前任務(wù)的任務(wù)數(shù)量。
[0114]1.4)pr_diS_Cnt用于記錄此處理器上正在運行的任務(wù)目前凈累積的“禁止搶先請求”次數(shù),若任務(wù)先執(zhí)行了 N次“禁止搶先請求”,接下來執(zhí)行了 N-1次“允許搶先請求”,則此任務(wù)pr_dis_cnt的值為I ;若在pr_dis_cnt為O時,任務(wù)仍然執(zhí)行“允許搶先請求”,則pr_dis_cnt 仍然為 O。
[0115]1.5) intr_mask_st為一個枚舉類型變量,值域為{DIS,ΕΝΑ},其值僅受任務(wù)執(zhí)行時的“打開對中斷的響應(yīng)”、“關(guān)閉對中斷的響應(yīng)”兩類操作的影響,任務(wù)在本處理器上執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作后,則intr_mask_st值變?yōu)镈IS ;任務(wù)在本處理器上執(zhí)行“打開對中斷的響應(yīng)”操作后,則intr_mask_st值變?yōu)棣ウ ?br>
[0116]本實施例中,步驟2)中將新創(chuàng)建或剛被喚醒的當(dāng)前任務(wù)暫存到全局隊列中之前,還包括為當(dāng)前任務(wù)初始化分配ctab、sched_lock, sched_st, vlistn信息的存儲空間的步驟通過調(diào)用init_rt_task接口完成,用于對實時任務(wù)進行初始化。本實施例要求操作系統(tǒng)為每個有實時要求任務(wù)維護上述信息,且上述信息的具體說明如下:
[0117]2.Dctab為一個列表,用于記錄本任務(wù)所試圖搶先、但因?qū)Ψ浇沽藫屜?,而沒有搶先成功的信息,由于系統(tǒng)中同時運行的任務(wù)個數(shù)不超過在線處理器的數(shù)量,故ctab最多包含的元素個數(shù)不大于在線處理器數(shù)量,ctab記錄的每一項可用<tried_cpu, snapshot〉來表示,其含義為此任務(wù)試圖搶先在處理器triecLcpu上運行的任務(wù),但搶先失敗了,且在失敗時處理器tried_cpu對應(yīng)的sched_cnt值為snapshot。
[0118]2.2) sched_lock為一個讀寫鎖,在需清除ctab中彳目息時,應(yīng)先獲得寫鎖;在需向ctab中添加信息時,應(yīng)先獲得讀鎖,在需為某任務(wù)尋找合適的處理器運行時,應(yīng)先獲得寫鎖。
[0119]2.3)vlistn為一個指向全局隊列中下一個待調(diào)度任務(wù)的指針。
[0120]2.4) schecLst為一個枚舉類型的變量,用于描述此任務(wù)的執(zhí)行狀態(tài),其值域為{RUN, PRD, INL, ING, SLEP},其中RUN表示該任務(wù)正在運行,PRD表示該任務(wù)原本在運行,但剛剛被搶先,還未放入到待運行隊列中,INL表示該任務(wù)在局部隊列中等待調(diào)度運行,ING表示該任務(wù)在全局隊列中等待調(diào)度運行,SLEP表示該任務(wù)目前還在等待除CPU之外的其它運行條件獲得滿足,新創(chuàng)建的任務(wù)的sched_st默認為SLEP。
[0121]本實施例中,步驟2)則作為被搶先任務(wù)選取模塊封裝在select_fittest_cpu接口供調(diào)用,在調(diào)度任務(wù)運行時,使用SeleCt_fitteSt_Cpu確定任務(wù)將在哪個調(diào)度隊列中排隊等待運行。被搶先任務(wù)選取模塊負責(zé)實現(xiàn)當(dāng)有任務(wù)剛被喚醒時“選擇在哪個處理器上運行此任務(wù)”的問題,因正在運行的任務(wù)與處理器之間存在一一對應(yīng)關(guān)系,故可將“選取被搶先的任務(wù)”與“選取搶先哪個處理器上的任務(wù)”視為等價。本實施例中解決“選取搶先哪個處理器上的任務(wù)”問題時,定義處理器的當(dāng)前實時優(yōu)先權(quán)與當(dāng)前正在其上運行的任務(wù)的實時優(yōu)先權(quán)相等。被搶先任務(wù)選取模塊對外提供select_fittest_cpu接口,其輸入?yún)?shù)包括剛被喚醒的待運行的高優(yōu)先權(quán)任務(wù)T、用戶實現(xiàn)聲明的、允許任務(wù)T可以使用的處理器的集合AFFINITY。本接口供操作系統(tǒng)的調(diào)度相關(guān)代碼選擇最適宜運行高優(yōu)先權(quán)任務(wù)T的處理器。
[0122]如圖2所示,本實施例中步驟2) (select_fittest_cpu接口函數(shù))的詳細步驟如下:
[0123]2.1)執(zhí)行R — Φ令預(yù)先建立的用于臨時存儲搶先列表ctab的臨時搶先列表R為空,執(zhí)行ctab — Φ令當(dāng)前任務(wù)T的搶先列表ctab為空,令變量first_try的值為true、變量low的值為系統(tǒng)所允許的最低優(yōu)先權(quán)MIN_PR10、變量high的值為當(dāng)前任務(wù)T的實時優(yōu)先權(quán)減 I (即 first_try — true, low — MIN_PR10, high — PRIO (T) -1),將當(dāng)前任務(wù) T 對應(yīng)的sched_st信息設(shè)置為ING,其中變量first_try用于指示是不是第一次就找到了被搶先任務(wù),若變量first_try為true,則說明第一次就找到的任務(wù)沒有禁止掉搶先,傳統(tǒng)的處理邏輯不會影響系統(tǒng)響應(yīng),若變量first_try為false,則說明是當(dāng)前正在運行的最低優(yōu)先級的任務(wù)禁止掉了搶先,系統(tǒng)決定搶先非最低優(yōu)先級任務(wù);變量low是本次循環(huán)中當(dāng)前任務(wù)T考慮可以搶先的任務(wù)最低應(yīng)具有優(yōu)先級;變量high是本次循環(huán)中當(dāng)前任務(wù)T考慮可以搶先的任務(wù)最高應(yīng)具有優(yōu)先級;執(zhí)行proc — VIRT設(shè)置用于指定執(zhí)行當(dāng)前任務(wù)T的處理器的變量proc的值為虛擬處理器;R與Ctab的含義相同,由于在本函數(shù)執(zhí)行完成前,不能確定到底是修改哪個任務(wù)的ctab,故此時先將ctab的內(nèi)容放到R,待到確定了具體的任務(wù)后,再將R的值復(fù)制到此任務(wù)的ctab。first_try指示是不是第一次就找到了被搶先任務(wù)。若first_try為true,則說明第一次就找到的任務(wù)沒有禁止掉搶先,傳統(tǒng)的處理邏輯不會影響系統(tǒng)響應(yīng);Sfirstjry為false,則說明是“當(dāng)前正在運行的最低優(yōu)先級的任務(wù)禁止掉了搶先,系統(tǒng)決定搶先非最低優(yōu)先級任務(wù)”。low和high是本次循環(huán)中,任務(wù)T考慮可以搶先的任務(wù)最低應(yīng)具有優(yōu)先級low,最高應(yīng)具有優(yōu)先級high。proc為最終決定在哪個處理器上運行任務(wù)T,若找不到合適的處理器,則其值為VIRT,表示應(yīng)將此任務(wù)放入全局調(diào)度隊列中。若找到了,則任務(wù)T會被放入此處理器的局部調(diào)度隊列中。
[0124]2.2)執(zhí)行enqueue_virt (T)將當(dāng)前任務(wù)T放入全局隊列中。
[0125]2.3)執(zhí)行S — get_cands (AFFINITY, low, high)為當(dāng)前任務(wù)T在指定的處理器集合AFFINITY中篩選出所有可運行用戶任務(wù)的處理器集合S,并將篩選得到的處理器集合S保存。
[0126]2.4)判斷處理器集合S是否為空集,如果為空集則跳轉(zhuǎn)執(zhí)行步驟2.22);否則,跳轉(zhuǎn)執(zhí)行下一步。
[0127]2.5)執(zhí)行proc — get_fittest (S)獲得當(dāng)前任務(wù)T應(yīng)當(dāng)搶先的處理器,將得到的處理器放入變量proc中,然后執(zhí)行X — get_cur (proc)獲得變量proc對應(yīng)處理器上當(dāng)前正在運行的任務(wù)X。
[0128]2.6)試圖獲取當(dāng)前任務(wù)T對應(yīng)的sched_lock讀鎖(T.sched_lock),若獲取失敗,則執(zhí)行Proc — VIRT、R — Φ,令變量proc的值為虛擬處理器(proc — VIRT)、臨時搶先列表R的值為空(R — Φ),跳轉(zhuǎn)執(zhí)行步驟2.22);否則跳轉(zhuǎn)執(zhí)行下一步。
[0129]2.7)獲取當(dāng)前任務(wù)T的sched_st信息,若當(dāng)前任務(wù)T對應(yīng)的sched_st (T.sched_st)不是ING,則首先令變量proc的值為虛擬處理器(proc — VIRT)、變量first_try的值為true (first_try — true)、臨時搶先列表R的值為空(R — Φ),然后跳轉(zhuǎn)執(zhí)行步驟2.15);否貝U,跳轉(zhuǎn)執(zhí)行下一步。
[0130]2.8)獲得變量 proc 對應(yīng)處理器的 sched_cnt_rwl 讀鎖(proc.sched_cnt_rwl)。
[0131]2.9)讀取變量proc對應(yīng)處理器的sched_cnt信息(proc.sched_cnt)作為變量snap_cnt,將讀取的sched_cnt信息(變量snap_cnt)、變量proc對應(yīng)處理器兩者作為一條記錄存入臨時搶先列表R(R — R+?proc, snap_cnt>})。
[0132]2.10)獲得變量proc對應(yīng)處理器的try_pr_cnt信息增I。
[0133]2.11)釋放變量 proc 對應(yīng)處理器的 sched_cnt_rwl 讀鎖(proc.sched_cnt_rwl)。
[0134]2.12)判斷變量 proc 對應(yīng)處理器的 pr_dis_cnt 信息(proc.pr_dis_cnt)為 O、intr_mask_st信息(proc.1ntr_mask_st)為ENA兩個條件是否同時成立,如果同時成立則跳轉(zhuǎn)執(zhí)行步驟2.13);否則如果不能同時成立,則釋放當(dāng)前任務(wù)T對應(yīng)的schecLlock讀鎖(T.sched_lock),從處理器集合S中去掉變量proc對應(yīng)的處理器(S — S-{proc}),然后判斷處理器集合S是否變?yōu)榭占?,如果處理器集合S不是空集則跳轉(zhuǎn)執(zhí)行步驟2.5);如果處理器集合S是空集,則令變量first_try的值為false (first_try — false)、變量low的值為變量proc對應(yīng)的處理器的當(dāng)前實時優(yōu)先權(quán)加I (low —PRIOC(proc)+1)、變量proc的值為虛擬處理器(proc — VIRT),跳轉(zhuǎn)執(zhí)行步驟2.3)。
[0135]2.13)將當(dāng)前任務(wù)T對應(yīng)的sched_st信息設(shè)為INL。
[0136]2.14)執(zhí)行dequeue_virt (T)將當(dāng)前任務(wù)T從全局隊列中刪除,并執(zhí)行enqueue_local (T)將當(dāng)前任務(wù)T添加至變量proc對應(yīng)處理器的獨步隊列中。
[0137]2.15)釋放當(dāng)前任務(wù)T對應(yīng)的sched_lock讀鎖。
[0138]2.16)判斷變量first_try的值,若first_try的值為true,則跳轉(zhuǎn)執(zhí)行步驟2.22),否則跳轉(zhuǎn)執(zhí)行步驟2.17)。
[0139]2.17)獲得變量proc對應(yīng)處理器上當(dāng)前正在運行的任務(wù)X對應(yīng)的sched_lock的讀鎖;
[0140]2.18)檢查任務(wù)X的sched_st信息,若任務(wù)X對應(yīng)的sched_st信息不是RUN狀態(tài),則從處理器集合S中去掉變量proc對應(yīng)的處理器(S — S-{pix)C}),然后判斷處理器集合S是否變?yōu)榭占?,如果處理器集合S不是空集則跳轉(zhuǎn)執(zhí)行步驟2.5);如果處理器集合S是空集,則令變量first_try的值為false (first_try — false)、變量low的值為變量proc對應(yīng)的處理器的當(dāng)前實時優(yōu)先權(quán)加I (low —PRIOC(proc)+1)、變量proc的值為虛擬處理器(proc — VIRT),跳轉(zhuǎn)執(zhí)行步驟2.3);若任務(wù)X對應(yīng)的sched_st信息是RUN狀態(tài),則跳轉(zhuǎn)執(zhí)行下一步。
[0141]2.19)將任務(wù)X對應(yīng)的sched_st信息設(shè)為PRD狀態(tài)。
[0142]2.20)將臨時搶先列表R的內(nèi)容填寫到任務(wù)X的搶先列表ctab中,再令臨時搶先列表R為空(R — Φ)。
[0143]2.21)釋放任務(wù)X對應(yīng)的sched_lock讀鎖。
[0144]2.22)將臨時搶先列表R復(fù)制到當(dāng)前任務(wù)T的搶先列表ctab中,返回變量proc對應(yīng)處理器即為被選中用于運行當(dāng)前任務(wù)T的處理器。
[0145]本實施例中,步驟2.1)?2.22)應(yīng)通過關(guān)閉搶先等方式,保證以上步驟2.1)?
2.22)在執(zhí)行時不會被另外的任務(wù)打斷。其中,函數(shù)PRIO (TASKx)返回任務(wù)TASKx的實時優(yōu)先權(quán),函數(shù)PRIOC (CPUx)返回處理器CPUx的當(dāng)前實時優(yōu)先權(quán)。函數(shù)get_cands(TASK_AFFINITY,PR10_L0ff,PR10_HIGH)返回一個處理器的集合,函數(shù)get_cands要求這個集合包含、且僅包含所有滿足如下條件的處理器core: l)core在集合TASK_AFFINITY中;2)PRIOC(core) > =PR10_L0W,且PRIOC (core)〈 = PR10_HIGH ;3)對于任意滿足以上性質(zhì)I)和性質(zhì)2)的處理器 core’,不等式 PRIOC (core,)> = PRIOC (core)成立。函數(shù) get_fittest (S)的輸入為處理器集合S,輸出為一個在S中的處理器,函數(shù)get_fitteSt為從處理器集合S中選擇一個處理器所使用的傳統(tǒng)方法。函數(shù)get_CUr(p)返回當(dāng)前正在處理器P上運行的任務(wù)。需要說明的是,上述函數(shù)的實現(xiàn)均為本領(lǐng)的公知手段,因此本實施例不再對其進行詳細說明。
[0146]本實施例中,步驟3)則作為本地調(diào)度模塊封裝在new_schedule接口供調(diào)用,該接口用于實現(xiàn)調(diào)度器中“選取哪個任務(wù)在當(dāng)前處理器上運行”的功能。此外,任務(wù)在執(zhí)行過程中,可能需要暫時的關(guān)閉中斷,以防止中斷處理程序干擾任務(wù)運行,此時則需要調(diào)用中斷狀態(tài)切換模塊;任務(wù)也有可能需要暫時禁止任務(wù)搶先機制,以執(zhí)行不允許其它任務(wù)插入執(zhí)行的代碼,此時則需要調(diào)用搶先狀態(tài)改變模塊。
[0147]設(shè)系統(tǒng)中有PO?P3共4個處理器。任務(wù)A實時優(yōu)先權(quán)為80,可以在處理器P2和處理器P3上運行;任務(wù)C實時優(yōu)先權(quán)為70,可以在處理器P3、處理器P2、處理器PO上運行,當(dāng)前正運行于處理器P3 ;任務(wù)D實時優(yōu)先權(quán)為60,可以在處理器P2和處理器P3上運行,當(dāng)前正運行于處理器P2 ;任務(wù)B的實時優(yōu)先權(quán)為75,可以在處理器Pl上運行;任務(wù)A當(dāng)前正睡眠;處理器PO上當(dāng)前正在運行的任務(wù)優(yōu)先權(quán)為90 ;任務(wù)B現(xiàn)在要喚醒任務(wù)A。下面針對四種不同情形,對本實施例中select_fittest_cpu接口函數(shù)的進行舉例說明:
[0148]場景1:處理器P2允許搶先、中斷開放。此時為標(biāo)準(zhǔn)情形,無論是否采用本實施例中的select_fittest_cpu接口函數(shù)的方法,任務(wù)A都將搶先處理器P2上的任務(wù)。
[0149]場景2:處理器P2不允許搶先,或中斷被關(guān)閉,處理器P3允許搶先、中斷開放。該場景下,如果不采用本實施例中的select_fittest_cpu接口函數(shù)的方法,任務(wù)A將試圖搶先處理器P2上的當(dāng)前任務(wù),由于不能成功,任務(wù)A被迫等待;如果采用本實施例中的SeleCt_fittest_cpu接口函數(shù)的方法,則任務(wù)A將增加處理器P2的搶先計數(shù),將處理器P2加入任務(wù)A的搶先列表,然后考察處理器P3,發(fā)現(xiàn)處理器P3上運行的任務(wù)C可被搶先,則將任務(wù)A的搶先任務(wù)列表表項移動到任務(wù)C的搶先列表;然后任務(wù)A搶先處理器P3上的當(dāng)前任務(wù),從而可以立即執(zhí)行。當(dāng)處理器P2允許搶先時,它發(fā)現(xiàn)自己的搶先計數(shù)不為0,從全局隊列和局部隊列中選取最應(yīng)該執(zhí)行的任務(wù),假設(shè)為任務(wù)C,調(diào)度運行之。另一種可能是:在處理器P2允許搶先前,處理器PO上的任務(wù)放棄使用CPU,或者降低優(yōu)先權(quán),拉取高優(yōu)先權(quán)任務(wù)C,調(diào)度執(zhí)行之,任務(wù)C在被調(diào)度時減少處理器P2的搶先計數(shù),從而處理器P2在允許搶先時不再檢查是否需要進行調(diào)度。
[0150]場景3:處理器P2、處理器P3均不允許搶先,或中斷被關(guān)閉;處理器P2先開放搶先,處理器P3緊接著開放搶先。該場景下,如果不采用本實施例中的select_fittest_cpu接口函數(shù)的方法,任務(wù)A將試圖搶先處理器P2上的當(dāng)前任務(wù),由于不能成功,任務(wù)A被迫等待;如果采用本實施例中的select_fittest_cpu接口函數(shù)的方法,任務(wù)A被喚醒時發(fā)現(xiàn)無法搶先處理器P2和處理器P3,增加處理器P2和處理器P3的搶先計數(shù)器值,并將處理器P2和處理器P3放入任務(wù)A的搶先列表中,然后被放入全局隊列中;在處理器P2開放搶先時,發(fā)現(xiàn)自己的搶先計數(shù)器的計數(shù)不為0,從全局隊列和局部隊列中選取最應(yīng)該在本處理器上運行的任務(wù),假設(shè)該任務(wù)為任務(wù)A,任務(wù)A搶先處理器P2上的任務(wù),并根據(jù)搶先列表,減小處理器P3的搶先計數(shù)。這樣在處理器P3開放搶先時,不會發(fā)現(xiàn)有人試圖搶先,從而不會運行額外的調(diào)度處理。
[0151]場景4:處理器P2、處理器P3均不允許搶先,或中斷被關(guān)閉;處理器P3先開放搶先,處理器P2緊接著開放搶先。該場景下,采用本實施例中的select_fittest_cpu接口函數(shù)的方法時,任務(wù)A被喚醒時發(fā)現(xiàn)無法搶先處理器P2和處理器P3,增加處理器P2和處理器P3的搶先計數(shù)器值,并將處理器P2和處理器P3放入任務(wù)A的搶先列表中,然后被放入全局隊列中;在處理器P3開放搶先時,發(fā)現(xiàn)自己的搶先計數(shù)不為0,從全局隊列和局部隊列中選取最應(yīng)該在本處理器上運行的任務(wù),假設(shè)為任務(wù)A,任務(wù)A搶先處理器P3上的任務(wù),并根據(jù)搶先列表,減小處理器P2的搶先計數(shù),然后為根據(jù)任務(wù)C的搶先列表,增加列表中處理器的搶先計數(shù),這樣當(dāng)處理器P2開放搶先時,任務(wù)C可獲得執(zhí)行。
[0152]如圖3所示,本實施例中步驟3)中各個處理器分別選取在當(dāng)前處理器上運行的任務(wù)的詳細步驟如下:
[0153]3.1)獲得當(dāng)前處理器的sched_cnt_rwl寫鎖。
[0154]3.2)將當(dāng)前處理器的sched_cnt信息增1、try_pr_cnt信息設(shè)為O (try_pr_cnt 一 O) ο
[0155]3.3)釋放當(dāng)前處理器的sched_cnt_rwl寫鎖。
[0156]3.4)執(zhí)行next — get_local O獲取當(dāng)前處理器本地的局部隊列中最高實時優(yōu)先權(quán)的任務(wù)放在變量next中,執(zhí)行curr — get_curp O獲取當(dāng)前處理器上正在運行的任務(wù)放在變量curr中;其中,“一”表示賦值操作,下文中的含義相同。
[0157]3.5)獲取變量curr對應(yīng)任務(wù)的sched_lock寫鎖。
[0158]3.6)判斷變量curr對應(yīng)任務(wù)的sched_st信息curr.sched_st,若變量curr對應(yīng)任務(wù)的 sched_st 信息 curr.sched_st 為 PRD,貝U執(zhí)行 next — get_global (next)根據(jù)變量curr對應(yīng)任務(wù)從全局隊列中獲取一個任務(wù)Tg放在變量next中,且獲取的任務(wù)Tg滿足下述條件④?⑥,④任務(wù)Tg的實時優(yōu)先權(quán)高于變量curr對應(yīng)任務(wù)的實時優(yōu)先權(quán);⑤任務(wù)Tg的搶先列表ctab中,當(dāng)前處理器編號對應(yīng)的tried_cpu項中包含有效內(nèi)容;⑥在所有滿足條件④和⑤的所有任務(wù)中,任務(wù)Tg的實時優(yōu)先權(quán)最高。
[0159]3.7)判斷變量next和變量curr是否相同,若變量next和變量curr相同,貝U釋放變量curr對應(yīng)任務(wù)的sched_lock寫鎖,并返回繼續(xù)執(zhí)行變量curr對應(yīng)的任務(wù);否則跳轉(zhuǎn)執(zhí)行下一步。
[0160]3.8)判斷變量curr對應(yīng)任務(wù)的sched_st信息是否為PRD,若curr對應(yīng)任務(wù)的sched_st信息為PRD,則執(zhí)行dequeue_local (cur)將變量curr對應(yīng)任務(wù)從當(dāng)前處理器的局部隊列中刪除,并執(zhí)行enqueue_virt (cur)將變量curr對應(yīng)任務(wù)添加至全局隊列,然后設(shè)置變量curr對應(yīng)任務(wù)的sched_st信息為ING。
[0161]3.9)判斷變量curr對應(yīng)任務(wù)是否需要繼續(xù)運行,如果不需要繼續(xù)運行,則設(shè)置變量curr對應(yīng)任務(wù)的sched_st信息為SLEP,執(zhí)行dequeue_local (curr)將變量curr對應(yīng)任務(wù)從當(dāng)前處理器的局部隊列中刪除,將變量curr對應(yīng)的任務(wù)作為待清除任務(wù),執(zhí)行clear_record (curr)刪除待清除任務(wù)的相關(guān)記錄信息,然后跳轉(zhuǎn)執(zhí)行步驟3.10);如果需要繼續(xù)運行,則直接跳轉(zhuǎn)執(zhí)行步驟3.10)。
[0162]3.10)設(shè)置當(dāng)前處理器正在運行的任務(wù)為變量next對應(yīng)的任務(wù)。
[0163]3.11)釋放變量curr對應(yīng)任務(wù)的sched_lock寫鎖。
[0164]3.12)判斷變量next對應(yīng)任務(wù)當(dāng)前的sched_lock狀態(tài),若sched_lock狀態(tài)為無鎖或讀鎖,則跳轉(zhuǎn)執(zhí)行步驟3.13);否則,設(shè)置當(dāng)前處理器當(dāng)前運行的任務(wù)為空閑任務(wù)idle,執(zhí)行next — get_local O獲取當(dāng)前處理器本地的局部隊列中最高實時優(yōu)先權(quán)的任務(wù)放在變量next中,執(zhí)行next — get_global (next)以變量next對應(yīng)的任務(wù)作為查找失敗的默認返回值從全局隊列中獲取一個任務(wù)Tg放在變量next中,且獲取的任務(wù)Tg滿足下述條件④?⑥,④任務(wù)Tg的實時優(yōu)先權(quán)高于變量curr對應(yīng)任務(wù)的實時優(yōu)先權(quán);⑤任務(wù)Tg的搶先列表ctab中,當(dāng)前處理器編號對應(yīng)的tried_cpu項中包含有效內(nèi)容;⑥在所有滿足條件④和⑤的所有任務(wù)中,任務(wù)Tg的實時優(yōu)先權(quán)最高;設(shè)置當(dāng)前運行的任務(wù)為變量next對應(yīng)的任務(wù),跳轉(zhuǎn)重新執(zhí)行步驟3.12)。
[0165]3.13)試圖獲取變量next對應(yīng)任務(wù)的sched_lock寫鎖,若失敗則跳轉(zhuǎn)執(zhí)行步驟
3.12);否則,跳轉(zhuǎn)執(zhí)行步驟3.14)。
[0166]3.14)讀取變量next對應(yīng)任務(wù)的sched_st信息next.sched_st,若變量next對應(yīng)任務(wù)的sched_st信息next.sched_st不是PRD,跳轉(zhuǎn)執(zhí)行步驟3.17),否則跳轉(zhuǎn)執(zhí)行步驟
3.15)。
[0167]3.15)判斷變量next對應(yīng)的任務(wù)是否在全局隊列中,如果在全局隊列中,則設(shè)置變量next對應(yīng)任務(wù)的sched_st信息為ING,否則設(shè)置變量next對應(yīng)任務(wù)的sched_st信息為 INL;
[0168]3.16)釋放變量next對應(yīng)任務(wù)的sched_lock寫鎖,跳轉(zhuǎn)執(zhí)行步驟3.12)。
[0169]3.17)將變量next對應(yīng)的任務(wù)作為待清除任務(wù),執(zhí)行clear_record (next)刪除待清除任務(wù)的相關(guān)記錄/[目息。
[0170]3.18)判斷變量next對應(yīng)的任務(wù)是否在全局隊列中,如果在全局隊列中,則執(zhí)行dequeue_virt (next)將變量next對應(yīng)的任務(wù)從全局隊列中刪除,并執(zhí)行enqueue_local (next)將變量next對應(yīng)的任務(wù)添加至當(dāng)前處理器的局部隊列,然后跳轉(zhuǎn)執(zhí)行步驟
3.19);否則如果不在全局隊列中,則直接跳轉(zhuǎn)執(zhí)行步驟3.19)。
[0171]3.19)設(shè)置變量next對應(yīng)的任務(wù)的sched_st信息為RUN。
[0172]3.20)釋放變量next對應(yīng)的任務(wù)的sched_lock寫鎖,開始執(zhí)行變量next對應(yīng)的任務(wù)。
[0173]上述步驟3.1)?3.20)中,函數(shù)get_local為獲取本地的局部調(diào)度隊列中最高實時優(yōu)先權(quán)的任務(wù)。函數(shù)enqueue_local (Tg)為將任務(wù)Tg從添加到本地調(diào)度隊列,函數(shù)dequeue_local (Tl)為將任務(wù)Tl從本地調(diào)度隊列刪除。函數(shù)enqueue_virt (TASKx)為將TASKx放入全局隊列virtual_q ;函數(shù)dequeue_virt (TASKk)為將TASKk任務(wù)從全局隊列virtual_q 中刪除,函數(shù) enqueue_virt (TASKx)和 dequeue_virt (TASKk) —般可以將其實現(xiàn)為單向鏈表,通過原子執(zhí)行“比較交換”操作來達到對于鏈表的無鎖插入和刪除。函數(shù)get_global (TASKstd)為獲取全局隊列virtual_q隊列中的一個滿足條件CONDB的任務(wù)Tg,若沒有找到這樣的Tg,則get_global返回任務(wù)TASKstd。條件CONDB:①實時優(yōu)先權(quán)高于任務(wù)TASKstd的實時優(yōu)先權(quán)此任務(wù)對應(yīng)的ctab中,當(dāng)前處理器編號對應(yīng)的項中包含有效內(nèi)容;③在所有滿足性質(zhì)①②的任務(wù)中,Tg的實時優(yōu)先權(quán)最高。函數(shù)get_curp()返回當(dāng)前處理器上正在運行的任務(wù)。需要說明的是,上述函數(shù)的實現(xiàn)均為本領(lǐng)的公知手段,因此本實施例不再對其進行詳細說明。
[0174]如圖4所示,本實施例中步驟3.9)和步驟3.17)中執(zhí)行clear_record函數(shù)刪除待清除任務(wù)的相關(guān)記錄信息的詳細步驟如下:
[0175]3.9.1)檢查待清除任務(wù)task的搶先列表ctabtask.ctab中是否包含有效記錄,若待清除任務(wù)的搶先列表ctabtask.ctab中不包含有效記錄,則返回;否則,跳轉(zhuǎn)執(zhí)行步驟
3.9.2);
[0176]3.9.2)獲取待清除任務(wù)的搶先列表ctab中的第一個有效記錄(有效記錄的表現(xiàn)形式為<tried_cpu, snapshot〉,其含義為此任務(wù)試圖搶先在處理器tried_cpu上運行的任務(wù),但搶先失敗了,且在失敗時處理器tried_cpu對應(yīng)的sched_cnt值為snapshot),首先將有效記錄刪除。
[0177]3.9.3)判斷已刪除有效記錄中的triecLcpu信息是否與本處理器相同,如果是則跳轉(zhuǎn)執(zhí)行步驟3.9.1);否則,跳轉(zhuǎn)執(zhí)行步驟3.9.4)。
[0178]3.9.4)獲取已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的sched_cnt_rwl讀鎖 tried_cpu.sched_cnt_rwl。
[0179]3.9.5)讀取已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的sched_cnt信息tried_cpu.sched_cnt,如果sched_cnt信息的值與已刪除有效記錄中的snapshot的值相同,則將已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的try_pr_cnt信息的值以原子方式減I。
[0180]3.9.6)釋放已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的sched_cnt_rwl讀鎖;跳轉(zhuǎn)執(zhí)行步驟3.9.1)。
[0181]本實施例通過中斷狀態(tài)切換模塊對外提供enable_intr和disable_intr兩個接口。當(dāng)任務(wù)在執(zhí)行時需要暫時關(guān)閉處理器對于中斷的響應(yīng)時,應(yīng)調(diào)用本模塊的disable_intr接口 ;當(dāng)任務(wù)執(zhí)行完不能被中斷程打斷的代碼后,應(yīng)調(diào)用本模塊的enable_intr接口,使得處理器重新可以隨時對中斷做出響應(yīng)。
[0182]如圖5所示,本實施例中步驟3)中通過執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已禁止(調(diào)用disable_intr接口函數(shù)實現(xiàn))的詳細步驟包括:
[0183]3.21)將當(dāng)前處理器的intr_mask_st信息this.1ntr_mask_st設(shè)置為DIS完成執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作,修改搶先允許狀態(tài)標(biāo)明中斷已禁止。
[0184]3.22)判斷當(dāng)前處理器的 pr_dis_cnt 信息(this.pr_dis_cnt)為 1、try_pr_cnt (this.try_pr_cnt)不為0兩個條件是否同時不成立,如果兩個條件不能同時成立,則關(guān)閉當(dāng)前處理器對物理中斷的響應(yīng),當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù),“關(guān)閉對中斷的響應(yīng)”操作執(zhí)行完畢,退出;否則如果兩個條件同時成立,則跳轉(zhuǎn)執(zhí)行下一步。
[0185]3.23)將當(dāng)前處理器的intr_mask_st信息this.1ntr_mask_st設(shè)置為ENA完成執(zhí)行“打開對中斷的響應(yīng)”操作,修改搶先允許狀態(tài)標(biāo)明中斷已打開。
[0186]3.24)當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù)(即調(diào)用newjchedule),跳轉(zhuǎn)執(zhí)行步驟3.21)。
[0187]如圖6所示,本實施例中步驟3)中通過執(zhí)行“打開對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已開放(調(diào)用enable_intr接口函數(shù)實現(xiàn))的詳細步驟包括:
[0188]3.25)打開當(dāng)前處理器對物理中斷的響應(yīng)。
[0189]3.26)執(zhí)行 this.1ntr_mask_st — ENA 將當(dāng)前處理器的 intr_mask_st 信息 this.1ntr_mask_st設(shè)置為ΕΝΑ,完成執(zhí)行“打開對中斷的響應(yīng)”操作,修改搶先允許狀態(tài)標(biāo)明中斷已打開。
[0190]3.27)判斷當(dāng)前處理器的 pr_dis_cnt 信息 this.pr_dis_cnt 為 O、try_pr_cnt (this.try_pr_cnt)不為0兩個條件是否同時不成立,如果兩個條件不能同時成立,當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);否則如果兩個條件同時成立,則當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù)(即調(diào)用newjchedule)。
[0191]本實施例通過搶先狀態(tài)改變模塊提供preempt_enable和preempt_disable兩個接口。當(dāng)任務(wù)在執(zhí)行不能被搶先的代碼前,應(yīng)使用preempt_disable禁止搶先;當(dāng)任務(wù)執(zhí)行完不能被搶先的代碼后,應(yīng)調(diào)用本模塊的preempt_enable接口。
[0192]如圖7所示,本實施例中步驟3)中修改搶先允許狀態(tài)標(biāo)明搶先已禁止(調(diào)用preempt_disable接口函數(shù)實現(xiàn))的詳細步驟如下:
[0193]3.28)將當(dāng)前處理器的 pr_dis_cnt 信息 this.pr_dis_cnt 的值增 I。
[0194]3.29)判斷當(dāng)前處理器的 pr_dis_cnt 信息 this.pr_dis_cnt 的值為 1、try_pr_cnt/[言;窗、this.try_pr_cnt 白勺值不為 O、intr_mask_st/[言;窗、this.1ntr_mask_st 白勺值為 ENA三個條件是否同時成立,如果同時成立則跳轉(zhuǎn)執(zhí)行步驟3.30);否則,當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);
[0195]3.30)將當(dāng)前處理器的pr_dis_cnt信息this.pr_dis_cnt的值設(shè)置為O。
[0196]3.31)當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù)(即調(diào)用newjchedule),跳轉(zhuǎn)執(zhí)行步驟3.28);
[0197]如圖8所示,本實施例中步驟3)中修改搶先允許狀態(tài)標(biāo)明搶先已開放(調(diào)用preempt_enable接口函數(shù)實現(xiàn))的詳細步驟如下:
[0198]3.32)將當(dāng)前處理器的 pr_dis_cnt 信息 this.pr_dis_cnt 的值減 I。
[0199]3.33)判斷當(dāng)前處理器的 pr_dis_cnt 信息 this.pr_dis_cnt 的值為 O、try_pr_cnt/[言;窗、this.try_pr_cnt 白勺值不為 O、intr_mask_st/[言;窗、this.1ntr_mask_st 白勺值為 ENA三個條件是否同時成立,如果三個條件同時成立,則跳轉(zhuǎn)執(zhí)行步驟3.34);否則,當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);
[0200]3.34)當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù)(調(diào)用newjchedule)。
[0201]如圖9所示,本實施例要求操作系統(tǒng)為每個有實時要求任務(wù)維護的sched_st信息為枚舉類型的變量,用于描述此任務(wù)的執(zhí)行狀態(tài)。其值域為{RUN,PRD, INL, ING, SLEP}。RUN表示該任務(wù)正在運行;PRD表示該任務(wù)原本在運行,但剛剛被搶先,還未放入到待運行隊列中;INL表示該任務(wù)在局部調(diào)度隊列中等待調(diào)度運行;ING表示該任務(wù)在全局調(diào)度隊列中等待調(diào)度運行;SLEP表示該任務(wù)目前還在等待除CPU之外的其它運行條件獲得滿足。當(dāng)任務(wù)不需要運行時,處于SLEP狀態(tài);某些外部事件會將該任務(wù)喚醒,將其首先放入全局調(diào)度隊列中,從而轉(zhuǎn)變?yōu)镮NG狀態(tài)。此時調(diào)度器會尋找在哪個處理器上運行此任務(wù),有四種情況:a)確定應(yīng)立即運行此任務(wù),且順利運行,則此任務(wù)進入RUN狀態(tài);b)確定應(yīng)立即運行此任務(wù),但在運行之前就被其它更高優(yōu)先級的任務(wù)搶先,則它進入PRD狀態(tài);c)確定當(dāng)前應(yīng)由另外的某個處理器運行此任務(wù),將此任務(wù)放入對應(yīng)處理器的局部調(diào)度隊列,任務(wù)進入INL狀態(tài)。d)沒有找到合適的處理器運行此任務(wù),此時任務(wù)停留在ING狀態(tài)。INL狀態(tài)的任務(wù)若被成功調(diào)度,則轉(zhuǎn)入RUN狀態(tài),開始運行,也有可能在運行前就被搶先,進入PRD狀態(tài);new_schedule在運行時,發(fā)現(xiàn)剛調(diào)度上來的任務(wù)進入了 PRD狀態(tài),就知道調(diào)度失敗了,將這個任務(wù)重新放入此任務(wù)原來所在的調(diào)度隊列,并將其狀態(tài)更新為相應(yīng)值(ING或INL);處于運行狀態(tài)的任務(wù)若被搶先,則進入PRD狀態(tài);若此任務(wù)暫時不需要處理器,則進入SLEP狀態(tài)。
[0202]如圖10所示,本實施例在操作系統(tǒng)啟動各個處理器后,各個接口調(diào)用步驟如下:I )調(diào)用init_cpu,初始化各個處理器的狀態(tài)信息。II )調(diào)用init_rt_intr,對實時中斷處理相關(guān)例程進行設(shè)置。III)創(chuàng)建任務(wù),調(diào)用init_rt_task,對實時任務(wù)進行初始化。IV)任務(wù)激活后調(diào)度任務(wù)運行,首先調(diào)用SeleCt_fitteSt_Cpu確定任務(wù)將在哪個調(diào)度隊列中排隊等待運行。V )各個處理器分別執(zhí)行分配的任務(wù)。任務(wù)在執(zhí)行過程中,可能需要暫時的關(guān)閉中斷,以防止中斷處理程序干擾任務(wù)運行;任務(wù)也有可能需要暫時禁止任務(wù)搶先機制,以執(zhí)行不允許其它任務(wù)插入執(zhí)行的代碼。在運行不允許插入執(zhí)行中斷處理程序的代碼前,調(diào)用disable_intr接口,在運行不允許插入執(zhí)行中斷處理程序的代碼后,調(diào)用enable_intr接口。在運行不允許其它任務(wù)插入執(zhí)行的代碼前,調(diào)用preempt_disable接口,在運行不允許其它任務(wù)插入執(zhí)行的代碼后,調(diào)用preempt_enable接口。在執(zhí)行內(nèi)核中與任務(wù)相關(guān)的其它功能的時候,則允許搶先和中斷。
[0203]本實施例與傳統(tǒng)調(diào)度算法只有一個全局隊列或完全分布的局部隊列不同,本發(fā)明采取局部隊列與全局隊列相結(jié)合的方法。其中,各處理器對應(yīng)的局部調(diào)度隊列中存放確定將在該處理器上運行的任務(wù);全局調(diào)度隊列存放暫時沒有找到合適處理器運行的任務(wù)。本實施例在為高優(yōu)先權(quán)任務(wù)選取運行的處理器時,先把任務(wù)暫存到全局調(diào)度隊列中,然后檢查處理器狀態(tài)信息,避開該表中標(biāo)明不能馬上實施搶先的處理器(即:中斷或搶先已臨時關(guān)閉),若能找到合適的處理器,則將其放入此處理器的局部調(diào)度隊列中,否則任務(wù)停留在全局調(diào)度隊列,并將不能馬上實施搶先的處理器的試圖被搶先計數(shù)器增I。本實施例任務(wù)在關(guān)閉/打開對中斷的響應(yīng)時,將此中斷的關(guān)閉、打開信息記錄到全系統(tǒng)可見的位置(intr_mask_st信息);任務(wù)在打開/關(guān)閉對搶先的支持時,將此搶先的打開、關(guān)閉信息記錄到全系統(tǒng)可見的位置(pr_dis_cnt信息);任務(wù)在關(guān)閉對中斷的響應(yīng)前和打開對中斷的響應(yīng)后,若發(fā)現(xiàn)自己的試圖被搶先計數(shù)器值不為0,則檢查全局隊列中是否有任務(wù)要搶先自己;任務(wù)在關(guān)閉對搶先的支持前,或打開對搶先的支持后,若發(fā)現(xiàn)本處理器被標(biāo)記為候選處理器,則會檢查當(dāng)前全局隊列中是否有任務(wù)要搶先自己;當(dāng)任務(wù)被運行時,若調(diào)度器曾經(jīng)增加了某個處理器的試圖被搶先計數(shù)器,則此時將對應(yīng)處理器的試圖被搶先計數(shù)器減I。
[0204]本實施例中,操作系統(tǒng)中保留系統(tǒng)內(nèi)編號最大的處理器,該處理器僅被系統(tǒng)用于接收實時相關(guān)中斷,不能用于調(diào)度用戶任務(wù),所有處理器均可運行中斷狀態(tài)切換模塊。在傳統(tǒng)的操作系統(tǒng)中的任務(wù)調(diào)度方法中,調(diào)度器為某個新喚醒的任務(wù)選取處理器時僅考慮各個處理器上當(dāng)前任務(wù)的實時優(yōu)先級,不考慮這些處理器是否已通過“關(guān)中斷”、“關(guān)搶先”等方式禁止了被派發(fā)到其上的高優(yōu)先級任務(wù)立即獲得執(zhí)行權(quán)。本實施例中,每當(dāng)處理器需要暫時禁止搶先時,它都通過修改禁止搶先計數(shù)和中斷關(guān)閉狀態(tài)變量,讓其它處理器可以查詢此處理器的狀態(tài),從而主動避免“因?qū)⑷蝿?wù)派發(fā)到不能立刻實施搶先的處理器上而導(dǎo)致任務(wù)被延遲處理”。比如,在實時優(yōu)先級數(shù)值越大,就越優(yōu)先執(zhí)行時,正在處理器I上運行的任務(wù)Tl的實時優(yōu)先級為10,但它當(dāng)前關(guān)閉了中斷或搶先;正在處理器2上運行任務(wù)T2的實時優(yōu)先權(quán)為20,它沒有關(guān)閉中斷或搶先,T2當(dāng)前喚醒了一個實時優(yōu)先權(quán)為30的任務(wù)T3。在傳統(tǒng)的實現(xiàn)中,處理器2上的調(diào)度器可能會決定由處理器I來運行任務(wù)T3。但這會導(dǎo)致任務(wù)T3被迫等Tl執(zhí)行,直到其把中斷或搶先打開。此外,本實施例中,為每個處理器維護一個調(diào)度函數(shù)執(zhí)行次數(shù)信息一schecLcnt。處理器2在為任務(wù)T3選取處理器時,會發(fā)現(xiàn)處理器I運行的任務(wù)Tl雖具有較低的優(yōu)先級,但不能馬上實施搶先,就不會選擇有處理器I運行T3,而是僅增加此處理器的試圖被搶先計數(shù)器的值,并獲得處理器I當(dāng)前的schecLcnt值作為變量SCHED_CNT,然后選擇其它的處理器,如處理器2,運行任務(wù)T3。后文假設(shè)選擇的是處理器2。調(diào)度器會登記“若T2運行了,且處理器I上的調(diào)度函數(shù)執(zhí)行次數(shù)為變量SCHED_CNT時,則減少處理器I的試圖被搶先計數(shù)器”。此時,本實施例事實上會造成“低優(yōu)先級的任務(wù)Tl能夠運行,高優(yōu)先級的任務(wù)T2不能運行”,為了避免這種情況,當(dāng)?shù)蛢?yōu)先級的任務(wù)Tl結(jié)束禁止搶先狀態(tài)后,會檢查自己的試圖被搶先計數(shù),若發(fā)現(xiàn)其不為O,就綜合全局調(diào)度隊列和局部調(diào)度隊列,選取出一個任務(wù),比如是任務(wù)T2,并運行之。在任務(wù)Tl結(jié)束禁止搶先狀態(tài)之前,任務(wù)T2也有可能被另外的處理器,如處理器3,調(diào)度運行。此時它會試圖減小處理器I的試圖被搶先計數(shù)器,以使得任務(wù)Tl結(jié)束禁止搶先狀態(tài)之后不進行調(diào)度隊列的檢查工作。若處理器I在此時仍然沒有運行過調(diào)度函數(shù),則其schecLcnt必然等于變量SCHED_CNT,故系統(tǒng)會減少處理器I的試圖被搶先計數(shù)器;若從試圖搶先處理器I上的任務(wù),到現(xiàn)在,處理器I已經(jīng)運行過調(diào)度函數(shù),則說明其已考慮過任務(wù)搶先問題,故“減小處理器I的試圖被搶先計數(shù)器”會被視為過時信息,而被丟棄。處理器每執(zhí)行一次“選取哪個任務(wù)在本處理器上運行”的調(diào)度函數(shù),就會更新一下自己的調(diào)度函數(shù)執(zhí)行次數(shù)變量,并將試圖被搶先計數(shù)器清零,以向外界宣告:本處理器已進入新的歷史時代,之前基于老的調(diào)度函數(shù)執(zhí)行次數(shù)變量的所做的一切決策都作廢(這些決策比如:當(dāng)某任務(wù)運行時,減小此處理器的試圖被搶先計數(shù)器值)。在此函數(shù)執(zhí)行時,若發(fā)現(xiàn)當(dāng)前任務(wù)是被搶先了,則會把它放入全局調(diào)度隊列中(這樣其它的處理器在檢查完試圖被搶先計數(shù)器后,在檢查全局調(diào)度隊列中的任務(wù)時會發(fā)現(xiàn)這個被搶先的任務(wù))。
[0205]以上所述僅是本發(fā)明的優(yōu)選實施方式,本發(fā)明的保護范圍并不僅局限于上述實施例,凡屬于本發(fā)明思路下的技術(shù)方案均屬于本發(fā)明的保護范圍。應(yīng)當(dāng)指出,對于本【技術(shù)領(lǐng)域】的普通技術(shù)人員來說,在不脫離本發(fā)明原理前提下的若干改進和潤飾,這些改進和潤飾也應(yīng)視為本發(fā)明的保護范圍。
【權(quán)利要求】
1.一種基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,其特征在于實施步驟如下: 1)在操作系統(tǒng)系統(tǒng)初始化啟動各個處理器時,為各個處理器建立用于存放確定將在該處理器上運行任務(wù)的局部隊列、用于記錄試圖被搶先次數(shù)的搶先計數(shù)器以及搶先允許狀態(tài),所述搶先允許狀態(tài)用于表示處理器的中斷或搶先的開放/禁止情況;建立用于存放暫時沒有找到合適處理器運行任務(wù)的全局隊列; 2)將新創(chuàng)建或剛被喚醒的當(dāng)前任務(wù)暫存到全局隊列中,在當(dāng)前任務(wù)在全局隊列被調(diào)度運行時遍歷所有的處理器選擇在哪個處理器上運行當(dāng)前任務(wù),且在選擇處理器時檢查用于記錄各個處理器的搶先允許狀態(tài),避開搶先允許狀態(tài)標(biāo)明中斷或搶先已禁止而不能馬上實施搶先的處理器,若能找到合適的處理器,則將當(dāng)前任務(wù)放入所找到處理器的局部隊列中并跳轉(zhuǎn)執(zhí)行步驟3);否則,將當(dāng)前任務(wù)繼續(xù)停留在全局調(diào)度隊列,并通過搶先計數(shù)器記錄不能馬上實施搶先的處理器的試圖被搶先次數(shù),然后等待下一次在全局隊列被調(diào)度運行; 3)各個處理器分別執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù),在執(zhí)行任務(wù)過程中,如果遇到不允許插入執(zhí)行中斷處理程序的代碼,則通過執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已禁止,返回執(zhí)行所述不允許插入執(zhí)行中斷處理程序的代碼,最終通過執(zhí)行“打開對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已開放;如果遇到不允許插入執(zhí)行的代碼,則修改搶先允許狀態(tài)標(biāo)明搶先已禁止,返回執(zhí)行所述不允許插入執(zhí)行的代碼,最終修改搶先允許狀態(tài)標(biāo)明搶先已開放。
2.根據(jù)權(quán)利要求1所述的基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,其特征在于:所述步驟I)中建立用于存放暫時沒有找到合適處理器運行任務(wù)的全局隊列具體是指啟動一個虛擬處理器,針對該虛擬處理器建議一個用于緩存任務(wù)的任務(wù)調(diào)度隊列作為用于存放暫時沒有找到合適處理器運行任務(wù)的全局隊列。
3.根據(jù)權(quán)利要求2所述的基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,其特征在于,所述步驟I)中在操作系統(tǒng)系統(tǒng)初始化啟動各個處理器時,分別為每一個處理器分配schecLcnt、sched_cnt_rwl> try_pr_cnt> pr_dis_cnt、intr_mask_st 信息的存儲空間,其中,sched_cnt用于記錄了從開機至今在此處理器上調(diào)度函數(shù)的執(zhí)行次數(shù),sched_cnt_rwl為一個讀寫鎖,處理器在修改自己對應(yīng)的schecLcnt信息前,需要以“寫”的方式獲得自己對應(yīng)的sched_cnt_rwl,處理器在查看其它處理器對應(yīng)的sched_cnt信息前,需要以“讀”的方式獲得相應(yīng)處理器對應(yīng)的sched_cnt_rwl ;try_pr_cnt用于記錄從本處理器上次執(zhí)行調(diào)度函數(shù)至今,中間有試圖搶先本處理器上的當(dāng)前任務(wù)的任務(wù)數(shù)量;pr_dis_cnt用于記錄此處理器上正在運行的任務(wù)目前凈累積的“禁止搶先請求”次數(shù),若任務(wù)先執(zhí)行了 N次“禁止搶先請求”,接下來執(zhí)行了 N-1次“允許搶先請求”,則此任務(wù)pr_dis_cnt的值為I ;若在pr_dis_cnt為O時,任務(wù)仍然執(zhí)行“允許搶先請求”,則pr_dis_cnt仍然為O ;intr_mask_st為一個枚舉類型變量,值域為{DIS,ENA},其值僅受任務(wù)執(zhí)行時的“打開對中斷的響應(yīng)”、“關(guān)閉對中斷的響應(yīng)”兩類操作的影響,任務(wù)在本處理器上執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作后,則intr_mask_st值變?yōu)镈IS ;任務(wù)在本處理器上執(zhí)行“打開對中斷的響應(yīng)”操作后,則intr_mask_st 值變?yōu)?ΕΝΑ。
4.根據(jù)權(quán)利要求3所述的基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,其特征在于,所述步驟2)中將新創(chuàng)建或剛被喚醒的當(dāng)前任務(wù)暫存到全局隊列中之前,還包括為當(dāng)前任務(wù)初始化分配ctab、sched_lock, sched_st, vlistn信息的存儲空間的步驟;其中,ctab為搶先列表,用于記錄本任務(wù)所試圖搶先、但因?qū)Ψ浇沽藫屜?,而沒有搶先成功的信息,由于系統(tǒng)中同時運行的任務(wù)個數(shù)不超過在線處理器的數(shù)量,故ctab最多包含的元素個數(shù)不大于在線處理器數(shù)量,ctab記錄的每一項可用<tried_cpu, snapshot〉來表示,其含義為此任務(wù)試圖搶先在處理器tried_cpu上運行的任務(wù),但搶先失敗了,且在失敗時處理器tried_cpu對應(yīng)的sched_cnt值為snapshot ;sched_lock為一個讀寫鎖,在需清除ctab中信息時,應(yīng)先獲得寫鎖;在需向ctab中添加信息時,應(yīng)先獲得讀鎖,在需為某任務(wù)尋找合適的處理器運行時,應(yīng)先獲得寫鎖;vlistn為一個指向全局隊列中下一個待調(diào)度任務(wù)的指針;SChed_st為一個枚舉類型的變量,用于描述此任務(wù)的執(zhí)行狀態(tài),其值域為{RUN,PRD, INL, ING,SLEP},其中RUN表示該任務(wù)正在運行,PRD表示該任務(wù)原本在運行,但剛剛被搶先,還未放入到待運行隊列中,INL表示該任務(wù)在局部隊列中等待調(diào)度運行,ING表示該任務(wù)在全局隊列中等待調(diào)度運行,SLEP表示該任務(wù)目前還在等待除CPU之外的其它運行條件獲得滿足,新創(chuàng)建的任務(wù)的sched_st默認為SLEP ;所述步驟2)的詳細步驟如下: .2.1)令預(yù)先建立的用于臨時存儲搶先列表ctab的臨時搶先列表R為空,令當(dāng)前任務(wù)T的搶先列表ctab為空,令變量first_try的值為true、變量low的值為系統(tǒng)所允許的最低優(yōu)先權(quán)、變量high的值為當(dāng)前任務(wù)T的實時優(yōu)先權(quán)減I,將當(dāng)前任務(wù)T對應(yīng)的schecLst信息設(shè)置為ING,其中變量first_try用于指示是不是第一次就找到了被搶先任務(wù),若變量first_try為true,則說明第一次就找到的任務(wù)沒有禁止掉搶先,傳統(tǒng)的處理邏輯不會影響系統(tǒng)響應(yīng),若變量first_try為false,則說明是當(dāng)前正在運行的最低優(yōu)先級的任務(wù)禁止掉了搶先,系統(tǒng)決定搶先非最低優(yōu)先級任務(wù);變量low是本次循環(huán)中當(dāng)前任務(wù)T考慮可以搶先的任務(wù)最低應(yīng)具有優(yōu)先級;變量high是本次循環(huán)中當(dāng)前任務(wù)T考慮可以搶先的任務(wù)最高應(yīng)具有優(yōu)先級;設(shè)置用于指定執(zhí)行當(dāng)前任務(wù)T的處理器的變量proc的值為所述虛擬處理器; . 2.2)將當(dāng)前任務(wù)T放入全局隊列中; .2.3)為當(dāng)前任務(wù)T在指定的處理器集合中篩選出所有可運行用戶任務(wù)的處理器集合S,并將篩選得到的處理器集合S保存; .2.4)判斷處理器集合S是否為空集,如果為空集則跳轉(zhuǎn)執(zhí)行步驟2.22);否則,跳轉(zhuǎn)執(zhí)行下一步; .2.5)獲得當(dāng)前任務(wù)T應(yīng)當(dāng)搶先的處理器,將得到的處理器放入變量proc中,然后獲得變量proc對應(yīng)處理器上當(dāng)前正在運行的任務(wù)X ; .2.6)試圖獲取當(dāng)前任務(wù)T對應(yīng)的schecLlock讀鎖,若獲取失敗,則令變量proc的值為虛擬處理器、臨時搶先列表R的值為空,跳轉(zhuǎn)執(zhí)行步驟2.22);否則跳轉(zhuǎn)執(zhí)行下一步; .2.7)獲取當(dāng)前任務(wù)T的sched_st信息,若當(dāng)前任務(wù)T對應(yīng)的sched_st不是ING,則首先令變量proc的值為虛擬處理器、變量first_try的值為true、臨時搶先列表R的值為空,然后跳轉(zhuǎn)執(zhí)行步驟2.15);否則,跳轉(zhuǎn)執(zhí)行下一步; .2.8)獲得變量proc對應(yīng)處理器的sched_cnt_rwl讀鎖; . 2.9)讀取變量proc對應(yīng)處理器的schecLcnt信息,將讀取的SChed_Cnt信息、變量proc對應(yīng)處理器兩者作為一條記錄存入臨時搶先列表R ; .2.10)獲得變量proc對應(yīng)處理器的try_pr_cnt信息增I ; .2.11)釋放變量proc對應(yīng)處理器的sched_cnt_rwl讀鎖; .2.12)判斷變量proc對應(yīng)處理器的pr_dis_cnt信息為O、intr_mask_st信息為ENA兩個條件是否同時成立,如果同時成立則跳轉(zhuǎn)執(zhí)行步驟2.13);否則如果不能同時成立,則釋放當(dāng)前任務(wù)T對應(yīng)的sched_lock讀鎖,從處理器集合S中去掉變量proc對應(yīng)的處理器,然后判斷處理器集合S是否變?yōu)榭占绻幚砥骷蟂不是空集則跳轉(zhuǎn)執(zhí)行步驟2.5);如果處理器集合S是空集,則令變量first_try的值為false、變量low的值為變量proc對應(yīng)的處理器的當(dāng)前實時優(yōu)先權(quán)加1、變量proc的值為所述虛擬處理器,跳轉(zhuǎn)執(zhí)行步驟2.3); . 2.13)將當(dāng)前任務(wù)T對應(yīng)的schecLst信息設(shè)為INL ; . 2.14)將當(dāng)前任務(wù)T從全局隊列中刪除,并將當(dāng)前任務(wù)T添加至變量proc對應(yīng)處理器的獨步隊列中; .2.15)釋放當(dāng)前任務(wù)T對應(yīng)的sched_lock讀鎖;
.2.16)判斷變量first_try的值,若first_try的值為true,則跳轉(zhuǎn)執(zhí)行步驟2.22),否則跳轉(zhuǎn)執(zhí)行步驟2.17); . 2.17)獲得變量proc對應(yīng)處理器上當(dāng)前正在運行的任務(wù)X對應(yīng)的schecLlock的讀鎖; . 2.18)檢查所述任務(wù)X的sched_st信息,若所述任務(wù)X對應(yīng)的sched_st信息不是RUN狀態(tài),則從處理器集合S中去掉變量proc對應(yīng)的處理器,然后判斷處理器集合S是否變?yōu)榭占?,如果處理器集合S不是空集則跳轉(zhuǎn)執(zhí)行步驟2.5);如果處理器集合S是空集,則令變量first_try的值為false、變量low的值為變量proc對應(yīng)的處理器的當(dāng)前實時優(yōu)先權(quán)加.1、變量proc的值為所述虛擬處理器,跳轉(zhuǎn)執(zhí)行步驟2.3);若任務(wù)X對應(yīng)的SChed_St信息是RUN狀態(tài),則跳轉(zhuǎn)執(zhí)行下一步; .2.19)將所述任務(wù)X對應(yīng)的schecLst信息設(shè)為PRD狀態(tài); .2.20)將臨時搶先列表R的內(nèi)容填寫到所述任務(wù)X的搶先列表ctab中,再令臨時搶先列表R為空; .2.21)釋放所述任務(wù)X對應(yīng)的sched_lock讀鎖; . 2.22)將臨時搶先列表R復(fù)制到當(dāng)前任務(wù)T的搶先列表ctab中,返回變量proc對應(yīng)處理器即為被選中用于運行當(dāng)前任務(wù)T的處理器。
5.根據(jù)權(quán)利要求4所述的基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,其特征在于,所述步驟3)中各個處理器分別選取在當(dāng)前處理器上運行的任務(wù)的詳細步驟如下: .3.1)獲得當(dāng)前處理器的sched_cnt_rwl寫鎖; . 3.2)將當(dāng)前處理器的sched_cnt信息增1、try_pr_cnt信息設(shè)為O ; .3.3)釋放當(dāng)前處理器的sched_cnt_rwl寫鎖; .3.4)獲取當(dāng)前處理器本地的局部隊列中最高實時優(yōu)先權(quán)的任務(wù)放在變量next中,獲取當(dāng)前處理器上正在運行的任務(wù)放在變量curr中;. 3.5)獲取變量curr對應(yīng)任務(wù)的sched_lock寫鎖; .3.6)判斷變量curr對應(yīng)任務(wù)的sched_st信息,若變量curr對應(yīng)任務(wù)的sched_st信息為PRD,則根據(jù)變量curr對應(yīng)任務(wù)從全局隊列中獲取一個任務(wù)Tg放在變量next中,且獲取的任務(wù)Tg滿足下述條件④~⑥,④任務(wù)Tg的實時優(yōu)先權(quán)高于變量curr對應(yīng)任務(wù)的實時優(yōu)先權(quán);⑤任務(wù)Tg的搶先列表ctab中,當(dāng)前處理器編號對應(yīng)的tried_cpu項中包含有效內(nèi)容;⑥在所有滿足條件④和⑤的所有任務(wù)中,任務(wù)Tg的實時優(yōu)先權(quán)最高; .3.7)判斷變量next和變量curr是否相同,若變量next和變量curr相同,則釋放變量curr對應(yīng)任務(wù)的sched_lock寫鎖,并返回繼續(xù)執(zhí)行變量curr對應(yīng)的任務(wù);否則跳轉(zhuǎn)執(zhí)行下一步; 3.8)判斷變量curr對應(yīng)任務(wù)的sched_st信息是否為PRD,若curr對應(yīng)任務(wù)的sched_st信息為PRD,則將變量curr對應(yīng)任務(wù)從當(dāng)前處理器的局部隊列中刪除,并將變量curr對應(yīng)任務(wù)添加至全局隊列,然后設(shè)置變量curr對應(yīng)任務(wù)的sched_st信息為ING ; 3.9)判斷變量curr對應(yīng)任務(wù)是否需要繼續(xù)運行,如果不需要繼續(xù)運行,則設(shè)置變量curr對應(yīng)任務(wù)的sched_st信息為SLEP,將變量curr對應(yīng)任務(wù)從當(dāng)前處理器的局部隊列中刪除,將變量curr對應(yīng)的任務(wù)作為待清除任務(wù),刪除待清除任務(wù)的相關(guān)記錄信息,然后跳轉(zhuǎn)執(zhí)行步驟3.10);如果需要繼續(xù)運行,則直接跳轉(zhuǎn)執(zhí)行步驟3.10); 3.10)設(shè)置當(dāng)前處理器正在運行的任務(wù)為變量next對應(yīng)的任務(wù); 3.11)釋放變量curr對應(yīng)任務(wù)的sched_lock寫鎖; 3.12)判斷變量next對應(yīng)任務(wù)當(dāng)前的sched_lock狀態(tài),若sched_lock狀態(tài)為無鎖或讀鎖,則跳轉(zhuǎn)執(zhí)行步驟3.13);否則,設(shè)置當(dāng)前處理器當(dāng)前運行的任務(wù)為空閑任務(wù),獲取當(dāng)前處理器本地的局部隊列中最高實時優(yōu)先權(quán)的任務(wù)放在變量next中,以變量next對應(yīng)的任務(wù)作為查找失敗的默認返回值從全局隊列中獲取一個任務(wù)Tg放在變量next中,且獲取的任務(wù)Tg滿足下述條件④~⑥,④任務(wù)Tg的實時優(yōu)先權(quán)高于變量curr對應(yīng)任務(wù)的實時優(yōu)先權(quán);⑤任務(wù)Tg的搶先列表ctab中,當(dāng)前處理器編號對應(yīng)的tried_cpu項中包含有效內(nèi)容;⑥在所有滿足條件④和⑤的所有任務(wù)中,任務(wù)Tg的實時優(yōu)先權(quán)最高;設(shè)置當(dāng)前運行的任務(wù)為變量next對應(yīng)的任務(wù),跳轉(zhuǎn)重新執(zhí)行步驟3.12); 3.13)試圖獲取變 量next對應(yīng)任務(wù)的sched_lock寫鎖,若失敗則跳轉(zhuǎn)執(zhí)行步驟3.12);否則,跳轉(zhuǎn)執(zhí)行步驟3.14); 3.14)讀取變量next對應(yīng)任務(wù)的sched_st信息,若變量next對應(yīng)任務(wù)的sched_st信息不是PRD,跳轉(zhuǎn)執(zhí)行步驟3.17),否則跳轉(zhuǎn)執(zhí)行步驟3.15); 3.15)判斷變量next對應(yīng)的任務(wù)是否在全局隊列中,如果在全局隊列中,則設(shè)置變量next對應(yīng)任務(wù)的sched_st信息為ING,否則設(shè)置變量next對應(yīng)任務(wù)的sched_st信息為INL ; 3.16)釋放變量next對應(yīng)任務(wù)的sched_lock寫鎖,跳轉(zhuǎn)執(zhí)行步驟3.12); 3.17)將變量next對應(yīng)的任務(wù)作為待清除任務(wù),刪除待清除任務(wù)的相關(guān)記錄信息; 3.18)判斷變量next對應(yīng)的任務(wù)是否在全局隊列中,如果在全局隊列中,則將變量next對應(yīng)的任務(wù)從全局隊列中刪除,并將變量next對應(yīng)的任務(wù)添加至當(dāng)前處理器的局部隊列,然后跳轉(zhuǎn)執(zhí)行步驟3.19);否則如果不在全局隊列中,則直接跳轉(zhuǎn)執(zhí)行步驟3.19); 3.19)設(shè)置變量next對應(yīng)的任務(wù)的sched_st信息為RUN ; 3.20)釋放變量next對應(yīng)的任務(wù)的sched_lock寫鎖,開始執(zhí)行變量next對應(yīng)的任務(wù)。
6.根據(jù)權(quán)利要求5所述的基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,其特征在于,所述步驟3.9)和步驟3.17)中刪除待清除任務(wù)的相關(guān)記錄信息的詳細步驟如下: 3.9.1)檢查待清除任務(wù)的搶先列表ctab中是否包含有效記錄,若待清除任務(wù)的搶先列表ctab中不包含有效記錄,則返回;否則,跳轉(zhuǎn)執(zhí)行步驟3.9.2); 3.9.2)獲取待清除任務(wù)的搶先列表ctab中的第一個有效記錄,首先將所述有效記錄刪除; 3.9.3)判斷已刪除有效記錄中的triecLcpu信息是否與本處理器相同,如果是則跳轉(zhuǎn)執(zhí)行步驟3.9.1);否則,跳轉(zhuǎn)執(zhí)行步驟3.9.4); . 3.9.4)獲取已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的sched_cnt_rwl讀鎖;.3.9.5)讀取已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的sched_cnt信息,如果所述sched_cnt信息的值與已刪除有效記錄中的snapshot的值相同,則將已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的try_pr_cnt信息的值以原子方式減I ; . 3.9.6)釋放已刪除有效記錄中的tried_cpu信息對應(yīng)處理器的sched_cnt_rwl讀鎖;跳轉(zhuǎn)執(zhí)行步驟3.9.1)。
7.根據(jù)權(quán)利要求6所述的基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,其特征在于,所述步驟3)中通過執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已禁止的詳細步驟包括: . 3.21)將當(dāng)前處理器的intr_mask_st信息設(shè)置為DIS完成執(zhí)行“關(guān)閉對中斷的響應(yīng)”操作,修改搶先允許狀態(tài)標(biāo)明中斷已禁止;. 3.22)判斷當(dāng)前處理器的pr_dis_cnt信息為l、try_pr_cnt不為O兩個條件是否同時不成立,如果兩個條件不能同時成立,則關(guān)閉當(dāng)前處理器對物理中斷的響應(yīng),當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);否則如果兩個條件同時成立,則跳轉(zhuǎn)執(zhí)行下一步; . 3.23)將當(dāng)前處理器的intr_mask_st信息設(shè)置為ENA完成執(zhí)行“打開對中斷的響應(yīng)”操作,修改搶先允許狀態(tài)標(biāo)明中斷已打開; . 3.24)當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù),跳轉(zhuǎn)執(zhí)行步驟3.21); 所述步驟3)中通過執(zhí)行“打開對中斷的響應(yīng)”操作修改搶先允許狀態(tài)標(biāo)明中斷已開放的詳細步驟包括: . 3.25)打開當(dāng)前處理器對物理中斷的響應(yīng); . 3.26)將當(dāng)前處理器的intr_mask_st信息設(shè)置為ENA完成執(zhí)行“打開對中斷的響應(yīng)”操作,修改搶先允許狀態(tài)標(biāo)明中斷已打開;. 3.27)判斷當(dāng)前處理器的pr_dis_cnt信息為0、try_pr_cnt不為O兩個條件是否同時不成立,如果兩個條件不能同時成立,當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);否則如果兩個條件同時成立,則當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù)。
8.根據(jù)權(quán)利要求7所述的基于資源預(yù)約的兩級混合任務(wù)調(diào)度方法,其特征在于,所述步驟3)中修改搶先允許狀態(tài)標(biāo)明搶先已禁止的詳細步驟如下: . 3.28)將當(dāng)前處理器的pr_dis_cnt信息的值增I ;. 3.29)判斷當(dāng)前處理器的pr_dis_cnt信息的值為1、try_pr_cnt信息的值不為O、intr_mask_st信息的值為ENA三個條件是否同時成立,如果同時成立則跳轉(zhuǎn)執(zhí)行步驟.3.30);否則,當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);. 3.30)將當(dāng)前處理器的pr_dis_cnt信息的值設(shè)置為O ; . 3.31)當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上運行的任務(wù),跳轉(zhuǎn)執(zhí)行步驟3.28); 所述步驟3)中修改搶先允許狀態(tài)標(biāo)明搶先已開放的詳細步驟如下: . 3.32)將當(dāng)前處理器的pr_dis_cnt信息的值減I ; . 3.33)判斷當(dāng)前處理器的pr_dis_cnt信息的值為O、try_pr_cnt信息的值不為O、intr_mask_st信息的值為ENA三個條件是否同時成立,如果三個條件同時成立,貝U跳轉(zhuǎn)執(zhí)行步驟3.34);否則,當(dāng)前處理器返回執(zhí)行當(dāng)前處理器上運行的任務(wù);、3.34)當(dāng)前處理器執(zhí)行選擇在當(dāng)前處理器上 運行的任務(wù)。
【文檔編號】G06F9/50GK103995743SQ201410215702
【公開日】2014年8月20日 申請日期:2014年5月21日 優(yōu)先權(quán)日:2014年5月21日
【發(fā)明者】廖湘科, 劉曉建, 楊沙洲, 韋奇, 李俊良, 顏躍進, 汪黎, 秦瑩, 周強, 王非 申請人:中國人民解放軍國防科學(xué)技術(shù)大學(xué)