ucos-ii核心演算法分析
μc/os-ⅱ是一種免費公開源**、結構小巧、具有可剝奪實時核心的實時作業系統。其核心提供任務排程與管理、時間管理、任務間同步與通訊、記憶體管理和中斷服務等功能。適合小型控制系統,具有執行效率高、占用空間小、實時效能優良和可擴充套件 性強等特點,最小核心可編譯至2kb。μc/os-ⅱ為何如此高效呢?我們從它的核心演算法——任務排程演算法開始分析。
1任務排程演算法分析
作業系統的實時性主要體現在:當優先順序高的任務要求工作時,作業系統要以盡快的時間將此任務排程到cpu執行。這裡所花費的時間主要包括兩部分:查詢最高優先順序任務和任務上下文切換。其中,任務上下文切換時間是和處理器相關的,作業系統無法控制。我們主要分析uc/os-ii如何查詢最高優先順序任務的。
因為任務較少,uc/os-ii採用單一優先順序,這為演算法的實現提供了很大的方便。在uc/os-ii中,優先順序可以作為任務的標識(當然要在任務存在的情況下,是通過乙個指標陣列實現的)來用。
排程演算法主要基於分級查詢。考慮到任務數目<64,可以用6bit來表示,分為高3位和低三位。uc/os-ii將優先順序進行分組,按高三位進行分組,可得8個(最多)優先順序陣列(000-111);每個優先順序的在陣列中的位置由其低三位表示。在原始碼中,高三位用帶y字尾的變數表示,而低三位用帶x字尾的變數表示。這樣建立了1個變數osrdygrp(int8u,8bit,每個bit代表一組)和1個陣列osrdytbl[8](int8u,每 組8bit,每個bit代表乙個優先順序)。這樣形成了的二級查詢,先選組,再選組內偏移。
其中,osrdygrp每一bit置1,表示該組有任務就緒。(第0~7組)。其示意圖見下圖:
我們舉乙個例子,看一下如果優先順序為22的任務就緒,我們如何對優先順序陣列進行操作。用二進位制表示為0b00010110,其高3位為010,為2,則將第2組,也就是osrdygrp的第2位置1。其低3位為110,為6,則將其osrdytbl[2]的第6位置1。程式設計實現時,可以通過對1進行移位, 再進行 或 操作來實現。但考慮到移位時間不確定(要進行統一化),uc/os-ii選擇建立了乙個表osmaptbl[8],如下。
表 t3.1 osmaptbl的值
index bit mask (binary)
0 00000001
1 00000010
2 00000100
3 00001000
4 00010000
5 00100000
6 01000000
7 10000000
這樣,當乙個任務就緒時,我們這樣處理。其中prio是任務的優先順序。
程式清單l3.5 使任務進入就緒態
osrdygrp |= osmaptbl[prio >> 3];
osrdytbl[prio >> 3] |= osmaptbl[prio & 0x07];
而當任務被掛起或刪除時,我們這樣處理:
程式清單l3.6 從就緒表中刪除乙個任務
if ((osrdytbl[prio >> 3] &= ~osmaptbl[prio & 0x07]) == 0)
osrdygrp &= ~osmaptbl[prio >> 3];
表建立了,如何查詢最高優先順序呢?這是很關鍵的。因為優先順序的值越小,優先順序越高,我們只需從osrdygrp中找到最低位置1的的那一組,再從該組中,查詢最低位置1的位置,組合一下,就得到了最高的優先順序。
同樣,這可以通過乙個while迴圈進行判斷,但是,時間也是不確定的(要進行統一化)。所以,uc/os-ii又建立了一張表osunmaptbl,這張表有點大,其下標值範圍為0x00-0xff,值域為0-7。
這樣,其查詢流程為:
程式清單l3.7 找出進入就緒態的優先順序最高的任務
y = osunmaptbl[osrdygrp];
x = osunmaptbl[osrdytbl[y]];
prio = (y << 3) + x;
2事件處理演算法分析
在uc/os-ii中,事件可以是訊號量、郵箱或者訊息佇列等,並用統一的結構體os_event表示。
我們先看一下os_event的組成:
typedef struct os_event;注意其中兩個變數:oseventgrp和oseventtbl,是不是覺得有點象osrdygrp和osrdytbl。那它們的處理演算法是不是 也一樣呢?你猜對了,這裡關於事件的各種操作(如pend、post、timeout、wait等)的演算法和任務排程演算法如出一轍。當然也用到了osunmaptb和osmaptbl。只是任務就緒時(等待cpu時)插入就緒表,而當任務需要等待事件時要插入event等待列表,反之亦同。
3 小結
這兩個演算法(1種演算法)是os_core.c中最主要的演算法。此演算法執行時間恆定,不隨任務數目的多少變化(但不能超過64個任務),保證了其實時性。這裡,順便對uc/os-ii的設計哲學進行臆測:那就是「以空間換時間」,也就是**table (array)。這可以從uc/os-ii中存在眾多的全域性變數,如oseventtabl,osrdytbl,ostcbtbl(這樣避免了動態初始化)看出,也可以從上面介紹的任務排程演算法中看出(核心資料結構為陣列,並建立了兩張表osunmaptbl和osmaptbl)。
掃 雷 核 心 算 法
定義 在該案例中我們要實現類似於windows掃雷遊戲程式的核心功能,我們將掃雷遊戲的核心功能分為以下4個模組 1,隨機布雷模組 在該模組中,我們要為掃雷遊戲隨機的布置地雷,掃雷遊戲的布雷面板可以用二維int陣列表示,若某位置為地雷,則該位置用數字 1表示,若該位置不是地雷,則暫時用數字0表示。我們...
rsync 的核心演算法
rsync是unix linux下同步檔案的乙個高效演算法,它能同步更新兩處計算機的檔案與目錄,並適當利用查詢檔案中的不同塊以減少資料傳輸。rsync中一項與其他大部分類似程式或協定中所未見的重要特性是映象是只對有變更的部分進行傳送。rsync可拷貝 顯示目錄屬性,以及拷貝檔案,並可選擇性的壓縮以及...
rsync 的核心演算法
rsync是unix linux下同步檔案的乙個高效演算法,它能同步更新兩處計算機的檔案與目錄,並適當利用查詢檔案中的不同塊以減少資料傳輸。rsync中一項與其他大部分類似程式或協定中所未見的重要特性是映象是只對有變更的部分進行傳送。rsync可拷貝 顯示目錄屬性,以及拷貝檔案,並可選擇性的壓縮以及...