日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
鴻蒙輕內(nèi)核M核源碼分析系列二數(shù)據(jù)結(jié)構(gòu)-任務(wù)就緒隊(duì)列

想了解更多內(nèi)容,請?jiān)L問:

和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.

鴻蒙輕內(nèi)核源碼分析上一個(gè)系列,我們分析了雙向循環(huán)鏈表的源碼。本文會(huì)繼續(xù)給讀者介紹源碼中重要的數(shù)據(jù)結(jié)構(gòu),任務(wù)基于優(yōu)先級的就緒隊(duì)列Priority Queue。在講解時(shí),會(huì)結(jié)合數(shù)據(jù)結(jié)構(gòu)相關(guān)繪圖,培養(yǎng)讀者們的數(shù)據(jù)結(jié)構(gòu)的平面想象能力,幫助更好的學(xué)習(xí)和理解這些數(shù)據(jù)結(jié)構(gòu)的用法。

1 任務(wù)就緒隊(duì)列

在任務(wù)調(diào)度模塊,就緒隊(duì)列是個(gè)重要的數(shù)據(jù)結(jié)構(gòu)。任務(wù)創(chuàng)建后即進(jìn)入就緒態(tài),并放入就緒隊(duì)列。在鴻蒙輕內(nèi)核中,就緒隊(duì)列是一個(gè)雙向循環(huán)鏈表數(shù)組,每個(gè)數(shù)組元素就是一個(gè)鏈表,相同優(yōu)先級的任務(wù)放入同一個(gè)鏈表。

任務(wù)就緒隊(duì)列Priority Queue主要供內(nèi)部使用,用戶進(jìn)行業(yè)務(wù)開發(fā)時(shí)不涉及,所以并未對外提供接口。雙向循環(huán)鏈表數(shù)組能夠更加方便的支持任務(wù)基于優(yōu)先級進(jìn)行調(diào)度。任務(wù)就緒隊(duì)列的核心代碼在kernel\src\los_task.c文件中。

1.1 任務(wù)就緒隊(duì)列的定義

在kernel\src\los_task.c文件中定義了和任務(wù)就緒隊(duì)列相關(guān)的主要變量。

源碼如下:

 
 
 
 
  1. ⑴ LITE_OS_SEC_BSS LOS_DL_LIST *g_losPriorityQueueList = NULL; 
  2.  
  3. ⑵ static LITE_OS_SEC_BSS UINT32 g_priqueueBitmap = 0; 
  4.  
  5. ⑶ #define PRIQUEUE_PRIOR0_BIT              (UINT32)0x80000000 
  6.  
  7. ⑷ #define OS_PRIORITY_QUEUE_PRIORITYNUM    32 

 其中⑴表示任務(wù)就緒隊(duì)列,是一個(gè)雙向鏈表數(shù)組,后文初始化該數(shù)組時(shí)會(huì)將數(shù)組長度設(shè)置為⑷處定義的OS_PRIORITY_QUEUE_PRIORITYNUM;⑵表示優(yōu)先級位圖,標(biāo)識了任務(wù)就緒隊(duì)列中已掛載的就緒任務(wù)所在的優(yōu)先級;⑶表示優(yōu)先級為0的比特位;⑷表示任務(wù)就緒隊(duì)列支持的優(yōu)先級個(gè)數(shù)32,所以鴻蒙輕內(nèi)核優(yōu)先級的取值范圍為0-31,數(shù)值越小優(yōu)先級越大。

優(yōu)先級位圖g_priqueueBitmap的bit位和優(yōu)先級的關(guān)系為bit=31-priority,優(yōu)先級數(shù)組g_losPriorityQueueList[priority]包含了OS_PRIORITY_QUEUE_PRIORITYNUM個(gè)數(shù)組元素,每個(gè)數(shù)組元素都是一個(gè)雙向鏈表,同一優(yōu)先級的處于就緒狀態(tài)的所有任務(wù)都會(huì)掛載到對應(yīng)優(yōu)先級的雙向鏈表中。

示意圖如下:

2 任務(wù)就緒隊(duì)列操作

2.1 初始化任務(wù)就緒隊(duì)列

