liteos线程的建立和线程优先级选择的策略

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;
}

 

你可能感兴趣的:(liteos)