本文共 2917 字,大约阅读时间需要 9 分钟。
litos线程是通过LOS_TaskCreate 这个函数创建的,其源码分析如下:LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *puwTaskID, TSK_INIT_PARAM_S *pstInitParam){ UINT32 uwRet = LOS_OK; UINTPTR uvIntSave; LOS_TASK_CB *pstTaskCB;#下面这个函数主要是给pstTaskCB这个结构体赋值 uwRet = LOS_TaskCreateOnly(puwTaskID, pstInitParam); if (LOS_OK != uwRet) { return uwRet; } pstTaskCB = OS_TCB_FROM_TID(*puwTaskID);#获得锁 uvIntSave = LOS_IntLock(); pstTaskCB->usTaskStatus &= (~OS_TASK_STATUS_SUSPEND); pstTaskCB->usTaskStatus |= OS_TASK_STATUS_READY;#if (LOSCFG_BASE_CORE_CPUP == YES) g_pstCpup[pstTaskCB->uwTaskID].uwID = pstTaskCB->uwTaskID; g_pstCpup[pstTaskCB->uwTaskID].usStatus = pstTaskCB->usTaskStatus;#endif#将这个线程按照优先级插入到全局变量g_pstLosPriorityQueueList 中,这里的形参pstTaskCB->usPriority表示这个进程的优先级 osPriqueueEnqueue(&pstTaskCB->stPendList, pstTaskCB->usPriority);#从全局变量g_pstLosPriorityQueueList 中选择下一个要执行的线程 g_stLosTask.pstNewTask = LOS_DL_LIST_ENTRY(osPriqueueTop(), LOS_TASK_CB, stPendList); /*lint !e413*/ if ((g_bTaskScheduled) && (g_usLosTaskLock == 0)) {#如果下一个要运行的线程不等于当前正在运行的线程,则调用OSSchedule()来触发调度 if (g_stLosTask.pstRunTask != g_stLosTask.pstNewTask) { if (LOS_CHECK_SCHEDULE) {#释放锁,从这里可以知道对全局变量g_pstLosPriorityQueueList 操作是要加锁的 (VOID)LOS_IntRestore(uvIntSave); osSchedule(); return LOS_OK; } } } (VOID)LOS_IntRestore(uvIntSave); return LOS_OK;}我们重点看看线程优先级是如何选择的首先全局变量g_pstLosPriorityQueueList 的初始化如下:#从这里可以知道这个函数是被放到text段LITE_OS_SEC_TEXT VOID osPriqueueInit(VOID){ UINT32 uwPri = 0; UINT32 uwSize = 0;#这里的OS_PRIORITY_QUEUE_PRIORITYNUM 表示最大支持的优先级 uwSize = OS_PRIORITY_QUEUE_PRIORITYNUM * sizeof(LOS_DL_LIST);#申请空间 g_pstLosPriorityQueueList = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, uwSize); if (NULL == g_pstLosPriorityQueueList) { return; }#每个优先级都对应一个双向链表 for (uwPri = 0; uwPri < OS_PRIORITY_QUEUE_PRIORITYNUM; ++uwPri) { LOS_ListInit(&g_pstLosPriorityQueueList[uwPri]); }}#每个优先级都对应一个双向链表LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListInit(LOS_DL_LIST *pstList){ pstList->pstNext = pstList; pstList->pstPrev = pstList;}再看看线程是如何插入到全局变量g_pstLosPriorityQueueList 中,其源码如下:#第一个形参是指向线程的指针,第二个形参是线程的优先级LITE_OS_SEC_TEXT VOID osPriqueueEnqueue(LOS_DL_LIST *ptrPQItem, UINT32 uwPri){#g_pstLosPriorityQueueList是一个以优先级为index的数组,数组中的每一项都是一个链表,这个链表中的每一个节点都是#一个线程,同一个链表中的优先级相等 LOS_ListTailInsert(&g_pstLosPriorityQueueList[uwPri], ptrPQItem);}最后再看看如何选择下一个要运行的线程LITE_OS_SEC_TEXT LOS_DL_LIST *osPriqueueTop(VOID){ UINT32 uwPri = 0;#优先级从高到低,从这里知道0对应的优先级最高 for (uwPri = 0; uwPri < OS_PRIORITY_QUEUE_PRIORITYNUM; ++uwPri) {#检测当前优先级是否有对应的线程要运行 if (!LOS_ListEmpty(&g_pstLosPriorityQueueList[uwPri])) {#返回这个优先级队列第一个线程 return LOS_DL_LIST_FIRST(&g_pstLosPriorityQueueList[uwPri]); } } return (LOS_DL_LIST *)NULL;}
转载地址:http://lpnmi.baihongyu.com/