前言
在軟件世界里面,超時是一個非常重要的概念。比如
● 當前線程暫時休眠1秒鐘,休眠結束后繼續執行
● 每5秒鐘采集一下CPU利用率
● 數據發送失敗,2秒鐘以后再試一試
● 等待某種數據,但最多等待50毫秒
應用
//將當前任務休眠若干tick數,tick為時間單位,常見值為10毫秒
LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
//獲取信號量semHandle, 如果當前信號量不可用且timeout不為0,則最多等待timeout所指定的時間,在這段時間內如果信號量可用,則獲取成功,否則獲取失敗。
LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
//從空的消息隊列讀取消息,或者向滿的消息隊列寫消息時,如果timeout不為0,則最多等待timeout指定的時間,在這段時間內消息隊列可讀或可寫,則進行對應的讀寫并返回成功,否則返回失敗。
LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeOut)
LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeOut)
//獲取互斥鎖,如果當前互斥鎖被其它線程占用,則最多等待timeout指定的時間,此時間內其它線程釋放了互斥鎖并被本線程搶到則返回成功,否則返回失敗。
LITE_OS_SEC_TEXT UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout)
//等待其它線程向本線程發送事件,最多等待timout指定的時間
LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeOut)
上述這些函數都是超時概念在OpenHarmony中liteos_m內核里的具體應用。
具體而言,liteos_m內核如何實現這個超時邏輯的呢,我們接著看下一個章節
原理
如上圖所示。在時間軸上,黃色圓點代表需要進行某種操作的時間點,而綠色圓點為檢查系統是否有超時事件需要處理的檢查時間點。系統周期性的進行檢查(周期單位為tick)。在2個檢查點之間可能有超時事件,也可能無超時事件。
例如,根據上圖展示的情況。當前在第一個檢查點,發現了2個超時事件,那么這次處理這2個超時事件;隨著時間流逝,箭頭來到第2個檢查點,又發現2個超時事件,繼續處理;在第3個檢查點時,本段時間內無超時事件,所以是空操作。后續的檢查以此類推。
代碼實現
為了準確性以及時效性,本文選取了最新的版本的代碼來描述。上述檢查點和時間點由鏈表結構進行定義。具體在kernel/liteos_m/include/los_sortlink.h文件中。
由于原理圖中的超時事件發生是非均勻的,且存在有序依次發生的邏輯,所以,這些信息被維護在雙向鏈表中(對刪除操作更友好)。
SortLinkList代表了鏈表中的每一個需要處理事件的時間點,responseTime代表具體的時間值(從啟機開始的cpu cycle數目)。SortLinkAttribute代表鏈表的頭部(啞頭)。從名稱也能看出,這個是一個排序的雙向鏈表,排序的依據即responseTime這個數值。
需要注意的一個細節是:系統支持2個鏈表,其中一個是TASK鏈表,另一個是SWTMR鏈表。這2個鏈表實現方式一致,主要區別是,SWTMR鏈表超時處理是喚醒swtmr線程來處理超時事件,而task鏈表喚醒的是每個具體的task(sleep,ipc超時等場景)。使用swtmr線程來處理若干超時的機制,可以有效減少系統需要的線程數目,從而節省系統資源的占用。
總結
審核編輯:湯梓紅
-
代碼
+關注
關注
30文章
4748瀏覽量
68356 -
超時
+關注
關注
0文章
2瀏覽量
6768 -
OpenHarmony
+關注
關注
25文章
3660瀏覽量
16157
原文標題:對OpenHarmony中LiteOS的內核分析——超時原理和應用
文章出處:【微信號:gh_e4f28cfa3159,微信公眾號:OpenAtom OpenHarmony】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論