任務(wù)就緒隊(duì)列初始化函數(shù)為OsPriQueueInit(),系統(tǒng)初始化階段被調(diào)用,調(diào)用路徑為:main.c:main() --> kernel\src\los_init.c:LOS_KernelInit() --> kernel\src\los_task.c:OsTaskInit() --> OsPriqueueInit()。

源碼如下:

 
 
 
 
  1. STATIC UINT32 OsPriqueueInit(VOID) 
  2.     UINT32 priority; 
  3. ⑴  UINT32 size = OS_PRIORITY_QUEUE_PRIORITYNUM * sizeof(LOS_DL_LIST); 
  4.  
  5.     g_losPriorityQueueList = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, size); 
  6.     if (g_losPriorityQueueList == NULL) { 
  7.         return LOS_NOK; 
  8.     } 
  9.  
  10.     for (priority = 0; priority < OS_PRIORITY_QUEUE_PRIORITYNUM; ++priority) { 
  11. ⑵      LOS_ListInit(&g_losPriorityQueueList[priority]); 
  12.     } 
  13.     return LOS_OK; 

 ⑴處計(jì)算就緒隊(duì)列數(shù)組需要的內(nèi)存大小,然后為任務(wù)就緒隊(duì)列申請內(nèi)存,占用內(nèi)存為OS_PRIORITY_QUEUE_PRIORITYNUM個(gè)雙向鏈表所需要的內(nèi)存大小,運(yùn)行期間該內(nèi)存不會(huì)釋放,為系統(tǒng)常駐內(nèi)存。⑵處代碼將每一個(gè)數(shù)組元素都初始化為雙向循環(huán)鏈表。

2.2 任務(wù)就緒隊(duì)列插入

任務(wù)就緒隊(duì)列插入函數(shù)為OsPriqueueEnqueue(),該函數(shù)把就緒狀態(tài)的任務(wù)插入任務(wù)就緒隊(duì)列的尾部。在任務(wù)就緒隊(duì)列中,先調(diào)用隊(duì)列頭部的任務(wù),最后調(diào)用隊(duì)列尾部的任務(wù)。

源碼如下:

 
 
 
 
  1. STATIC VOID OsPriqueueEnqueue(LOS_DL_LIST *priqueueItem, UINT32 priority) 
  2. ⑴  if (LOS_ListEmpty(&g_losPriorityQueueList[priority])) { 
  3. ⑵      g_priqueueBitmap |= (PRIQUEUE_PRIOR0_BIT >> priority); 
  4.     } 
  5.  
  6. ⑶  LOS_ListTailInsert(&g_losPriorityQueueList[priority], priqueueItem); 

 ⑴處先判斷指定優(yōu)先級priority的任務(wù)就緒隊(duì)列是否為空,如果為空,則在⑵處更新優(yōu)先級位圖,將第31-prioritybit位設(shè)置為1。⑶處把就緒狀態(tài)的任務(wù)插入任務(wù)就緒隊(duì)列的尾部,進(jìn)行排隊(duì)。

2.3 從任務(wù)就緒隊(duì)列中刪除

從任務(wù)就緒隊(duì)列中刪除的函數(shù)為OsPriqueueDequeue()。任務(wù)被刪除、進(jìn)入suspend阻塞狀態(tài)、優(yōu)先級調(diào)整等場景中,都需要調(diào)用該函數(shù)把任務(wù)從任務(wù)就緒隊(duì)列中刪除。

源碼如下:

 
 
 
 
  1. STATIC VOID OsPriqueueDequeue(LOS_DL_LIST *priqueueItem) 
  2.     LosTaskCB *runningTask = NULL; 
  3. ⑴  LOS_ListDelete(priqueueItem); 
  4.  
  5. ⑵  runningTask = LOS_DL_LIST_ENTRY(priqueueItem, LosTaskCB, pendList); 
  6. ⑶  if (LOS_ListEmpty(&g_losPriorityQueueList[runningTask->priority])) { 
  7. ⑷      g_priqueueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> runningTask->priority); 
  8.     } 

 ⑴把任務(wù)從任務(wù)就緒隊(duì)列中刪除。⑵獲取被刪除任務(wù)的任務(wù)控制塊信息,以獲取任務(wù)的優(yōu)先級。刪除完任務(wù)后隊(duì)列可能成為空隊(duì)列,所以⑶處代碼判斷任務(wù)就緒隊(duì)列是否為空,如果為空,則需要執(zhí)行⑷處代碼,更新優(yōu)先級位圖,將第31-prioritybit位設(shè)置為0。

