|
|
|
@ -68,13 +68,83 @@
|
|
|
|
|
#if (LOSCFG_BASE_CORE_TSK_LIMIT <= 0)
|
|
|
|
|
#error "task maxnum cannot be zero"
|
|
|
|
|
#endif /* LOSCFG_BASE_CORE_TSK_LIMIT <= 0 */
|
|
|
|
|
|
|
|
|
|
LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray;
|
|
|
|
|
LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask;
|
|
|
|
|
LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList;
|
|
|
|
|
LITE_OS_SEC_BSS UINT32 g_taskMaxNum;
|
|
|
|
|
/*
|
|
|
|
|
基本概念
|
|
|
|
|
从系统角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、
|
|
|
|
|
使用内存空间等系统资源,并独立于其它任务运行。
|
|
|
|
|
任务模块可以给用户提供多个任务,实现任务间的切换,帮助用户管理业务程序流程。具有如下特性:
|
|
|
|
|
支持多任务。
|
|
|
|
|
一个任务表示一个线程。
|
|
|
|
|
抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。
|
|
|
|
|
相同优先级任务支持时间片轮转调度方式。
|
|
|
|
|
共有32个优先级[0-31],最高优先级为0,最低优先级为31。
|
|
|
|
|
|
|
|
|
|
任务状态通常分为以下四种:
|
|
|
|
|
就绪(Ready):该任务在就绪队列中,只等待CPU。
|
|
|
|
|
运行(Running):该任务正在执行。
|
|
|
|
|
阻塞(Blocked):该任务不在就绪队列中。包含任务被挂起(suspend状态)、任务被延时(delay状态)、
|
|
|
|
|
任务正在等待信号量、读写队列或者等待事件等。
|
|
|
|
|
退出态(Dead):该任务运行结束,等待系统回收资源。
|
|
|
|
|
|
|
|
|
|
任务状态迁移说明
|
|
|
|
|
就绪态→运行态
|
|
|
|
|
任务创建后进入就绪态,发生任务切换时,就绪队列中最高优先级的任务被执行,
|
|
|
|
|
从而进入运行态,但此刻该任务依旧在就绪队列中。
|
|
|
|
|
运行态→阻塞态
|
|
|
|
|
正在运行的任务发生阻塞(挂起、延时、读信号量等)时,该任务会从就绪队列中删除,
|
|
|
|
|
任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪队列中最高优先级任务。
|
|
|
|
|
阻塞态→就绪态(阻塞态→运行态)
|
|
|
|
|
阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被
|
|
|
|
|
恢复的任务会被加入就绪队列,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于
|
|
|
|
|
正在运行任务的优先级,则会发生任务切换,该任务由就绪态变成运行态。
|
|
|
|
|
就绪态→阻塞态
|
|
|
|
|
任务也有可能在就绪态时被阻塞(挂起),此时任务状态由就绪态变为阻塞态,该任务
|
|
|
|
|
从就绪队列中删除,不会参与任务调度,直到该任务被恢复。
|
|
|
|
|
运行态→就绪态
|
|
|
|
|
有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪队列中最高优先级任务
|
|
|
|
|
变为运行态,那么原先运行的任务由运行态变为就绪态,依然在就绪队列中。
|
|
|
|
|
运行态→退出态
|
|
|
|
|
运行中的任务运行结束,任务状态由运行态变为退出态。退出态包含任务运行结束的正常退出状态
|
|
|
|
|
以及Invalid状态。例如,任务运行结束但是没有自删除,对外呈现的就是Invalid状态,即退出态。
|
|
|
|
|
阻塞态→退出态
|
|
|
|
|
阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。
|
|
|
|
|
|
|
|
|
|
主要术语
|
|
|
|
|
任务ID
|
|
|
|
|
任务ID,在任务创建时通过参数返回给用户,是任务的重要标识。系统中的ID号是唯一的。用户可以
|
|
|
|
|
通过任务ID对指定任务进行任务挂起、任务恢复、查询任务名等操作。
|
|
|
|
|
|
|
|
|
|
任务优先级
|
|
|
|
|
优先级表示任务执行的优先顺序。任务的优先级决定了在发生任务切换时即将要执行的任务,
|
|
|
|
|
就绪队列中最高优先级的任务将得到执行。
|
|
|
|
|
|
|
|
|
|
任务入口函数
|
|
|
|
|
新任务得到调度后将执行的函数。该函数由用户实现,在任务创建时,通过任务创建结构体设置。
|
|
|
|
|
|
|
|
|
|
任务栈
|
|
|
|
|
每个任务都拥有一个独立的栈空间,我们称为任务栈。栈空间里保存的信息包含局部变量、寄存器、函数参数、函数返回地址等。
|
|
|
|
|
|
|
|
|
|
任务上下文
|
|
|
|
|
任务在运行过程中使用的一些资源,如寄存器等,称为任务上下文。当这个任务挂起时,其他任务继续执行,
|
|
|
|
|
可能会修改寄存器等资源中的值。如果任务切换时没有保存任务上下文,可能会导致任务恢复后出现未知错误。
|
|
|
|
|
因此,Huawei LiteOS在任务切换时会将切出任务的任务上下文信息,保存在自身的任务栈中,以便任务恢复后,
|
|
|
|
|
从栈空间中恢复挂起时的上下文信息,从而继续执行挂起时被打断的代码。
|
|
|
|
|
任务控制块TCB
|
|
|
|
|
每个任务都含有一个任务控制块(TCB)。TCB包含了任务上下文栈指针(stack pointer)、任务状态、
|
|
|
|
|
任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。
|
|
|
|
|
任务切换
|
|
|
|
|
任务切换包含获取就绪队列中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。
|
|
|
|
|
|
|
|
|
|
运作机制
|
|
|
|
|
用户创建任务时,系统会初始化任务栈,预置上下文。此外,系统还会将“任务入口函数”
|
|
|
|
|
地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。
|
|
|
|
|
*/
|
|
|
|
|
LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray;//任务池 128个
|
|
|
|
|
LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask;//空闲任务链表
|
|
|
|
|
LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList;//回收任务链表
|
|
|
|
|
LITE_OS_SEC_BSS UINT32 g_taskMaxNum;//任务最大个数
|
|
|
|
|
LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores */
|
|
|
|
|
LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent;
|
|
|
|
|
LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent;//资源的事件
|
|
|
|
|
/* spinlock for task module, only available on SMP mode */
|
|
|
|
|
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin);
|
|
|
|
|
|
|
|
|
@ -82,7 +152,7 @@ STATIC VOID OsConsoleIDSetHook(UINT32 param1,
|
|
|
|
|
UINT32 param2) __attribute__((weakref("OsSetConsoleID")));
|
|
|
|
|
|
|
|
|
|
/* temp task blocks for booting procedure */
|
|
|
|
|
LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM];
|
|
|
|
|
LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM];//启动引导过程中使用的临时任务
|
|
|
|
|
|
|
|
|
|
LosTaskCB *OsGetMainTask(VOID)
|
|
|
|
|
{
|
|
|
|
@ -92,23 +162,23 @@ LosTaskCB *OsGetMainTask(VOID)
|
|
|
|
|
VOID OsSetMainTask(VOID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 i;
|
|
|
|
|
CHAR *name = "osMain";
|
|
|
|
|
CHAR *name = "osMain";//任务名称
|
|
|
|
|
SchedParam schedParam = { 0 };
|
|
|
|
|
|
|
|
|
|
schedParam.policy = LOS_SCHED_RR;
|
|
|
|
|
schedParam.basePrio = OS_PROCESS_PRIORITY_HIGHEST;
|
|
|
|
|
schedParam.priority = OS_TASK_PRIORITY_LOWEST;
|
|
|
|
|
|
|
|
|
|
//为每个CPU core 设置mainTask
|
|
|
|
|
for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {
|
|
|
|
|
g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED;
|
|
|
|
|
g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT;
|
|
|
|
|
g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT;//128
|
|
|
|
|
g_mainTask[i].processCB = OS_KERNEL_PROCESS_GROUP;
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP_LOCKDEP
|
|
|
|
|
g_mainTask[i].lockDep.lockDepth = 0;
|
|
|
|
|
g_mainTask[i].lockDep.waitLock = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
(VOID)strncpy_s(g_mainTask[i].taskName, OS_TCB_NAME_LEN, name, OS_TCB_NAME_LEN - 1);
|
|
|
|
|
LOS_ListInit(&g_mainTask[i].lockList);
|
|
|
|
|
LOS_ListInit(&g_mainTask[i].lockList);//初始化任务锁链表,上面挂的是任务已申请到的互斥锁
|
|
|
|
|
(VOID)OsSchedParamInit(&g_mainTask[i], schedParam.policy, &schedParam, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -122,31 +192,34 @@ VOID OsSetMainTaskProcess(UINTPTR processCB)
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//空闲任务,每个CPU都有自己的空闲任务
|
|
|
|
|
LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID)
|
|
|
|
|
{
|
|
|
|
|
while (1) {
|
|
|
|
|
WFI;
|
|
|
|
|
while (1) {//只有一个死循环
|
|
|
|
|
WFI;//WFI指令:arm core立即进入low-power standly state,进入休眠模式,等待中断
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList);
|
|
|
|
|
LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList);//将任务挂入回收链表,等待回收
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
查找task通过OS_TCB_FROM_PENDLIST来实现,相当于由LOS_DL_LIST找到LosTaskCB,
|
|
|
|
|
将这些和参数任务绑在一起的task唤醒
|
|
|
|
|
*/
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
|
|
|
|
|
if (!LOS_ListEmpty(&taskCB->joinList)) {
|
|
|
|
|
LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList)));
|
|
|
|
|
OsTaskWakeClearPendMask(resumedTask);
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join任务处理
|
|
|
|
|
if (!LOS_ListEmpty(&taskCB->joinList)) {//joinList中的节点身上都有阻塞标签
|
|
|
|
|
LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList)));//通过贴有JOIN标签链表的第一个节点找到Task
|
|
|
|
|
OsTaskWakeClearPendMask(resumedTask);//清除任务的挂起标记
|
|
|
|
|
resumedTask->ops->wake(resumedTask);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
taskCB->taskStatus |= OS_TASK_STATUS_EXIT;
|
|
|
|
|
taskCB->taskStatus |= OS_TASK_STATUS_EXIT;//贴上任务退出标签
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//挂起任务,任务进入等待链表,Join代表是支持通过的第一个任务去唤醒其他的任务
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_INIT) {
|
|
|
|
@ -165,13 +238,13 @@ LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
|
|
|
|
|
|
|
|
|
|
return LOS_EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//任务设置分离模式Deatch和JOIN是一对有你没我的状态
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
|
|
|
|
|
if (LOS_ListEmpty(&(taskCB->joinList))) {
|
|
|
|
|
LOS_ListDelete(&(taskCB->joinList));
|
|
|
|
|
taskCB->taskStatus &= ~OS_TASK_FLAG_PTHREAD_JOIN;
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join状态时
|
|
|
|
|
if (LOS_ListEmpty(&(taskCB->joinList))) {//joinlist中没有数据了
|
|
|
|
|
LOS_ListDelete(&(taskCB->joinList));//所谓删除就是自己指向自己
|
|
|
|
|
taskCB->taskStatus &= ~OS_TASK_FLAG_PTHREAD_JOIN;//去掉JOIN标签
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
/* This error code has a special purpose and is not allowed to appear again on the interface */
|
|
|
|
@ -181,39 +254,40 @@ LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
|
|
|
|
|
return LOS_EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//初始化任务模块
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(UINTPTR processCB)
|
|
|
|
|
{
|
|
|
|
|
UINT32 index;
|
|
|
|
|
UINT32 size;
|
|
|
|
|
UINT32 ret;
|
|
|
|
|
|
|
|
|
|
g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;
|
|
|
|
|
size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);
|
|
|
|
|
g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;//任务池中最多默认128个,可谓铁打的任务池流水的线程
|
|
|
|
|
size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);//计算需分配内存总大小
|
|
|
|
|
/*
|
|
|
|
|
* This memory is resident memory and is used to save the system resources
|
|
|
|
|
* of task control block and will not be freed.
|
|
|
|
|
*/
|
|
|
|
|
g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);
|
|
|
|
|
g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);//任务池常驻内存,不被释放
|
|
|
|
|
if (g_taskCBArray == NULL) {
|
|
|
|
|
ret = LOS_ERRNO_TSK_NO_MEMORY;
|
|
|
|
|
goto EXIT;
|
|
|
|
|
}
|
|
|
|
|
(VOID)memset_s(g_taskCBArray, size, 0, size);
|
|
|
|
|
|
|
|
|
|
LOS_ListInit(&g_losFreeTask);
|
|
|
|
|
LOS_ListInit(&g_taskRecycleList);
|
|
|
|
|
for (index = 0; index < g_taskMaxNum; index++) {
|
|
|
|
|
g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;
|
|
|
|
|
g_taskCBArray[index].taskID = index;
|
|
|
|
|
LOS_ListInit(&g_losFreeTask);//初始化空闲任务链表
|
|
|
|
|
LOS_ListInit(&g_taskRecycleList);//初始化回收任务链表
|
|
|
|
|
for (index = 0; index < g_taskMaxNum; index++) {//任务挨个初始化
|
|
|
|
|
g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;//默认未使用,
|
|
|
|
|
g_taskCBArray[index].taskID = index;//任务ID[0~g_taskMaxNum-1]
|
|
|
|
|
g_taskCBArray[index].processCB = processCB;
|
|
|
|
|
LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);
|
|
|
|
|
}
|
|
|
|
|
LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);//通过pendlist节点插入空闲任务列表
|
|
|
|
|
}//注意:这里挂的是pendList节点,可以取TCB也要通过OS_TCB_FROM-PENDLIST取
|
|
|
|
|
|
|
|
|
|
g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;
|
|
|
|
|
g_taskCBArray[index].taskID = index;
|
|
|
|
|
g_taskCBArray[index].processCB = processCB;
|
|
|
|
|
|
|
|
|
|
ret = OsSchedInit();
|
|
|
|
|
ret = OsSchedInit();//调度器初始化
|
|
|
|
|
|
|
|
|
|
EXIT:
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
@ -221,41 +295,41 @@ EXIT:
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取IdletaskId,每个CPU核都对Task进行了内部管理,做到真正的并行处理
|
|
|
|
|
UINT32 OsGetIdleTaskId(VOID)
|
|
|
|
|
{
|
|
|
|
|
return OsSchedRunqueueIdleGet()->taskID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//创建一个空闲任务
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(UINTPTR processID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
|
TSK_INIT_PARAM_S taskInitParam;
|
|
|
|
|
UINT32 idleTaskID;
|
|
|
|
|
|
|
|
|
|
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
|
|
|
|
|
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;
|
|
|
|
|
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;
|
|
|
|
|
taskInitParam.pcName = "Idle";
|
|
|
|
|
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//任务初始参数清零
|
|
|
|
|
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;//入口函数
|
|
|
|
|
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;//任务栈大小 2K
|
|
|
|
|
taskInitParam.pcName = "Idle";//任务名称叫pcNAME
|
|
|
|
|
taskInitParam.policy = LOS_SCHED_IDLE;
|
|
|
|
|
taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST;
|
|
|
|
|
taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST;//默认最低优先级31
|
|
|
|
|
taskInitParam.processID = processID;
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
|
taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());
|
|
|
|
|
taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());//每个idle任务只在单独的CPU上运行
|
|
|
|
|
#endif
|
|
|
|
|
ret = LOS_TaskCreateOnly(&idleTaskID, &taskInitParam);
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
LosTaskCB *idleTask = OS_TCB_FROM_TID(idleTaskID);
|
|
|
|
|
idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;
|
|
|
|
|
idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//标记为系统任务,idle任务是给CPU休息用的,当然是个系统任务
|
|
|
|
|
OsSchedRunqueueIdleInit(idleTask);
|
|
|
|
|
|
|
|
|
|
return LOS_TaskResume(idleTaskID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Description : get id of current running task.
|
|
|
|
|
* Description : get id of current running task. |获取当前CPU正在执行的任务ID
|
|
|
|
|
* Return : task id
|
|
|
|
|
*/
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
|
|
|
|
@ -267,7 +341,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
|
|
|
|
|
}
|
|
|
|
|
return runTask->taskID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//创建指定任务同步信号量
|
|
|
|
|
STATIC INLINE UINT32 TaskSyncCreate(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
|
|
|
|
@ -280,7 +354,7 @@ STATIC INLINE UINT32 TaskSyncCreate(LosTaskCB *taskCB)
|
|
|
|
|
#endif
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//销毁指定任务同步信号量
|
|
|
|
|
STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
|
|
|
|
@ -291,6 +365,7 @@ STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
|
//任务同步等待,通过信号量保持同步
|
|
|
|
|
STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
|
|
|
|
@ -316,7 +391,7 @@ STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//同步唤醒
|
|
|
|
|
STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
|
|
|
|
@ -338,14 +413,14 @@ STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB)
|
|
|
|
|
taskCB->taskStatus = OS_TASK_STATUS_UNUSED;
|
|
|
|
|
LOS_ListAdd(&g_losFreeTask, &taskCB->pendList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//释放任务在内核状态下占用的资源
|
|
|
|
|
STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack)
|
|
|
|
|
{
|
|
|
|
|
OsTaskSyncDestroy(syncSignal);
|
|
|
|
|
OsTaskSyncDestroy(syncSignal);//任务销毁,同步信息
|
|
|
|
|
|
|
|
|
|
(VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack);
|
|
|
|
|
(VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack);//释放内核态空间
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//释放任务资源
|
|
|
|
|
STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT;
|
|
|
|
@ -353,7 +428,7 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
|
|
|
|
|
UINTPTR topOfStack;
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
|
|
|
if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) {
|
|
|
|
|
if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) {//释放用户态栈
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
UINT32 mapBase = (UINTPTR)taskCB->userMapBase;
|
|
|
|
|
UINT32 mapSize = taskCB->userMapSize;
|
|
|
|
@ -363,7 +438,7 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
|
|
|
|
|
|
|
|
|
|
LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB);
|
|
|
|
|
LOS_ASSERT(!(OsProcessVmSpaceGet(processCB) == NULL));
|
|
|
|
|
UINT32 ret = OsUnMMap(OsProcessVmSpaceGet(processCB), (UINTPTR)mapBase, mapSize);
|
|
|
|
|
UINT32 ret = OsUnMMap(OsProcessVmSpaceGet(processCB), (UINTPTR)mapBase, mapSize);//解除映射
|
|
|
|
|
if ((ret != LOS_OK) && (mapBase != 0) && !OsProcessIsInit(processCB)) {
|
|
|
|
|
PRINT_ERR("process(%u) unmmap user task(%u) stack failed! mapbase: 0x%x size :0x%x, error: %d\n",
|
|
|
|
|
processCB->processID, taskCB->taskID, mapBase, mapSize, ret);
|
|
|
|
@ -375,36 +450,36 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务还未使用情况
|
|
|
|
|
topOfStack = taskCB->topOfStack;
|
|
|
|
|
taskCB->topOfStack = 0;
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
|
|
|
|
|
syncSignal = taskCB->syncSignal;
|
|
|
|
|
taskCB->syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT;
|
|
|
|
|
#endif
|
|
|
|
|
OsTaskKernelResourcesToFree(syncSignal, topOfStack);
|
|
|
|
|
OsTaskKernelResourcesToFree(syncSignal, topOfStack);//释放内核所占内存,即内核栈的栈空间
|
|
|
|
|
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
|
|
|
OsClearSigInfoTmpList(&(taskCB->sig));
|
|
|
|
|
OsClearSigInfoTmpList(&(taskCB->sig));//归还信号控制块的内存
|
|
|
|
|
#endif
|
|
|
|
|
OsInsertTCBToFreeList(taskCB);
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//批量回收任务
|
|
|
|
|
LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree(void)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
|
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
while (!LOS_ListEmpty(&g_taskRecycleList)) {
|
|
|
|
|
LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList));
|
|
|
|
|
LOS_ListDelete(&taskCB->pendList);
|
|
|
|
|
while (!LOS_ListEmpty(&g_taskRecycleList)) {//遍历回收链表
|
|
|
|
|
LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList));//取出任务
|
|
|
|
|
LOS_ListDelete(&taskCB->pendList);//重置节点
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
|
|
|
|
|
OsTaskResourcesToFree(taskCB);
|
|
|
|
|
OsTaskResourcesToFree(taskCB);//释放任务所占资源
|
|
|
|
|
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
}
|
|
|
|
@ -414,7 +489,7 @@ LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree(void)
|
|
|
|
|
/*
|
|
|
|
|
* Description : All task entry
|
|
|
|
|
* Input : taskID --- The ID of the task to be run
|
|
|
|
|
*/
|
|
|
|
|
*///所有任务的入口函数,OsTaskEntry是new task OsTaskStackInit时指定的
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
|
|
|
|
|
{
|
|
|
|
|
LOS_ASSERT(!OS_TID_CHECK_INVALID(taskID));
|
|
|
|
@ -424,19 +499,19 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
|
|
|
|
|
* from interrupt and other cores. release task spinlock and enable
|
|
|
|
|
* interrupt in sequence at the task entry.
|
|
|
|
|
*/
|
|
|
|
|
LOS_SpinUnlock(&g_taskSpin);
|
|
|
|
|
(VOID)LOS_IntUnLock();
|
|
|
|
|
LOS_SpinUnlock(&g_taskSpin);//释放任务自旋锁
|
|
|
|
|
(VOID)LOS_IntUnLock();//恢复中断
|
|
|
|
|
|
|
|
|
|
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
|
|
|
|
taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],
|
|
|
|
|
taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],//调出任务的入口函数
|
|
|
|
|
taskCB->args[2], taskCB->args[3]); /* 2 & 3: just for args array index */
|
|
|
|
|
if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) {
|
|
|
|
|
taskCB->joinRetval = 0;
|
|
|
|
|
taskCB->joinRetval = 0;//结合数为0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OsRunningTaskToExit(taskCB, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//任务创建参数检查
|
|
|
|
|
STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
|
|
|
|
|
{
|
|
|
|
|
UINT32 poolSize = OS_SYS_MEM_SIZE;
|
|
|
|
@ -455,30 +530,30 @@ STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initP
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (initParam->pfnTaskEntry == NULL) {
|
|
|
|
|
if (initParam->pfnTaskEntry == NULL) {//入口函数不能为空
|
|
|
|
|
return LOS_ERRNO_TSK_ENTRY_NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) {
|
|
|
|
|
if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) {//优先级必须大于31
|
|
|
|
|
return LOS_ERRNO_TSK_PRIOR_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (initParam->uwStackSize > poolSize) {
|
|
|
|
|
if (initParam->uwStackSize > poolSize) {//希望申请的栈大小不能大于总池子
|
|
|
|
|
return LOS_ERRNO_TSK_STKSZ_TOO_LARGE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (initParam->uwStackSize == 0) {
|
|
|
|
|
if (initParam->uwStackSize == 0) {//任何任务都必须由内核态栈,所以uwStackSize不能为0
|
|
|
|
|
initParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
|
|
|
|
|
}
|
|
|
|
|
initParam->uwStackSize = (UINT32)ALIGN(initParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE);
|
|
|
|
|
|
|
|
|
|
if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) {
|
|
|
|
|
if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) {//运行栈空间不能低于最低值
|
|
|
|
|
return LOS_ERRNO_TSK_STKSZ_TOO_SMALL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//任务栈(内核态)内存分配,由内核态进程空间提供,即KProcess进程空间
|
|
|
|
|
STATIC VOID TaskCBDeInit(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -531,13 +606,13 @@ STATIC VOID TaskCBBaseInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
|
|
|
|
|
LOS_ListInit(&taskCB->joinList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOS_ListInit(&taskCB->lockList);
|
|
|
|
|
LOS_ListInit(&taskCB->lockList);//初始化互斥锁链表
|
|
|
|
|
SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME);
|
|
|
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
|
|
|
taskCB->futex.index = OS_INVALID_VALUE;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//任务初始化
|
|
|
|
|
STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
@ -546,7 +621,7 @@ STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
|
|
|
|
|
LosSchedParam initSchedParam = {0};
|
|
|
|
|
UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy;
|
|
|
|
|
|
|
|
|
|
TaskCBBaseInit(taskCB, initParam);
|
|
|
|
|
TaskCBBaseInit(taskCB, initParam);//初始化任务的基本信息,task->stackPointer指向内核态栈sp位置,该位置存着任务初始上下文
|
|
|
|
|
|
|
|
|
|
schedParam.policy = policy;
|
|
|
|
|
ret = OsProcessAddNewTask(initParam->processID, taskCB, &schedParam, &numCount);
|
|
|
|
@ -598,25 +673,27 @@ STATIC UINT32 TaskStackInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam
|
|
|
|
|
#endif
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取一个空闲TCB
|
|
|
|
|
STATIC LosTaskCB *GetFreeTaskCB(VOID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
|
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
if (LOS_ListEmpty(&g_losFreeTask)) {
|
|
|
|
|
if (LOS_ListEmpty(&g_losFreeTask)) {//全局空闲task为空
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
PRINT_ERR("No idle TCB in the system!\n");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask));
|
|
|
|
|
LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask));
|
|
|
|
|
LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask));//从g_losFreeTask链表中摘除自己
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
|
|
|
|
|
return taskCB;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
创建任务,并使该任务进入suspend状态,不对该状态进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态
|
|
|
|
|
*/
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
|
|
|
|
|
{
|
|
|
|
|
UINT32 errRet = TaskCreateParamCheck(taskID, initParam);
|
|
|
|
@ -656,7 +733,7 @@ DEINIT_TCB:
|
|
|
|
|
TaskCBDeInit(taskCB);
|
|
|
|
|
return errRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
@ -670,7 +747,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in
|
|
|
|
|
return LOS_ERRNO_TSK_YIELD_IN_INT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OsProcessIsUserMode(OsCurrProcessGet())) {
|
|
|
|
|
if (OsProcessIsUserMode(OsCurrProcessGet())) {//当前进程为用户进程
|
|
|
|
|
initParam->processID = (UINTPTR)OsGetKernelInitProcess();
|
|
|
|
|
} else {
|
|
|
|
|
initParam->processID = (UINTPTR)OsCurrProcessGet();
|
|
|
|
@ -696,7 +773,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in
|
|
|
|
|
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//恢复挂起的任务,是该任务进入ready状态
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -711,7 +788,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
|
|
|
|
|
/* clear pending signal */
|
|
|
|
|
taskCB->signal &= ~SIGNAL_SUSPEND;
|
|
|
|
|
taskCB->signal &= ~SIGNAL_SUSPEND;//清楚挂起信号
|
|
|
|
|
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
|
|
|
|
|
errRet = LOS_ERRNO_TSK_NOT_CREATED;
|
|
|
|
@ -737,13 +814,13 @@ LOS_ERREND:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Check if needs to do the suspend operation on the running task.
|
|
|
|
|
* Return TRUE, if needs to do the suspension.
|
|
|
|
|
* Return FALSE, if meets following circumstances:
|
|
|
|
|
* 1. Do the suspension across cores, if SMP is enabled
|
|
|
|
|
* 2. Do the suspension when preemption is disabled
|
|
|
|
|
* 3. Do the suspension in hard-irq
|
|
|
|
|
* then LOS_TaskSuspend will directly return with 'ret' value.
|
|
|
|
|
* Check if needs to do the suspend operation on the running task.//检查是否需要对正在运行的任务执行挂起操作。
|
|
|
|
|
* Return TRUE, if needs to do the suspension. //如果需要暂停,返回TRUE。
|
|
|
|
|
* Return FALSE, if meets following circumstances: //如果满足一下情况,则返回FALSE:
|
|
|
|
|
* 1. Do the suspension across cores, if SMP is enabled //1.如果启用了SMP,则跨CPU核执行挂起操作
|
|
|
|
|
* 2. Do the suspension when preemption is disabled //2.当禁用抢占时则挂起
|
|
|
|
|
* 3. Do the suspension in hard-irq //3.在硬中断时则挂起
|
|
|
|
|
* then LOS_TaskSuspend will directly return with 'ret' value. //那么LOS_taskssuspend将直接返回ret值。
|
|
|
|
|
*/
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UINT32 *ret)
|
|
|
|
|
{
|
|
|
|
@ -752,20 +829,20 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
|
/* ASYNCHRONIZED. No need to do task lock checking */
|
|
|
|
|
if (taskCB->currCpu != ArchCurrCpuid()) {
|
|
|
|
|
if (taskCB->currCpu != ArchCurrCpuid()) {//跨CPU核的情况
|
|
|
|
|
taskCB->signal = SIGNAL_SUSPEND;
|
|
|
|
|
LOS_MpSchedule(taskCB->currCpu);
|
|
|
|
|
LOS_MpSchedule(taskCB->currCpu);//task所属CPU执行调度
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (!OsPreemptableInSched()) {
|
|
|
|
|
if (!OsPreemptableInSched()) {//不能抢占时
|
|
|
|
|
/* Suspending the current core's running task */
|
|
|
|
|
*ret = LOS_ERRNO_TSK_SUSPEND_LOCKED;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OS_INT_ACTIVE) {
|
|
|
|
|
if (OS_INT_ACTIVE) {//正在硬抢断时
|
|
|
|
|
/* suspend running task in interrupt */
|
|
|
|
|
taskCB->signal = SIGNAL_SUSPEND;
|
|
|
|
|
return FALSE;
|
|
|
|
@ -773,7 +850,7 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//任务暂停,参数可以不是当前任务,也就是说A任务可以让B任务处于阻塞状态,挂起指定的任务,然后切换任务
|
|
|
|
|
LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
UINT32 errRet;
|
|
|
|
@ -786,14 +863,14 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB)
|
|
|
|
|
return LOS_ERRNO_TSK_ALREADY_SUSPENDED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((tempStatus & OS_TASK_STATUS_RUNNING) &&
|
|
|
|
|
!OsTaskSuspendCheckOnRun(taskCB, &errRet)) {
|
|
|
|
|
if ((tempStatus & OS_TASK_STATUS_RUNNING) &&//如果参数任务正在运行,注意多Cpu core情况,贴着正在运行标签的任务并不一定是当前CPU的执行任务,
|
|
|
|
|
!OsTaskSuspendCheckOnRun(taskCB, &errRet)) {//很有可能是别的CPU core在跑的任务
|
|
|
|
|
return errRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return taskCB->ops->suspend(taskCB);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//外部接口,对OsTaskSuspend的封装
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -813,7 +890,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
return errRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置任务为不使用状态
|
|
|
|
|
STATIC INLINE VOID OsTaskStatusUnusedSet(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
|
taskCB->taskStatus |= OS_TASK_STATUS_UNUSED;
|
|
|
|
@ -959,7 +1036,7 @@ LOS_ERREND:
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -989,7 +1066,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取任务的优先级
|
|
|
|
|
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -1010,7 +1087,7 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
return param.priority;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置指定任务的优先级
|
|
|
|
|
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -1048,12 +1125,12 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
|
|
|
|
|
}
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置当前任务的优先级
|
|
|
|
|
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
|
|
|
|
|
{
|
|
|
|
|
return LOS_TaskPriSet(OsCurrTaskGet()->taskID, taskPrio);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//当前任务释放CPU,并将其移到具有相同优先级的就绪任务队列的末尾。
|
|
|
|
|
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -1099,7 +1176,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
|
|
|
|
|
LOS_Schedule();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取任务信息,给shell使用的
|
|
|
|
|
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -1129,8 +1206,8 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf
|
|
|
|
|
taskCB->ops->schedParamGet(taskCB, ¶m);
|
|
|
|
|
taskInfo->usTaskStatus = taskCB->taskStatus;
|
|
|
|
|
taskInfo->usTaskPrio = param.priority;
|
|
|
|
|
taskInfo->uwStackSize = taskCB->stackSize;
|
|
|
|
|
taskInfo->uwTopOfStack = taskCB->topOfStack;
|
|
|
|
|
taskInfo->uwStackSize = taskCB->stackSize;//内核态栈大小
|
|
|
|
|
taskInfo->uwTopOfStack = taskCB->topOfStack;//内核态栈顶位置
|
|
|
|
|
taskInfo->uwEventMask = taskCB->eventMask;
|
|
|
|
|
taskInfo->taskEvent = taskCB->taskEvent;
|
|
|
|
|
taskInfo->pTaskMux = taskCB->taskMux;
|
|
|
|
@ -1141,16 +1218,16 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf
|
|
|
|
|
}
|
|
|
|
|
taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0';
|
|
|
|
|
|
|
|
|
|
taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize),
|
|
|
|
|
taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize),//这里可以看出栈顶地址是高于栈顶
|
|
|
|
|
OS_TASK_STACK_ADDR_ALIGN);
|
|
|
|
|
taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP);
|
|
|
|
|
taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP);//当前任务栈已使用了多少
|
|
|
|
|
|
|
|
|
|
taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack,
|
|
|
|
|
taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack,//获取栈的使用情况
|
|
|
|
|
(const UINTPTR *)taskInfo->uwTopOfStack, &taskInfo->uwPeakUsed);
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//CPU亲和性(affinity)将任务绑定在指定CPU上,用于多核CPU情况,(该函数仅在SMP模式下支持)
|
|
|
|
|
LITE_OS_SEC_TEXT BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
@ -1176,17 +1253,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa
|
|
|
|
|
UINT32 intSave;
|
|
|
|
|
UINT16 currCpuMask;
|
|
|
|
|
|
|
|
|
|
if (OS_TID_CHECK_INVALID(taskID)) {
|
|
|
|
|
if (OS_TID_CHECK_INVALID(taskID)) {//检测taskid是否有效,task由task池分配,鸿蒙默认128个任务 ID范围[0:127]
|
|
|
|
|
return LOS_ERRNO_TSK_ID_INVALID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) {
|
|
|
|
|
if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) {//检测cpu亲和力
|
|
|
|
|
return LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//贴有未使用标签的处理
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
return LOS_ERRNO_TSK_NOT_CREATED;
|
|
|
|
|
}
|
|
|
|
@ -1194,13 +1271,13 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa
|
|
|
|
|
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
if (needSched && OS_SCHEDULER_ACTIVE) {
|
|
|
|
|
LOS_MpSchedule(currCpuMask);
|
|
|
|
|
LOS_Schedule();
|
|
|
|
|
LOS_MpSchedule(currCpuMask);//发送信号调度信号给目标cpu
|
|
|
|
|
LOS_Schedule();//申请调度
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//查询任务被绑在哪个cpu上
|
|
|
|
|
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
@ -1214,18 +1291,18 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
|
|
|
|
|
|
|
|
|
|
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务必须在使用
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
return INVALID_CPU_AFFI_MASK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cpuAffiMask = taskCB->cpuAffiMask;
|
|
|
|
|
cpuAffiMask = taskCB->cpuAffiMask;//获取亲和力掩码
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
|
|
|
|
|
return cpuAffiMask;
|
|
|
|
|
#else
|
|
|
|
|
(VOID)taskID;
|
|
|
|
|
return 1;
|
|
|
|
|
return 1;//单核情况直接返回1,0号cpu对应0x01
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1235,14 +1312,14 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
|
|
|
|
|
LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
|
|
|
|
|
|
//私有且不可中断,无需保护。这个任务在其他cpu核看到它时总是在运行,所以它在执行代码的同时也可以继续接收信号
|
|
|
|
|
/*
|
|
|
|
|
* private and uninterruptable, no protection needed.
|
|
|
|
|
* while this task is always running when others cores see it,
|
|
|
|
|
* so it keeps receiving signals while follow code executing.
|
|
|
|
|
*/
|
|
|
|
|
LosTaskCB *runTask = OsCurrTaskGet();
|
|
|
|
|
if (runTask->signal == SIGNAL_NONE) {
|
|
|
|
|
if (runTask->signal == SIGNAL_NONE) {//意思是其他cpu发起了要干掉你的信号
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1250,23 +1327,23 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID)
|
|
|
|
|
/*
|
|
|
|
|
* clear the signal, and do the task deletion. if the signaled task has been
|
|
|
|
|
* scheduled out, then this deletion will wait until next run.
|
|
|
|
|
*/
|
|
|
|
|
runTask->signal = SIGNAL_NONE;
|
|
|
|
|
*///如果发出信号的任务以出调度就绪队列,则此删除将等待下次运行
|
|
|
|
|
runTask->signal = SIGNAL_NONE;//清除信号
|
|
|
|
|
ret = LOS_TaskDelete(runTask->taskID);
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
|
PRINT_ERR("Task proc signal delete task(%u) failed err:0x%x\n", runTask->taskID, ret);
|
|
|
|
|
}
|
|
|
|
|
} else if (runTask->signal & SIGNAL_SUSPEND) {
|
|
|
|
|
runTask->signal &= ~SIGNAL_SUSPEND;
|
|
|
|
|
} else if (runTask->signal & SIGNAL_SUSPEND) {//意思是其他cpu发起了要挂起你的信号
|
|
|
|
|
runTask->signal &= ~SIGNAL_SUSPEND;//任务贴在被其他cpu挂起的标签
|
|
|
|
|
|
|
|
|
|
/* suspend killed task may fail, ignore the result */
|
|
|
|
|
(VOID)LOS_TaskSuspend(runTask->taskID);
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
|
} else if (runTask->signal & SIGNAL_AFFI) {
|
|
|
|
|
runTask->signal &= ~SIGNAL_AFFI;
|
|
|
|
|
} else if (runTask->signal & SIGNAL_AFFI) {//意思是下次调度其他cpu要媾和你
|
|
|
|
|
runTask->signal &= ~SIGNAL_AFFI;//任务贴上被其他CPU媾和的标签
|
|
|
|
|
|
|
|
|
|
/* priority queue has updated, notify the target cpu */
|
|
|
|
|
LOS_MpSchedule((UINT32)runTask->cpuAffiMask);
|
|
|
|
|
LOS_MpSchedule((UINT32)runTask->cpuAffiMask);//发生调度,此任务将移交给媾和CPU运行.
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1339,7 +1416,7 @@ INT32 OsUserProcessOperatePermissionsCheck(const LosTaskCB *taskCB, UINTPTR proc
|
|
|
|
|
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//创建任务之前,检查用户态任务栈的参数,是否地址在用户空间
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, TSK_INIT_PARAM_S *param)
|
|
|
|
|
{
|
|
|
|
|
UserTaskParam *userParam = NULL;
|
|
|
|
@ -1349,25 +1426,25 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
userParam = ¶m->userParam;
|
|
|
|
|
if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) {
|
|
|
|
|
if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) {//堆地址必须在用户空间
|
|
|
|
|
return OS_INVALID_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) {
|
|
|
|
|
if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) {//入口函数必须在用户空间
|
|
|
|
|
return OS_INVALID_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//堆栈必须在用户空间
|
|
|
|
|
if (userParam->userMapBase && !LOS_IsUserAddressRange(userParam->userMapBase, userParam->userMapSize)) {
|
|
|
|
|
return OS_INVALID_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//检查堆,栈范围
|
|
|
|
|
if (!LOS_IsUserAddress(userParam->userSP)) {
|
|
|
|
|
return OS_INVALID_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//创建一个用户态任务
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_S *initParam)
|
|
|
|
|
{
|
|
|
|
|
UINT32 taskID;
|
|
|
|
@ -1376,18 +1453,18 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_
|
|
|
|
|
INT32 policy;
|
|
|
|
|
SchedParam param;
|
|
|
|
|
|
|
|
|
|
ret = OsCreateUserTaskParamCheck(processID, initParam);
|
|
|
|
|
ret = OsCreateUserTaskParamCheck(processID, initParam);//检查参数,堆栈,入口地址必须在用户空间
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//这里可看出一个任务有两个栈,内核态栈(内核指定栈大小)和用户态栈(用户指定栈大小)
|
|
|
|
|
initParam->uwStackSize = OS_USER_TASK_SYSCALL_STACK_SIZE;
|
|
|
|
|
initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;
|
|
|
|
|
if (processID == OS_INVALID_VALUE) {
|
|
|
|
|
initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;//设置最低优先级31级
|
|
|
|
|
if (processID == OS_INVALID_VALUE) {//外面没指定进程ID的处理
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
LosProcessCB *processCB = OsCurrProcessGet();
|
|
|
|
|
initParam->processID = (UINTPTR)processCB;
|
|
|
|
|
initParam->consoleID = processCB->consoleID;
|
|
|
|
|
initParam->consoleID = processCB->consoleID;//任务控制台ID归属
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
ret = LOS_GetProcessScheduler(processCB->processID, &policy, NULL);
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
@ -1400,20 +1477,20 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_
|
|
|
|
|
initParam->deadlineUs = param.deadlineUs;
|
|
|
|
|
initParam->periodUs = param.periodUs;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
initParam->policy = LOS_SCHED_RR;
|
|
|
|
|
initParam->processID = processID;
|
|
|
|
|
initParam->consoleID = 0;
|
|
|
|
|
} else {//进程已经创建
|
|
|
|
|
initParam->policy = LOS_SCHED_RR;//调度方式为抢占式,注意鸿蒙不仅仅只支持抢占式调度方式
|
|
|
|
|
initParam->processID = processID;//进程ID赋值
|
|
|
|
|
initParam->consoleID = 0;//默认0号控制台
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = LOS_TaskCreateOnly(&taskID, initParam);
|
|
|
|
|
ret = LOS_TaskCreateOnly(&taskID, initParam);//只创建task实体,不申请调度
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
|
return OS_INVALID_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return taskID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取任务的调度方式
|
|
|
|
|
LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -1426,7 +1503,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
|
|
|
|
|
|
|
|
|
|
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
|
|
|
|
|
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务不能是没有在使用
|
|
|
|
|
policy = -LOS_EINVAL;
|
|
|
|
|
OS_GOTO_ERREND();
|
|
|
|
|
}
|
|
|
|
@ -1438,7 +1515,7 @@ LOS_ERREND:
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
return policy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置任务的调度信息
|
|
|
|
|
LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority)
|
|
|
|
|
{
|
|
|
|
|
SchedParam param = { 0 };
|
|
|
|
@ -1582,12 +1659,12 @@ UINT32 LOS_TaskDetach(UINT32 taskID)
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
return errRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取最大任务数
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_GetSystemTaskMaximum(VOID)
|
|
|
|
|
{
|
|
|
|
|
return g_taskMaxNum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//任务池中最后一个
|
|
|
|
|
LosTaskCB *OsGetDefaultTaskCB(VOID)
|
|
|
|
|
{
|
|
|
|
|
return &g_taskCBArray[g_taskMaxNum];
|
|
|
|
@ -1602,44 +1679,44 @@ LITE_OS_SEC_TEXT VOID OsWriteResourceEventUnsafe(UINT32 events)
|
|
|
|
|
{
|
|
|
|
|
(VOID)OsEventWriteUnsafe(&g_resourceEvent, events, FALSE, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//资源回收任务
|
|
|
|
|
STATIC VOID OsResourceRecoveryTask(VOID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
while (1) {//死循环,回收资源不存在退出情况,只要系统在运行资源就需要回收
|
|
|
|
|
ret = LOS_EventRead(&g_resourceEvent, OS_RESOURCE_EVENT_MASK,
|
|
|
|
|
LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
|
|
|
|
|
if (ret & (OS_RESOURCE_EVENT_FREE | OS_RESOURCE_EVENT_OOM)) {
|
|
|
|
|
LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);//读取资源事件
|
|
|
|
|
if (ret & (OS_RESOURCE_EVENT_FREE | OS_RESOURCE_EVENT_OOM)) {//收到资源释放或内存异常情况
|
|
|
|
|
OsTaskCBRecycleToFree();
|
|
|
|
|
|
|
|
|
|
OsProcessCBRecycleToFree();
|
|
|
|
|
OsProcessCBRecycleToFree();//回收进程到空闲进程池
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK
|
|
|
|
|
if (ret & OS_RESOURCE_EVENT_OOM) {
|
|
|
|
|
(VOID)OomCheckProcess();
|
|
|
|
|
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK//内存溢出检测任务开关
|
|
|
|
|
if (ret & OS_RESOURCE_EVENT_OOM) {//触发了这个事件
|
|
|
|
|
(VOID)OomCheckProcess();//检查进程的内存溢出情况
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//创建一个回收资源的任务
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
|
UINT32 taskID;
|
|
|
|
|
TSK_INIT_PARAM_S taskInitParam;
|
|
|
|
|
|
|
|
|
|
ret = LOS_EventInit((PEVENT_CB_S)&g_resourceEvent);
|
|
|
|
|
ret = LOS_EventInit((PEVENT_CB_S)&g_resourceEvent);//初始化资源事件
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
|
return LOS_NOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
|
|
|
|
|
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsResourceRecoveryTask;
|
|
|
|
|
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsResourceRecoveryTask;//入口函数
|
|
|
|
|
taskInitParam.uwStackSize = OS_TASK_RESOURCE_STATIC_SIZE;
|
|
|
|
|
taskInitParam.pcName = "ResourcesTask";
|
|
|
|
|
taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY;
|
|
|
|
|
taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY;//5,优先级很高
|
|
|
|
|
ret = LOS_TaskCreate(&taskID, &taskInitParam);
|
|
|
|
|
if (ret == LOS_OK) {
|
|
|
|
|
OS_TCB_FROM_TID(taskID)->taskStatus |= OS_TASK_FLAG_NO_DELETE;
|
|
|
|
@ -1647,5 +1724,5 @@ LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK);
|
|
|
|
|
LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK);//资源回收任务初始化
|
|
|
|
|
|
|
|
|
|