void OS_PendListInsertPrio (OS_PEND_LIST *p_pend_list,
OS_PEND_DATA *p_pend_data)
{
OS_PRIO prio;
OS_TCB *p_tcb;
OS_TCB *p_tcb_next;
OS_PEND_DATA *p_pend_data_prev;
OS_PEND_DATA *p_pend_data_next;
p_tcb = p_pend_data->TCBPtr; /* Obtain the priority of the task to insert */
prio = p_tcb->Prio; /*獲取當前傳入的等待任務的優先級*/
if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0) { /*如果任務是第一個等待該目標物件的任務 *//* CASE 0: Insert when there are no entries */
p_pend_list->NbrEntries = (OS_OBJ_QTY)1; /*等待串列的任務個數加1*/ /* This is the first entry */
p_pend_data->NextPtr = (OS_PEND_DATA *)0; /*本次傳入的結構指標指向的下一個是0 */ /* No other OS_PEND_DATAs in the list */
p_pend_data->PrevPtr = (OS_PEND_DATA *)0; /*本次傳入的結構指標指向的上一個是0 */
p_pend_list->HeadPtr = p_pend_data; /*誰指向本次結構 表首p_pend_list->HeadPtr */ /* */
p_pend_list->TailPtr = p_pend_data; /*誰指向本次結構 表尾p_pend_list->TailPtr */
} else { /*如果任務不是第一個等待該目標物件的任務 */
p_pend_list->NbrEntries++; /*等待串列的任務個數加1*/ /* CASE 1: One more OS_PEND_DATA in the list */
p_pend_data_next = p_pend_list->HeadPtr; /*把表首的地址賦給中間指標變數p_pend_data_next*/
while (p_pend_data_next != (OS_PEND_DATA *)0) { /*此時表首的地址自然不為0,而是鏈表中的第一個物件的地址,即p_pend_data_next */ /* Find the position where to insert */
p_tcb_next = p_pend_data_next->TCBPtr; /*此操作的目的是將本次傳入的任務的優先級與從表頭開始的各個節點的任務的優先級進行比較, */
if (prio < p_tcb_next->Prio) { /*如果本次的任務的優先級比表頭的任務的優先級高,則直接跳出while,進入表首的插入操作,只要while沒有回圈,只做一次,那么while跳出之后一定會進入表首的插入操作, */
break; /*如果本次的任務的優先級比表頭的任務的優先級高,則直接跳出while, */
//如果whil第二次回圈進入此條件,那么跳出回圈后進入中間插入操作
/* Found! ... insert BEFORE current */
} else {
p_pend_data_next = p_pend_data_next->NextPtr; /*第二次插入操作*如果本次的任務的優先級比表頭的任務的優先級低,那么將表頭的下一個指標0賦給p_pend_data_next,(也作為回圈查詢最低優先級的條件),此時退出while回圈,進入尾部插入的if操作 */ /* Not Found, follow the list */
} //第三次插入操作,因為任務比表首的任務優先級低所以進入了這一步操作pend_data_next->NextPtr指向的是鏈表中第二個節點,不為0,不能退出回圈,while繼續回圈執行,
//這一行的目的就是將優先級較低的節點向鏈表的尾部移動// //獲取第二個節點成員的優先級與本次任務的優先級進入比較
// 同時賦給節點變數p_pend_data_next, // //如果while第二次進入此條件,那么(pend_data_next->NextPtr)->NextPtr,即第二個節點的NextPtr指向0,while退出回圈,進入尾部插入操作,
}
if (p_pend_data_next == (OS_PEND_DATA *)0) { /* 最低優先級的尾部插入操作TCB to insert is lower in prio */
p_pend_data->NextPtr = (OS_PEND_DATA *)0; //如果優先級最低,那么此時的p_pend_data_next還是最后一個節點,也即將成為倒數第二個節點,
//先完成本次的表尾p_pend_data指向誰,它的后繼,// //1490行//p_pend_data_next把自己的下一個節點的地址賦給了自己,它自己成為了自己的下一個節點,表尾的下一個指向地址0,
//p_pend_data->NextPtr // //所以進入尾部插入的條件滿足了
/* ... insert at the tail. */
p_pend_data_prev = p_pend_list->TailPtr; //這兩行操作的目的是把先前的表尾節點先賦給中間周轉指標變數p_pend_data_prev ,此時p_pend_data_prev成為了表尾,也即將成為倒數第二個節點,
p_pend_data->PrevPtr = p_pend_data_prev; //p_pend_data為當前優先級最低的節點,它的前一個指標指向上一次的表尾,它成為表尾的同時,也把上一次的尾部節點變成了倒數第二個節點
//然后完成本次的表尾p_pend_data指向誰,它的前驅,//
//p_pend_data->PrevPtr //
p_pend_data_prev->NextPtr = p_pend_data; //再完成誰指向本次表尾的操作,p_pend_data要賦給誰,//
p_pend_list->TailPtr = p_pend_data; //while不論回圈了幾次,只要是從else陳述句中獲得不滿足while條件回圈跳出的,都會進入尾部插入操作//
} else {
if (p_pend_data_next->PrevPtr == (OS_PEND_DATA *)0) { /* 最高優先級的首部插入操作 Is new TCB highest priority? */
p_pend_data_next->PrevPtr = p_pend_data; /* Yes, insert as new Head of list */
p_pend_data->PrevPtr = (OS_PEND_DATA *)0;
p_pend_data->NextPtr = p_pend_data_next;
p_pend_list->HeadPtr = p_pend_data; //while只做一次,并且是從if陳述句中退出的,那么都將會進入首部插入操作//
} else { /* 優先級回圈比較后的中間插入操作 */
p_pend_data_prev = p_pend_data_next->PrevPtr;/* No, insert in between two entries */
p_pend_data->PrevPtr = p_pend_data_prev;
p_pend_data->NextPtr = p_pend_data_next;
p_pend_data_prev->NextPtr = p_pend_data;
p_pend_data_next->PrevPtr = p_pend_data; //while做了最少超過一次回圈,從if陳述句中退出的,都將進入中間插入操作,//
}
}
}
}
//這樣經過while回圈后,等待串列將會按優先級的大小,從高到低,串連成雙向鏈表,給系統呼叫,
//鏈表的插入操作,要做的是本次節點指標指向誰,與誰指向本次節點指標的賦值操作//
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/70274.html
標籤:單片機/工控
上一篇:vrrp路由備份-華為ensp
下一篇:arduino使用