2.4 獲取隊(duì)列中的最高優(yōu)先級節(jié)點(diǎn)

獲取任務(wù)就緒隊(duì)列中優(yōu)先級最高的鏈表節(jié)點(diǎn)的函數(shù)為OsPriQueueTop()。

源碼如下:

 
 
 
 
  1. STATIC LOS_DL_LIST *OsPriqueueTop(VOID) 
  2.     UINT32 priority; 
  3.  
  4. ⑴  if (g_priqueueBitmap != 0) { 
  5. ⑵      priority = CLZ(g_priqueueBitmap); 
  6. ⑶      return LOS_DL_LIST_FIRST(&g_losPriorityQueueList[priority]); 
  7.     } 
  8.  
  9.     return (LOS_DL_LIST *)NULL; 

 ⑴處判斷優(yōu)先級位圖g_priqueueBitmap是否為0,如果為0則直接返回NULL,說明任務(wù)就緒隊(duì)列中沒有任何就緒狀態(tài)的任務(wù)。 ⑵處計(jì)算g_priqueueBitmap以二進(jìn)制表示時(shí)高位為0的位數(shù),其值就是任務(wù)的優(yōu)先級priority,以此方法得到的優(yōu)先級就是任務(wù)就緒隊(duì)列中所有優(yōu)先級里最高的。然后⑶處從該優(yōu)先級的隊(duì)列&g_losPriorityQueueList[priority]中獲取第一個(gè)鏈表節(jié)點(diǎn),獲取的就是任務(wù)就緒隊(duì)列中優(yōu)先級最高的任務(wù)。

2.5 獲取指定優(yōu)先級的就緒任務(wù)的數(shù)量

獲取任務(wù)就緒隊(duì)列中指定優(yōu)先級的任務(wù)數(shù)量的函數(shù)為OsPriqueueSize()。

源碼如下:

 
 
 
 
  1. STATIC UINT32 OsPriqueueSize(UINT32 priority) 
  2.     UINT32 itemCnt = 0; 
  3.     LOS_DL_LIST *curPQNode = (LOS_DL_LIST *)NULL; 
  4.  
  5. ⑴  LOS_DL_LIST_FOR_EACH(curPQNode, &g_losPriorityQueueList[priority]) { 
  6. ⑵      ++itemCnt; 
  7.     } 
  8.  
  9.     return itemCnt; 

 ⑴處代碼使用宏LOS_DL_LIST_FOR_EACH定義的for循環(huán)遍歷指定優(yōu)先級priority的雙向鏈表,如果獲取到新節(jié)點(diǎn)則表示該優(yōu)先級下有一個(gè)就緒任務(wù),然后執(zhí)行⑵處代碼,對計(jì)數(shù)進(jìn)行加1操作,返回的結(jié)果就是指定優(yōu)先級下有多少個(gè)就緒任務(wù)。

小結(jié)

掌握鴻蒙輕內(nèi)核的優(yōu)先級就緒隊(duì)列Priority Queue這一重要的數(shù)據(jù)結(jié)構(gòu),會(huì)給進(jìn)一步學(xué)習(xí)、分析鴻蒙輕內(nèi)核源代碼打下了基礎(chǔ),讓后續(xù)的學(xué)習(xí)更加容易。后續(xù)也會(huì)陸續(xù)推出更多的分享文章,敬請期待。

想了解更多內(nèi)容,請?jiān)L問:

和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.


分享標(biāo)題:鴻蒙輕內(nèi)核M核源碼分析系列二數(shù)據(jù)結(jié)構(gòu)-任務(wù)就緒隊(duì)列
網(wǎng)站URL:http://www.5511xx.com/article/ccdhhhh.html