diff --git a/arch/arm/arm/src/los_exc.c b/arch/arm/arm/src/los_exc.c index 4aad1496..672e9396 100644 --- a/arch/arm/arm/src/los_exc.c +++ b/arch/arm/arm/src/los_exc.c @@ -589,7 +589,7 @@ STATIC VOID OsUserExcHandle(ExcContext *excBufAddr) SCHEDULER_UNLOCK(intSave); /* Exception handling All operations should be kept prior to that operation */ OsExcRestore(); - OsTaskToExit(runTask, OS_PRO_EXIT_OK); + OsRunningTaskToExit(runTask, OS_PRO_EXIT_OK); } else { SCHEDULER_UNLOCK(intSave); diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 60757ff7..ddfd9fe4 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -50,6 +50,9 @@ #ifdef LOSCFG_SECURITY_CAPABILITY #include "capability_api.h" #endif +#ifdef LOSCFG_KERNEL_DYNLOAD +#include "los_load_elf.h" +#endif #include "los_swtmr_pri.h" #include "los_vm_map.h" #include "los_vm_phys.h" @@ -75,6 +78,50 @@ STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB) LOS_ListTailInsert(&g_freeProcess, &processCB->pendList); } +VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB) +{ + LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); + + LOS_ListDelete(&taskCB->threadList); + processCB->threadNumber--; + OsTaskInsertToRecycleList(taskCB); +} + +UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB) +{ + UINT32 intSave; + UINT16 numCount; + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + + SCHEDULER_LOCK(intSave); + taskCB->processID = pid; + LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList)); + + if (OsProcessIsUserMode(processCB)) { + taskCB->taskStatus |= OS_TASK_FLAG_USER_MODE; + if (processCB->threadNumber > 0) { + taskCB->basePrio = OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio; + } else { + taskCB->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST; + } + } else { + taskCB->basePrio = OsCurrTaskGet()->basePrio; + } + +#ifdef LOSCFG_KERNEL_VM + taskCB->archMmu = (UINTPTR)&processCB->vmSpace->archMmu; +#endif + if (!processCB->threadNumber) { + processCB->threadGroupID = taskCB->taskID; + } + processCB->threadNumber++; + + numCount = processCB->threadCount; + processCB->threadCount++; + SCHEDULER_UNLOCK(intSave); + return numCount; +} + STATIC ProcessGroup *OsCreateProcessGroup(UINT32 pid) { LosProcessCB *processCB = NULL; @@ -337,11 +384,6 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) { - if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) { - PRINT_ERR("The process(%d) has no permission to release process(%d) resources!\n", - OsCurrProcessGet()->processID, processCB->processID); - } - #ifdef LOSCFG_KERNEL_VM if (OsProcessIsUserMode(processCB)) { (VOID)OsVmSpaceRegionFree(processCB->vmSpace); @@ -396,6 +438,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, Proc OsExitProcessGroup(childCB, group); LOS_ListDelete(&childCB->siblingList); if (childCB->processStatus & OS_PROCESS_STATUS_ZOMBIES) { + OsDeleteTaskFromProcess(OS_TCB_FROM_TID(childCB->threadGroupID)); childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES; childCB->processStatus |= OS_PROCESS_FLAG_UNUSED; } @@ -455,13 +498,10 @@ STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB) } } -STATIC VOID OsProcessNaturalExit(LosTaskCB *runTask, UINT32 status) +VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status) { - LosProcessCB *processCB = OS_PCB_FROM_PID(runTask->processID); LosProcessCB *parentCB = NULL; - LOS_ASSERT(processCB->processStatus & OS_PROCESS_STATUS_RUNNING); - OsChildProcessResourcesFree(processCB); /* is a child process */ @@ -485,7 +525,6 @@ STATIC VOID OsProcessNaturalExit(LosTaskCB *runTask, UINT32 status) (VOID)OsKill(processCB->parentProcessID, SIGCHLD, OS_KERNEL_KILL_PERMISSION); #endif LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList); - OsRunTaskToDelete(runTask); return; } @@ -636,13 +675,12 @@ UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name) return LOS_OK; } -STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, const CHAR *name) +STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name) { processCB->processMode = mode; processCB->processStatus = OS_PROCESS_STATUS_INIT; processCB->parentProcessID = OS_INVALID_VALUE; processCB->threadGroupID = OS_INVALID_VALUE; - processCB->priority = priority; processCB->umask = OS_PROCESS_DEFAULT_UMASK; processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; @@ -757,10 +795,10 @@ LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID) #endif } -STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name, UINT16 priority) +STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name) { ProcessGroup *group = NULL; - UINT32 ret = OsInitPCB(processCB, flags, priority, name); + UINT32 ret = OsInitPCB(processCB, flags, name); if (ret != LOS_OK) { goto EXIT; } @@ -802,7 +840,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) } LosProcessCB *kerInitProcess = OS_PCB_FROM_PID(g_kernelInitProcess); - ret = OsProcessCreateInit(kerInitProcess, OS_KERNEL_MODE, "KProcess", 0); + ret = OsProcessCreateInit(kerInitProcess, OS_KERNEL_MODE, "KProcess"); if (ret != LOS_OK) { return ret; } @@ -812,7 +850,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) LOS_ListInit(&g_processGroup->groupList); LosProcessCB *idleProcess = OS_PCB_FROM_PID(g_kernelIdleProcess); - ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, OS_TASK_PRIORITY_LOWEST, "KIdle"); + ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle"); if (ret != LOS_OK) { return ret; } @@ -826,6 +864,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) #ifdef LOSCFG_FS_VFS idleProcess->files = kerInitProcess->files; #endif + idleProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; ret = OsIdleTaskCreate(); if (ret != LOS_OK) { @@ -868,7 +907,7 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, UINT16 prio) } /* user mode process can reduce the priority of itself */ - if ((runProcess->processID == processCB->processID) && (prio > processCB->priority)) { + if ((runProcess->processID == processCB->processID) && (prio > OsCurrTaskGet()->basePrio)) { return TRUE; } @@ -952,7 +991,6 @@ LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio) LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) { - LosProcessCB *processCB = NULL; INT32 prio; UINT32 intSave; (VOID)which; @@ -965,14 +1003,14 @@ LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) return -LOS_EINVAL; } + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); SCHEDULER_LOCK(intSave); - processCB = OS_PCB_FROM_PID(pid); if (OsProcessIsUnused(processCB)) { prio = -LOS_ESRCH; goto OUT; } - prio = (INT32)processCB->priority; + prio = (INT32)OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio; OUT: SCHEDULER_UNLOCK(intSave); @@ -1424,6 +1462,36 @@ STATIC VOID *OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size) return (VOID *)(UINTPTR)region->range.base; } +#ifdef LOSCFG_KERNEL_DYNLOAD +LITE_OS_SEC_TEXT VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace) +{ + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *runTask = OsCurrTaskGet(); + + processCB->vmSpace = oldSpace; + runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu; + LOS_ArchMmuContextSwitch((LosArchMmu *)runTask->archMmu); +} + +LITE_OS_SEC_TEXT LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD) +{ + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *runTask = OsCurrTaskGet(); + + OsProcessThreadGroupDestroy(); + OsTaskCBRecycleToFree(); + + LosVmSpace *oldSpace = processCB->vmSpace; + processCB->vmSpace = newSpace; + processCB->vmSpace->heapBase += OsGetRndOffset(randomDevFD); + processCB->vmSpace->heapNow = processCB->vmSpace->heapBase; + processCB->vmSpace->mapBase += OsGetRndOffset(randomDevFD); + processCB->vmSpace->mapSize = stackBase - processCB->vmSpace->mapBase; + runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu; + LOS_ArchMmuContextSwitch((LosArchMmu *)runTask->archMmu); + return oldSpace; +} + LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldSpace, UINTPTR oldFiles) { @@ -1501,27 +1569,39 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT SCHEDULER_UNLOCK(intSave); return LOS_OK; } +#endif -STATIC UINT32 OsUserInitProcessStart(UINT32 processID, TSK_INIT_PARAM_S *param) +STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param) { UINT32 intSave; - UINT32 taskID; INT32 ret; - taskID = OsCreateUserTask(processID, param); + UINT32 taskID = OsCreateUserTask(processCB->processID, param); if (taskID == OS_INVALID_VALUE) { return LOS_NOK; } + ret = LOS_SetProcessPriority(processCB->processID, OS_PROCESS_USERINIT_PRIORITY); + if (ret != LOS_OK) { + PRINT_ERR("User init process set priority failed! ERROR:%d \n", ret); + goto EXIT; + } + + SCHEDULER_LOCK(intSave); + processCB->processStatus &= ~OS_PROCESS_STATUS_INIT; + SCHEDULER_UNLOCK(intSave); + ret = LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST); if (ret != LOS_OK) { PRINT_ERR("User init process set scheduler failed! ERROR:%d \n", ret); - SCHEDULER_LOCK(intSave); - (VOID)OsTaskDeleteUnsafe(OS_TCB_FROM_TID(taskID), OS_PRO_EXIT_OK, intSave); - return LOS_NOK; + goto EXIT; } return LOS_OK; + +EXIT: + (VOID)LOS_TaskDelete(taskID); + return ret; } STATIC UINT32 OsLoadUserInit(LosProcessCB *processCB) @@ -1597,7 +1677,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) VOID *stack = NULL; LosProcessCB *processCB = OS_PCB_FROM_PID(g_userInitProcess); - ret = OsProcessCreateInit(processCB, OS_USER_MODE, "Init", OS_PROCESS_USERINIT_PRIORITY); + ret = OsProcessCreateInit(processCB, OS_USER_MODE, "Init"); if (ret != LOS_OK) { return ret; } @@ -1618,7 +1698,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) param.userParam.userMapBase = (UINTPTR)stack; param.userParam.userMapSize = size; param.uwResved = OS_TASK_FLAG_PTHREAD_JOIN; - ret = OsUserInitProcessStart(g_userInitProcess, ¶m); + ret = OsUserInitProcessStart(processCB, ¶m); if (ret != LOS_OK) { (VOID)OsUnMMap(processCB->vmSpace, param.userParam.userMapBase, param.userParam.userMapSize); goto ERROR; @@ -1695,6 +1775,7 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR LosTaskCB *childTaskCB = OS_TCB_FROM_TID(taskID); childTaskCB->taskStatus = runTask->taskStatus; + childTaskCB->basePrio = runTask->basePrio; if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) { childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING; } else { @@ -1702,7 +1783,6 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus); } childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED; - childProcessCB->priority = OS_PROCESS_PRIORITY_LOWEST; } if (OsProcessIsUserMode(childProcessCB)) { @@ -1720,7 +1800,6 @@ STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProces LosProcessCB *parentProcessCB = NULL; SCHEDULER_LOCK(intSave); - childProcessCB->priority = runProcessCB->priority; if (flags & CLONE_PARENT) { parentProcessCB = OS_PCB_FROM_PID(runProcessCB->parentProcessID); @@ -1784,7 +1863,7 @@ STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINT32 ret; LosProcessCB *run = OsCurrProcessGet(); - ret = OsInitPCB(child, run->processMode, OS_PROCESS_PRIORITY_LOWEST, name); + ret = OsInitPCB(child, run->processMode, name); if (ret != LOS_OK) { return ret; } @@ -1812,6 +1891,7 @@ STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB * } } + child->processStatus &= ~OS_PROCESS_STATUS_INIT; OsSchedTaskEnQueue(OS_TCB_FROM_TID(child->threadGroupID)); SCHEDULER_UNLOCK(intSave); @@ -1851,7 +1931,7 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size) { - UINT32 intSave, ret, processID; + UINT32 ret, processID; LosProcessCB *run = OsCurrProcessGet(); LosProcessCB *child = OsGetFreePCB(); @@ -1883,8 +1963,7 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si return processID; ERROR_TASK: - SCHEDULER_LOCK(intSave); - (VOID)OsTaskDeleteUnsafe(OS_TCB_FROM_TID(child->threadGroupID), OS_PRO_EXIT_OK, intSave); + (VOID)LOS_TaskDelete(child->threadGroupID); ERROR_INIT: OsDeInitPCB(child); return -ret; @@ -1933,8 +2012,8 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) } SCHEDULER_UNLOCK(intSave); - OsTaskExitGroup((UINT32)status); - OsProcessExit(OsCurrTaskGet(), (UINT32)status); + OsProcessThreadGroupDestroy(); + OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK); } LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum) @@ -1988,17 +2067,77 @@ LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID) return OsCurrProcessGet()->processID; } -LITE_OS_SEC_TEXT VOID OsProcessExit(LosTaskCB *runTask, INT32 status) +#ifdef LOSCFG_KERNEL_VM +STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB) { + INT32 ret; + + taskCB->taskStatus |= OS_TASK_FLAG_EXIT_KILL; +#ifdef LOSCFG_KERNEL_SMP + /** The other core that the thread is running on and is currently running in a non-system call */ + if (!taskCB->sig.sigIntLock && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + taskCB->signal = SIGNAL_KILL; + LOS_MpSchedule(taskCB->currCpu); + } else +#endif + { + ret = OsTaskKillUnsafe(taskCB->taskID, SIGKILL); + if (ret != LOS_OK) { + PRINT_ERR("pid %u exit, Exit task group %u kill %u failed! ERROR: %d\n", + taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, ret); + } + } + + if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { + taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; + LOS_ListInit(&taskCB->joinList); + } + + ret = OsTaskJoinPendUnsafe(taskCB); + if (ret != LOS_OK) { + PRINT_ERR("pid %u exit, Exit task group %u to wait others task %u(0x%x) exit failed! ERROR: %d\n", + taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, taskCB->taskStatus, ret); + } +} +#endif + +LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID) +{ +#ifdef LOSCFG_KERNEL_VM UINT32 intSave; - LOS_ASSERT(runTask == OsCurrTaskGet()); - - OsTaskResourcesToFree(runTask); - OsProcessResourcesToFree(OsCurrProcessGet()); + LosProcessCB *processCB = OsCurrProcessGet(); + LosTaskCB *currTask = OsCurrTaskGet(); SCHEDULER_LOCK(intSave); - OsProcessNaturalExit(runTask, status); + if ((processCB->processStatus & OS_PROCESS_FLAG_EXIT) || !OsProcessIsUserMode(processCB)) { + SCHEDULER_UNLOCK(intSave); + return; + } + + processCB->processStatus |= OS_PROCESS_FLAG_EXIT; + processCB->threadGroupID = currTask->taskID; + + LOS_DL_LIST *list = &processCB->threadSiblingList; + LOS_DL_LIST *head = list; + do { + LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList); + if ((OsTaskIsInactive(taskCB) || + ((taskCB->taskStatus & OS_TASK_STATUS_READY) && !taskCB->sig.sigIntLock)) && + !(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { + OsInactiveTaskDelete(taskCB); + } else if (taskCB != currTask) { + ThreadGroupActiveTaskKilled(taskCB); + } else { + /* Skip the current task */ + list = list->pstNext; + } + } while (head != list->pstNext); + SCHEDULER_UNLOCK(intSave); + + LOS_ASSERT(processCB->threadNumber == 1); +#endif + return; } LITE_OS_SEC_TEXT UINT32 LOS_GetSystemProcessMaximum(VOID) diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index 9b1161ec..af6d7fa1 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -269,7 +269,11 @@ BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) { UINT64 currTime = OsGetCurrSchedTimeCycle(); - return (OsSortLinkGetNextExpireTime(currTime, &OsSchedRunQue()->swtmrSortLink) / OS_CYCLE_PER_TICK); + UINT64 time = (OsSortLinkGetNextExpireTime(currTime, &OsSchedRunQue()->swtmrSortLink) / OS_CYCLE_PER_TICK); + if (time > OS_INVALID_VALUE) { + time = OS_INVALID_VALUE; + } + return (UINT32)time; } /* @@ -293,7 +297,11 @@ LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr) { UINT64 currTime = OsGetCurrSchedTimeCycle(); - return (OsSortLinkGetTargetExpireTime(currTime, &swtmr->stSortList) / OS_CYCLE_PER_TICK); + UINT64 time = (OsSortLinkGetTargetExpireTime(currTime, &swtmr->stSortList) / OS_CYCLE_PER_TICK); + if (time > OS_INVALID_VALUE) { + time = OS_INVALID_VALUE; + } + return (UINT32)time; } LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index 37f40492..28ddc36f 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -95,6 +95,7 @@ VOID OsSetMainTask() g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED; g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT; g_mainTask[i].processID = OS_KERNEL_PROCESS_GROUP; + g_mainTask[i].basePrio = OS_TASK_PRIORITY_HIGHEST; g_mainTask[i].priority = OS_TASK_PRIORITY_LOWEST; #ifdef LOSCFG_KERNEL_SMP_LOCKDEP g_mainTask[i].lockDep.lockDepth = 0; @@ -112,14 +113,9 @@ LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID) } } -STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB) +VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB) { - UINT32 taskID = taskCB->taskID; - (VOID)memset_s(taskCB, sizeof(LosTaskCB), 0, sizeof(LosTaskCB)); - taskCB->taskID = taskID; - taskCB->taskStatus = OS_TASK_STATUS_UNUSED; - taskCB->processID = OS_INVALID_VALUE; - LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); + LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList); } LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB) @@ -138,11 +134,6 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB) LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - if (!(processCB->processStatus & OS_PROCESS_STATUS_RUNNING)) { - return LOS_EPERM; - } - if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { return LOS_EINVAL; } @@ -161,11 +152,6 @@ LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB) LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - if (!(processCB->processStatus & OS_PROCESS_STATUS_RUNNING)) { - return LOS_EPERM; - } - if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { if (LOS_ListEmpty(&(taskCB->joinList))) { LOS_ListDelete(&(taskCB->joinList)); @@ -316,60 +302,87 @@ STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB) #endif } -STATIC VOID OsTaskReleaseHoldLock(LosProcessCB *processCB, LosTaskCB *taskCB) +STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB) { - LosMux *mux = NULL; - UINT32 ret; + UINT32 taskID = taskCB->taskID; + (VOID)memset_s(taskCB, sizeof(LosTaskCB), 0, sizeof(LosTaskCB)); + taskCB->taskID = taskID; + taskCB->taskStatus = OS_TASK_STATUS_UNUSED; + taskCB->processID = OS_INVALID_VALUE; + LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); +} - while (!LOS_ListEmpty(&taskCB->lockList)) { - mux = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&taskCB->lockList), LosMux, holdList); - ret = OsMuxUnlockUnsafe(taskCB, mux, NULL); - if (ret != LOS_OK) { - LOS_ListDelete(&mux->holdList); - PRINT_ERR("mux ulock failed! : %u\n", ret); - } - } +STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack) +{ + OsTaskSyncDestroy(syncSignal); + + (VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack); +} + +STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB) +{ + UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; + UINT32 intSave; + UINTPTR topOfStack; #ifdef LOSCFG_KERNEL_VM - if (processCB->processMode == OS_USER_MODE) { - OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); + if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) { + SCHEDULER_LOCK(intSave); + UINT32 mapBase = (UINTPTR)taskCB->userMapBase; + UINT32 mapSize = taskCB->userMapSize; + taskCB->userMapBase = 0; + taskCB->userArea = 0; + SCHEDULER_UNLOCK(intSave); + + LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); + LOS_ASSERT(!(OsProcessVmSpaceGet(processCB) == NULL)); + 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", + taskCB->processID, taskCB->taskID, mapBase, mapSize, ret); + } + +#ifdef LOSCFG_KERNEL_LITEIPC + LiteIpcRemoveServiceHandle(taskCB->taskID); +#endif } #endif - OsTaskJoinPostUnsafe(taskCB); + 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); - OsTaskSyncWake(taskCB); + SCHEDULER_LOCK(intSave); +#ifdef LOSCFG_KERNEL_VM + OsClearSigInfoTmpList(&(taskCB->sig)); +#endif + OsInsertTCBToFreeList(taskCB); + SCHEDULER_UNLOCK(intSave); + } + return; } -LITE_OS_SEC_TEXT VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status) +LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree() { + LosTaskCB *taskCB = NULL; UINT32 intSave; - LosProcessCB *runProcess = OS_PCB_FROM_PID(taskCB->processID); - LosTaskCB *mainTask = OS_TCB_FROM_TID(runProcess->threadGroupID); - if (mainTask == taskCB) { - OsTaskExitGroup(status); - } - SCHEDULER_LOCK(intSave); - - if (runProcess->threadNumber == 1) { /* 1: The last task of the process exits */ + while (!LOS_ListEmpty(&g_taskRecycleList)) { + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList)); + LOS_ListDelete(&taskCB->pendList); SCHEDULER_UNLOCK(intSave); - (VOID)OsProcessExit(taskCB, status); - return; + + OsTaskResourcesToFree(taskCB); + + SCHEDULER_LOCK(intSave); } - - if ((taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) || !(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { - UINT32 ret = OsTaskDeleteUnsafe(taskCB, status, intSave); - LOS_Panic("Task delete failed! ERROR : 0x%x\n", ret); - return; - } - - OsTaskReleaseHoldLock(runProcess, taskCB); - - OsSchedResched(); SCHEDULER_UNLOCK(intSave); - return; } /* @@ -397,13 +410,12 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID) taskCB->joinRetval = 0; } - OsTaskToExit(taskCB, 0); + OsRunningTaskToExit(taskCB, 0); } LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initParam, VOID **pool) { - LosProcessCB *process = NULL; UINT32 poolSize = OS_SYS_MEM_SIZE; *pool = (VOID *)m_aucSysMem1; @@ -415,11 +427,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskID, return LOS_ERRNO_TSK_PTR_NULL; } - process = OS_PCB_FROM_PID(initParam->processID); - if (process->processMode > OS_USER_MODE) { - return LOS_ERRNO_TSK_ID_INVALID; - } - + LosProcessCB *process = OS_PCB_FROM_PID(initParam->processID); if (!OsProcessIsUserMode(process)) { if (initParam->pcName == NULL) { return LOS_ERRNO_TSK_NAME_EMPTY; @@ -455,81 +463,6 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskStackAlloc(VOID **topStack, UINT32 stack *topStack = (VOID *)LOS_MemAllocAlign(pool, stackSize, LOSCFG_STACK_POINT_ALIGN_SIZE); } -STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack) -{ - VOID *poolTmp = (VOID *)m_aucSysMem1; - - OsTaskSyncDestroy(syncSignal); - - (VOID)LOS_MemFree(poolTmp, (VOID *)topOfStack); -} - -LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree() -{ - LosTaskCB *taskCB = NULL; - UINT32 intSave; - - SCHEDULER_LOCK(intSave); - while (!LOS_ListEmpty(&g_taskRecycleList)) { - taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList)); - LOS_ListDelete(&taskCB->pendList); - SCHEDULER_UNLOCK(intSave); - - OsTaskResourcesToFree(taskCB); - - SCHEDULER_LOCK(intSave); - } - SCHEDULER_UNLOCK(intSave); -} - -LITE_OS_SEC_TEXT VOID OsTaskResourcesToFree(LosTaskCB *taskCB) -{ - UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT; - UINT32 intSave; - UINTPTR topOfStack; - -#ifdef LOSCFG_KERNEL_VM - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - if (OsProcessIsUserMode(processCB) && (taskCB->userMapBase != 0)) { - SCHEDULER_LOCK(intSave); - UINT32 mapBase = (UINTPTR)taskCB->userMapBase; - UINT32 mapSize = taskCB->userMapSize; - taskCB->userMapBase = 0; - taskCB->userArea = 0; - SCHEDULER_UNLOCK(intSave); - - LOS_ASSERT(!(processCB->vmSpace == NULL)); - UINT32 ret = OsUnMMap(processCB->vmSpace, (UINTPTR)mapBase, mapSize); - if ((ret != LOS_OK) && (mapBase != 0) && !(processCB->processStatus & OS_PROCESS_STATUS_INIT)) { - 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); - } - -#ifdef LOSCFG_KERNEL_LITEIPC - LiteIpcRemoveServiceHandle(taskCB->taskID); -#endif - } -#endif - - 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); - - SCHEDULER_LOCK(intSave); -#ifdef LOSCFG_KERNEL_VM - OsClearSigInfoTmpList(&(taskCB->sig)); -#endif - OsInsertTCBToFreeList(taskCB); - SCHEDULER_UNLOCK(intSave); - } - return; -} - LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, const VOID *stackPtr, const VOID *topStack, @@ -558,7 +491,6 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, LOS_ListInit(&taskCB->joinList); } - taskCB->futex.index = OS_INVALID_VALUE; LOS_ListInit(&taskCB->lockList); SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); } @@ -566,34 +498,21 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam, const VOID *stackPtr, const VOID *topStack) { - UINT32 intSave; UINT32 ret; UINT32 numCount; - UINT16 mode; - LosProcessCB *processCB = NULL; OsTaskCBInitBase(taskCB, stackPtr, topStack, initParam); - SCHEDULER_LOCK(intSave); - processCB = OS_PCB_FROM_PID(initParam->processID); - taskCB->processID = processCB->processID; - mode = processCB->processMode; - LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList)); - if (mode == OS_USER_MODE) { + numCount = OsProcessAddNewTask(initParam->processID, taskCB); +#ifdef LOSCFG_KERNEL_VM + taskCB->futex.index = OS_INVALID_VALUE; + if (taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) { taskCB->userArea = initParam->userParam.userArea; taskCB->userMapBase = initParam->userParam.userMapBase; taskCB->userMapSize = initParam->userParam.userMapSize; OsUserTaskStackInit(taskCB->stackPointer, (UINTPTR)taskCB->taskEntry, initParam->userParam.userSP); } - - if (!processCB->threadNumber) { - processCB->threadGroupID = taskCB->taskID; - } - processCB->threadNumber++; - - numCount = processCB->threadCount; - processCB->threadCount++; - SCHEDULER_UNLOCK(intSave); +#endif if (initParam->pcName != NULL) { ret = (UINT32)OsSetTaskName(taskCB, initParam->pcName, FALSE); @@ -688,7 +607,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in { UINT32 ret; UINT32 intSave; - LosTaskCB *taskCB = NULL; if (initParam == NULL) { return LOS_ERRNO_TSK_PTR_NULL; @@ -708,7 +626,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in if (ret != LOS_OK) { return ret; } - taskCB = OS_TCB_FROM_TID(*taskID); + + LosTaskCB *taskCB = OS_TCB_FROM_TID(*taskID); SCHEDULER_LOCK(intSave); OsSchedTaskEnQueue(taskCB); @@ -853,80 +772,79 @@ STATIC INLINE VOID OsTaskStatusUnusedSet(LosTaskCB *taskCB) OS_MEM_CLEAR(taskCB->taskID); } -LITE_OS_SEC_TEXT VOID OsRunTaskToDelete(LosTaskCB *runTask) +STATIC VOID OsTaskReleaseHoldLock(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(runTask->processID); + LosMux *mux = NULL; + UINT32 ret; - OsTaskReleaseHoldLock(processCB, runTask); - OsTaskStatusUnusedSet(runTask); + while (!LOS_ListEmpty(&taskCB->lockList)) { + mux = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&taskCB->lockList), LosMux, holdList); + ret = OsMuxUnlockUnsafe(taskCB, mux, NULL); + if (ret != LOS_OK) { + LOS_ListDelete(&mux->holdList); + PRINT_ERR("mux ulock failed! : %u\n", ret); + } + } - LOS_ListDelete(&runTask->threadList); - processCB->threadNumber--; - LOS_ListTailInsert(&g_taskRecycleList, &runTask->pendList); - OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL); - - OsSchedResched(); - return; -} - -/* - * Check if needs to do the delete operation on the running task. - * Return TRUE, if needs to do the deletion. - * Return FALSE, if meets following circumstances: - * 1. Do the deletion across cores, if SMP is enabled - * 2. Do the deletion when preemption is disabled - * 3. Do the deletion in hard-irq - * then LOS_TaskDelete will directly return with 'ret' value. - */ -STATIC BOOL OsRunTaskToDeleteCheckOnRun(LosTaskCB *taskCB, UINT32 *ret) -{ - /* init default out return value */ - *ret = LOS_OK; - -#ifdef LOSCFG_KERNEL_SMP - /* ASYNCHRONIZED. No need to do task lock checking */ - if (taskCB->currCpu != ArchCurrCpuid()) { - /* - * the task is running on another cpu. - * mask the target task with "kill" signal, and trigger mp schedule - * which might not be essential but the deletion could more in time. - */ - taskCB->signal = SIGNAL_KILL; - LOS_MpSchedule(taskCB->currCpu); - *ret = OsTaskSyncWait(taskCB); - return FALSE; +#ifdef LOSCFG_KERNEL_VM + if (taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) { + OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL); } #endif - if (!OsPreemptableInSched()) { - /* If the task is running and scheduler is locked then you can not delete it */ - *ret = LOS_ERRNO_TSK_DELETE_LOCKED; - return FALSE; - } + OsTaskJoinPostUnsafe(taskCB); - if (OS_INT_ACTIVE) { - /* - * delete running task in interrupt. - * mask "kill" signal and later deletion will be handled. - */ - taskCB->signal = SIGNAL_KILL; - return FALSE; - } - - return TRUE; + OsTaskSyncWake(taskCB); } -STATIC VOID OsTaskDeleteInactive(LosProcessCB *processCB, LosTaskCB *taskCB) +LITE_OS_SEC_TEXT VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status) +{ + UINT32 intSave; + + if (OsProcessThreadGroupIDGet(runTask) == runTask->taskID) { + OsProcessThreadGroupDestroy(); + } + + OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, runTask); + + SCHEDULER_LOCK(intSave); + if (OsProcessThreadNumberGet(runTask) == 1) { /* 1: The last task of the process exits */ + SCHEDULER_UNLOCK(intSave); + + OsTaskResourcesToFree(runTask); + OsProcessResourcesToFree(OS_PCB_FROM_PID(runTask->processID)); + + SCHEDULER_LOCK(intSave); + + OsProcessNaturalExit(OS_PCB_FROM_PID(runTask->processID), status); + OsTaskReleaseHoldLock(runTask); + OsTaskStatusUnusedSet(runTask); + } else if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { + OsTaskReleaseHoldLock(runTask); + } else { + SCHEDULER_UNLOCK(intSave); + + OsTaskResourcesToFree(runTask); + + SCHEDULER_LOCK(intSave); + OsInactiveTaskDelete(runTask); + OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL); + } + + OsSchedResched(); + SCHEDULER_UNLOCK(intSave); + return; +} + +LITE_OS_SEC_TEXT VOID OsInactiveTaskDelete(LosTaskCB *taskCB) { - LosMux *mux = (LosMux *)taskCB->taskMux; UINT16 taskStatus = taskCB->taskStatus; - LOS_ASSERT(!(taskStatus & OS_TASK_STATUS_RUNNING)); - - OsTaskReleaseHoldLock(processCB, taskCB); + OsTaskReleaseHoldLock(taskCB); OsSchedTaskExit(taskCB); if (taskStatus & OS_TASK_STATUS_PENDING) { + LosMux *mux = (LosMux *)taskCB->taskMux; if (LOS_MuxIsValid(mux) == TRUE) { OsMuxBitmapRestore(mux, taskCB, (LosTaskCB *)mux->owner); } @@ -934,53 +852,15 @@ STATIC VOID OsTaskDeleteInactive(LosProcessCB *processCB, LosTaskCB *taskCB) OsTaskStatusUnusedSet(taskCB); - LOS_ListDelete(&taskCB->threadList); - processCB->threadNumber--; - LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList); - return; -} + OsDeleteTaskFromProcess(taskCB); -LITE_OS_SEC_TEXT UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UINT32 intSave) -{ - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - UINT32 mode = processCB->processMode; - UINT32 errRet = LOS_OK; - - if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { - errRet = LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; - goto EXIT; - } - - if ((taskCB->taskStatus & OS_TASK_STATUS_RUNNING) && !OsRunTaskToDeleteCheckOnRun(taskCB, &errRet)) { - goto EXIT; - } - - if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { - OsTaskDeleteInactive(processCB, taskCB); - SCHEDULER_UNLOCK(intSave); - OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE); - return errRet; - } OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, taskCB); - if (mode == OS_USER_MODE) { - SCHEDULER_UNLOCK(intSave); - OsTaskResourcesToFree(taskCB); - SCHEDULER_LOCK(intSave); - } - - OsRunTaskToDelete(taskCB); - -EXIT: - SCHEDULER_UNLOCK(intSave); - return errRet; } LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) { UINT32 intSave; - UINT32 ret; - LosTaskCB *taskCB = NULL; - LosProcessCB *processCB = NULL; + UINT32 ret = LOS_OK; if (OS_TID_CHECK_INVALID(taskID)) { return LOS_ERRNO_TSK_ID_INVALID; @@ -990,32 +870,33 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) return LOS_ERRNO_TSK_YIELD_IN_INT; } - taskCB = OS_TCB_FROM_TID(taskID); + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB == OsCurrTaskGet()) { + OsRunningTaskToExit(taskCB, OS_PRO_EXIT_OK); + return LOS_NOK; + } + SCHEDULER_LOCK(intSave); - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { - ret = LOS_ERRNO_TSK_NOT_CREATED; - OS_GOTO_ERREND(); - } - - if (taskCB->taskStatus & (OS_TASK_FLAG_SYSTEM_TASK | OS_TASK_FLAG_NO_DELETE)) { - SCHEDULER_UNLOCK(intSave); - OsBackTrace(); - return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; - } - - processCB = OS_PCB_FROM_PID(taskCB->processID); - if (processCB->threadNumber == 1) { /* 1: The last task of the process exits */ - if (processCB == OsCurrProcessGet()) { - SCHEDULER_UNLOCK(intSave); - OsProcessExit(taskCB, OS_PRO_EXIT_OK); - return LOS_OK; + if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_FLAG_SYSTEM_TASK | OS_TASK_FLAG_NO_DELETE)) { + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + ret = LOS_ERRNO_TSK_NOT_CREATED; + } else { + ret = LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; } - - ret = LOS_ERRNO_TSK_ID_INVALID; OS_GOTO_ERREND(); } - return OsTaskDeleteUnsafe(taskCB, OS_PRO_EXIT_OK, intSave); +#ifdef LOSCFG_KERNEL_SMP + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + taskCB->signal = SIGNAL_KILL; + LOS_MpSchedule(taskCB->currCpu); + ret = OsTaskSyncWait(taskCB); + OS_GOTO_ERREND(); + } +#endif + + OsInactiveTaskDelete(taskCB); + OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL); LOS_ERREND: SCHEDULER_UNLOCK(intSave); @@ -1296,7 +1177,7 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) */ LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID) { - UINT32 intSave, ret; + UINT32 ret; /* * private and uninterruptable, no protection needed. @@ -1313,10 +1194,9 @@ 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. */ - SCHEDULER_LOCK(intSave); runTask->signal = SIGNAL_NONE; - ret = OsTaskDeleteUnsafe(runTask, OS_PRO_EXIT_OK, intSave); - if (ret) { + 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) { @@ -1338,7 +1218,6 @@ LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL s { UINT32 intSave; errno_t err; - LosProcessCB *processCB = NULL; const CHAR *namePtr = NULL; CHAR nameBuff[OS_TCB_NAME_LEN] = { 0 }; @@ -1365,10 +1244,9 @@ LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL s } err = LOS_OK; - processCB = OS_PCB_FROM_PID(taskCB->processID); /* if thread is main thread, then set processName as taskName */ - if ((taskCB->taskID == processCB->threadGroupID) && (setPName == TRUE)) { - err = (INT32)OsSetProcessName(processCB, (const CHAR *)taskCB->taskName); + if ((taskCB->taskID == OsProcessThreadGroupIDGet(taskCB)) && (setPName == TRUE)) { + err = (INT32)OsSetProcessName(OS_PCB_FROM_PID(taskCB->processID), (const CHAR *)taskCB->taskName); if (err != LOS_OK) { err = EINVAL; } @@ -1379,85 +1257,6 @@ EXIT: return err; } -STATIC VOID OsExitGroupActiveTaskKilled(LosProcessCB *processCB, LosTaskCB *taskCB) -{ - INT32 ret; - - taskCB->taskStatus |= OS_TASK_FLAG_EXIT_KILL; -#ifdef LOSCFG_KERNEL_SMP - /* The other core that the thread is running on and is currently running in a non-system call */ - if (!taskCB->sig.sigIntLock && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { - taskCB->signal = SIGNAL_KILL; - LOS_MpSchedule(taskCB->currCpu); - } else -#endif -#ifdef LOSCFG_KERNEL_VM - { - ret = OsTaskKillUnsafe(taskCB->taskID, SIGKILL); - if (ret != LOS_OK) { - PRINT_ERR("pid %u exit, Exit task group %u kill %u failed! ERROR: %d\n", - taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, ret); - } - } -#endif - - if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) { - taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; - LOS_ListInit(&taskCB->joinList); - } - - ret = OsTaskJoinPendUnsafe(taskCB); - if (ret != LOS_OK) { - PRINT_ERR("pid %u exit, Exit task group %u to wait others task %u(0x%x) exit failed! ERROR: %d\n", - taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, taskCB->taskStatus, ret); - } -} - -LITE_OS_SEC_TEXT VOID OsTaskExitGroup(UINT32 status) -{ - UINT32 intSave; - - LosProcessCB *processCB = OsCurrProcessGet(); - LosTaskCB *currTask = OsCurrTaskGet(); - SCHEDULER_LOCK(intSave); - if ((processCB->processStatus & OS_PROCESS_FLAG_EXIT) || !OsProcessIsUserMode(processCB)) { - SCHEDULER_UNLOCK(intSave); - return; - } - - processCB->processStatus |= OS_PROCESS_FLAG_EXIT; - processCB->threadGroupID = currTask->taskID; - - LOS_DL_LIST *list = &processCB->threadSiblingList; - LOS_DL_LIST *head = list; - do { - LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList); - if ((taskCB->taskStatus & (OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT) || - ((taskCB->taskStatus & OS_TASK_STATUS_READY) && !taskCB->sig.sigIntLock)) && - !(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { - OsTaskDeleteInactive(processCB, taskCB); - } else { - if (taskCB != currTask) { - OsExitGroupActiveTaskKilled(processCB, taskCB); - } else { - /* Skip the current task */ - list = list->pstNext; - } - } - } while (head != list->pstNext); - - SCHEDULER_UNLOCK(intSave); - - LOS_ASSERT(processCB->threadNumber == 1); - return; -} - -LITE_OS_SEC_TEXT VOID OsExecDestroyTaskGroup(VOID) -{ - OsTaskExitGroup(OS_PRO_EXIT_OK); - OsTaskCBRecycleToFree(); -} - UINT32 OsUserTaskOperatePermissionsCheck(LosTaskCB *taskCB) { return OsUserProcessOperatePermissionsCheck(taskCB, OsCurrProcessGet()->processID); @@ -1514,7 +1313,6 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam) { - LosProcessCB *processCB = NULL; UINT32 taskID; UINT32 ret; UINT32 intSave; @@ -1529,15 +1327,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S initParam->policy = LOS_SCHED_RR; if (processID == OS_INVALID_VALUE) { SCHEDULER_LOCK(intSave); - processCB = OsCurrProcessGet(); + LosProcessCB *processCB = OsCurrProcessGet(); initParam->processID = processCB->processID; initParam->consoleID = processCB->consoleID; SCHEDULER_UNLOCK(intSave); } else { - processCB = OS_PCB_FROM_PID(processID); - if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) { - return OS_INVALID_VALUE; - } initParam->processID = processID; initParam->consoleID = 0; } diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index 0403d132..dd39accd 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -80,10 +80,8 @@ typedef struct ProcessCB { UINT32 processID; /**< Process ID */ UINT16 processStatus; /**< [15:4] Process Status; [3:0] The number of threads currently running in the process */ - UINT16 priority; /**< Process priority */ UINT16 consoleID; /**< The console id of task belongs */ UINT16 processMode; /**< Kernel Mode:0; User Mode:1; */ - UINT16 readyTaskNum; /**< The number of ready tasks in the current process */ UINT32 parentProcessID; /**< Parent process ID */ UINT32 exitCode; /**< Process exit status */ LOS_DL_LIST pendList; /**< Block list to which the process belongs */ @@ -149,7 +147,7 @@ typedef struct ProcessCB { * * The process is created but does not participate in scheduling. */ -#define OS_PROCESS_STATUS_INIT 0x0010U +#define OS_PROCESS_STATUS_INIT OS_TASK_STATUS_INIT /** * @ingroup los_process @@ -157,7 +155,7 @@ typedef struct ProcessCB { * * The process is ready. */ -#define OS_PROCESS_STATUS_READY 0x0020U +#define OS_PROCESS_STATUS_READY OS_TASK_STATUS_READY /** * @ingroup los_process @@ -165,7 +163,7 @@ typedef struct ProcessCB { * * The process is running. */ -#define OS_PROCESS_STATUS_RUNNING 0x0040U +#define OS_PROCESS_STATUS_RUNNING OS_TASK_STATUS_RUNNING /** * @ingroup los_process @@ -173,7 +171,7 @@ typedef struct ProcessCB { * * The process is pending */ -#define OS_PROCESS_STATUS_PENDING 0x0080U +#define OS_PROCESS_STATUS_PENDING (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY | OS_TASK_STATUS_SUSPENDED) /** * @ingroup los_process @@ -181,23 +179,7 @@ typedef struct ProcessCB { * * The process is run out but the resources occupied by the process are not recovered. */ -#define OS_PROCESS_STATUS_ZOMBIES 0x100U - -/** - * @ingroup los_process - * Flag that indicates the process or process control block status. - * - * The number of task currently running under the process, it only works with multiple cores. - */ -#define OS_PROCESS_RUNTASK_COUNT_MASK 0x000FU - -/** - * @ingroup los_process - * Flag that indicates the process or process control block status. - * - * The process status mask. - */ -#define OS_PROCESS_STATUS_MASK 0xFFF0U +#define OS_PROCESS_STATUS_ZOMBIES 0x0100U /** * @ingroup los_process @@ -267,6 +249,11 @@ STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB) return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_ZOMBIES)) != 0); } +STATIC INLINE BOOL OsProcessIsInit(const LosProcessCB *processCB) +{ + return (processCB->processStatus & OS_PROCESS_STATUS_INIT); +} + /** * @ingroup los_process * The highest priority of a kernel mode process. @@ -297,13 +284,6 @@ STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB) */ #define OS_PROCESS_USERINIT_PRIORITY 28 -#define OS_GET_PROCESS_STATUS(status) ((UINT16)((UINT16)(status) & OS_PROCESS_STATUS_MASK)) -#define OS_PROCESS_GET_RUNTASK_COUNT(status) ((UINT16)(((UINT16)(status)) & OS_PROCESS_RUNTASK_COUNT_MASK)) -#define OS_PROCESS_RUNTASK_COUNT_ADD(status) ((UINT16)(((UINT16)(status)) & OS_PROCESS_STATUS_MASK) | \ - ((OS_PROCESS_GET_RUNTASK_COUNT(status) + 1) & OS_PROCESS_RUNTASK_COUNT_MASK)) -#define OS_PROCESS_RUNTASK_COUNT_DEC(status) ((UINT16)(((UINT16)(status)) & OS_PROCESS_STATUS_MASK) | \ - ((OS_PROCESS_GET_RUNTASK_COUNT(status) - 1) & OS_PROCESS_RUNTASK_COUNT_MASK)) - #define OS_TASK_DEFAULT_STACK_SIZE 0x2000 #define OS_USER_TASK_SYSCALL_STACK_SIZE 0x3000 #define OS_USER_TASK_STACK_SIZE 0x100000 @@ -410,6 +390,18 @@ STATIC INLINE UINT32 OsProcessThreadGroupIDGet(const LosTaskCB *taskCB) return OS_PCB_FROM_PID(taskCB->processID)->threadGroupID; } +STATIC INLINE UINT32 OsProcessThreadNumberGet(const LosTaskCB *taskCB) +{ + return OS_PCB_FROM_PID(taskCB->processID)->threadNumber; +} + +#ifdef LOSCFG_KERNEL_VM +STATIC INLINE LosVmSpace *OsProcessVmSpaceGet(const LosProcessCB *processCB) +{ + return processCB->vmSpace; +} +#endif + #ifdef LOSCFG_DRIVERS_TZDRIVER STATIC INLINE struct Vnode *OsProcessExecVnodeGet(const LosProcessCB *processCB) { @@ -474,15 +466,14 @@ extern UINTPTR __user_init_bss; extern UINTPTR __user_init_end; extern UINTPTR __user_init_load_addr; extern UINT32 OsSystemProcessCreate(VOID); +extern VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status); extern VOID OsProcessCBRecycleToFree(VOID); extern VOID OsProcessResourcesToFree(LosProcessCB *processCB); -extern VOID OsProcessExit(LosTaskCB *runTask, INT32 status); extern UINT32 OsUserInitProcess(VOID); -extern VOID OsTaskSchedQueueDequeue(LosTaskCB *taskCB, UINT16 status); -extern VOID OsTaskSchedQueueEnqueue(LosTaskCB *taskCB, UINT16 status); extern INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size); -extern UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, - LosVmSpace *oldAspace, UINTPTR oldFiles); +extern VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace); +extern LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD); +extern UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldAspace, UINTPTR oldFiles); extern UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize); extern UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name); extern INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy); @@ -497,6 +488,9 @@ extern UINTPTR OsGetSigHandler(VOID); extern VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID); extern INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission); extern INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission); +extern UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB); +extern VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB); +extern VOID OsProcessThreadGroupDestroy(VOID); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index 09d49654..354edf34 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -32,10 +32,22 @@ #ifndef _LOS_SCHED_PRI_H #define _LOS_SCHED_PRI_H -#include "los_task_pri.h" +#include "los_sortlink_pri.h" #include "los_sys_pri.h" #include "los_hwi.h" #include "hal_timer.h" +#ifdef LOSCFG_SCHED_DEBUG +#include "los_stat_pri.h" +#endif +#include "los_stackinfo_pri.h" +#include "los_futex_pri.h" +#include "los_signal.h" +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" +#endif +#ifdef LOSCFG_KERNEL_LITEIPC +#include "hm_liteipc.h" +#endif #ifdef __cplusplus #if __cplusplus @@ -53,6 +65,11 @@ extern UINT32 g_taskScheduled; typedef BOOL (*SCHED_TL_FIND_FUNC)(UINTPTR, UINTPTR); +STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID) +{ + return HalClockGetCycles(); +} + typedef enum { INT_NO_RESCH = 0x0, /* no needs to schedule */ INT_PEND_RESCH = 0x1, /* pending schedule flag */ @@ -243,9 +260,212 @@ VOID OsSchedRunQueSwtmrInit(UINT32 swtmrTaskID, UINT32 swtmrQueue); VOID OsSchedRunQueInit(VOID); BOOL OsSchedSwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg); -STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID) +/** + * @ingroup los_sched + * Define a usable task priority. + * + * Highest task priority. + */ +#define OS_TASK_PRIORITY_HIGHEST 0 + +/** + * @ingroup los_sched + * Define a usable task priority. + * + * Lowest task priority. + */ +#define OS_TASK_PRIORITY_LOWEST 31 + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is init. + */ +#define OS_TASK_STATUS_INIT 0x0001U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is ready. + */ +#define OS_TASK_STATUS_READY 0x0002U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is running. + */ +#define OS_TASK_STATUS_RUNNING 0x0004U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is suspended. + */ +#define OS_TASK_STATUS_SUSPENDED 0x0008U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is blocked. + */ +#define OS_TASK_STATUS_PENDING 0x0010U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is delayed. + */ +#define OS_TASK_STATUS_DELAY 0x0020U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The time for waiting for an event to occur expires. + */ +#define OS_TASK_STATUS_TIMEOUT 0x0040U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is pend for a period of time. + */ +#define OS_TASK_STATUS_PEND_TIME 0x0080U + +/** + * @ingroup los_sched + * Flag that indicates the task or task control block status. + * + * The task is exit. + */ +#define OS_TASK_STATUS_EXIT 0x0100U + +#define OS_TCB_NAME_LEN 32 + +typedef struct { + VOID *stackPointer; /**< Task stack pointer */ + UINT16 taskStatus; /**< Task status */ + + /* The scheduling */ + UINT16 basePrio; + UINT16 priority; /**< Task priority */ + UINT16 policy; + UINT64 startTime; /**< The start time of each phase of task */ + UINT64 irqStartTime; /**< Interrupt start time */ + UINT32 irqUsedTime; /**< Interrupt consumption time */ + UINT32 initTimeSlice; /**< Task init time slice */ + INT32 timeSlice; /**< Task remaining time slice */ + UINT32 waitTimes; /**< Task delay time, tick number */ + SortLinkList sortList; /**< Task sortlink node */ + + UINT32 stackSize; /**< Task stack size */ + UINTPTR topOfStack; /**< Task stack top */ + UINT32 taskID; /**< Task ID */ + TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */ + VOID *joinRetval; /**< pthread adaption */ + VOID *taskMux; /**< Task-held mutex */ + VOID *taskEvent; /**< Task-held event */ + UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */ + CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */ + LOS_DL_LIST pendList; /**< Task pend node */ + LOS_DL_LIST threadList; /**< thread list */ + UINT32 eventMask; /**< Event mask */ + UINT32 eventMode; /**< Event mode */ + UINT32 priBitMap; /**< BitMap for recording the change of task priority, + the priority can not be greater than 31 */ +#ifdef LOSCFG_KERNEL_CPUP + OsCpupBase taskCpup; /**< task cpu usage */ +#endif + INT32 errorNo; /**< Error Num */ + UINT32 signal; /**< Task signal */ + sig_cb sig; +#ifdef LOSCFG_KERNEL_SMP + UINT16 currCpu; /**< CPU core number of this task is running on */ + UINT16 lastCpu; /**< CPU core number of this task is running on last time */ + UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores */ +#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC + UINT32 syncSignal; /**< Synchronization for signal handling */ +#endif +#ifdef LOSCFG_KERNEL_SMP_LOCKDEP + LockDep lockDep; +#endif +#endif +#ifdef LOSCFG_SCHED_DEBUG + SchedStat schedStat; /**< Schedule statistics */ +#endif +#ifdef LOSCFG_KERNEL_VM + UINTPTR archMmu; + UINTPTR userArea; + UINTPTR userMapBase; + UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */ + FutexNode futex; +#endif + UINT32 processID; /**< Which belong process */ + LOS_DL_LIST joinList; /**< join list */ + LOS_DL_LIST lockList; /**< Hold the lock list */ + UINTPTR waitID; /**< Wait for the PID or GID of the child process */ + UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent, + a specific child process, or any child process */ +#ifdef LOSCFG_KERNEL_LITEIPC + IpcTaskInfo *ipcTaskInfo; +#endif +#ifdef LOSCFG_KERNEL_PERF + UINTPTR pc; + UINTPTR fp; +#endif +} LosTaskCB; + +STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB) { - return HalClockGetCycles(); + return ((taskCB->taskStatus & OS_TASK_STATUS_RUNNING) != 0); +} + +STATIC INLINE BOOL OsTaskIsReady(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_READY) != 0); +} + +STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & (OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) != 0); +} + +STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_PENDING) != 0); +} + +STATIC INLINE BOOL OsTaskIsSuspended(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_STATUS_SUSPENDED) != 0); +} + +STATIC INLINE BOOL OsTaskIsBlocked(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & (OS_TASK_STATUS_SUSPENDED | OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) != 0); +} + +STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID) +{ + return (LosTaskCB *)ArchCurrTaskGet(); +} + +STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task) +{ + ArchCurrTaskSet(task); +} + +STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread) +{ + ArchCurrUserTaskSet(thread); } STATIC INLINE VOID OsSchedIrqUpdateUsedTime(VOID) diff --git a/kernel/base/include/los_sortlink_pri.h b/kernel/base/include/los_sortlink_pri.h index 83465653..89fa1761 100644 --- a/kernel/base/include/los_sortlink_pri.h +++ b/kernel/base/include/los_sortlink_pri.h @@ -92,8 +92,8 @@ STATIC INLINE UINT32 OsGetSortLinkNodeNum(SortLinkAttribute *head) VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader); VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu); VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node); -UINT32 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList); -UINT32 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader); +UINT64 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList); +UINT64 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h index f9030500..11722cf1 100644 --- a/kernel/base/include/los_task_pri.h +++ b/kernel/base/include/los_task_pri.h @@ -33,20 +33,8 @@ #define _LOS_TASK_PRI_H #include "los_task.h" -#include "los_sortlink_pri.h" -#include "los_spinlock.h" -#ifdef LOSCFG_SCHED_DEBUG -#include "los_stat_pri.h" -#endif -#include "los_stackinfo_pri.h" -#include "los_futex_pri.h" -#include "los_signal.h" -#ifdef LOSCFG_KERNEL_CPUP -#include "los_cpup_pri.h" -#endif -#ifdef LOSCFG_KERNEL_LITEIPC -#include "hm_liteipc.h" -#endif +#include "los_sched_pri.h" + #ifdef __cplusplus #if __cplusplus extern "C" { @@ -79,97 +67,6 @@ extern SPIN_LOCK_S g_taskSpin; */ #define OS_TASK_ERRORID 0xFFFFFFFF -/** - * @ingroup los_task - * Define a usable task priority. - * - * Highest task priority. - */ -#define OS_TASK_PRIORITY_HIGHEST 0 - -/** - * @ingroup los_task - * Define a usable task priority. - * - * Lowest task priority. - */ -#define OS_TASK_PRIORITY_LOWEST 31 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is init. - */ -#define OS_TASK_STATUS_INIT 0x0001U - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is ready. - */ -#define OS_TASK_STATUS_READY 0x0002U - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is running. - */ -#define OS_TASK_STATUS_RUNNING 0x0004U - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is suspended. - */ -#define OS_TASK_STATUS_SUSPENDED 0x0008U - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is blocked. - */ -#define OS_TASK_STATUS_PENDING 0x0010U - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is delayed. - */ -#define OS_TASK_STATUS_DELAY 0x0020U - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The time for waiting for an event to occur expires. - */ -#define OS_TASK_STATUS_TIMEOUT 0x0040U - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is pend for a period of time. - */ -#define OS_TASK_STATUS_PEND_TIME 0x0080U - -#define OS_TASK_STATUS_BLOCKED (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \ - OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME) - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is exit. - */ -#define OS_TASK_STATUS_EXIT 0x0100U - /** * @ingroup los_task * Flag that indicates the task or task control block status. @@ -186,6 +83,14 @@ extern SPIN_LOCK_S g_taskSpin; */ #define OS_TASK_FLAG_PTHREAD_JOIN 0x0400U +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is user mode task. + */ +#define OS_TASK_FLAG_USER_MODE 0x0800U + /** * @ingroup los_task * Flag that indicates the task property. @@ -306,76 +211,6 @@ extern SPIN_LOCK_S g_taskSpin; #define OS_RESOURCE_EVENT_MASK 0xFF #define OS_RESOURCE_EVENT_OOM 0x02 #define OS_RESOURCE_EVENT_FREE 0x04 -#define OS_TCB_NAME_LEN 32 - -typedef struct { - VOID *stackPointer; /**< Task stack pointer */ - UINT16 taskStatus; /**< Task status */ - - /* The scheduling */ - UINT16 priority; /**< Task priority */ - UINT16 policy; - UINT64 startTime; /**< The start time of each phase of task */ - UINT64 irqStartTime; /**< Interrupt start time */ - UINT32 irqUsedTime; /**< Interrupt consumption time */ - UINT32 initTimeSlice; /**< Task init time slice */ - INT32 timeSlice; /**< Task remaining time slice */ - UINT32 waitTimes; /**< Task delay time, tick number */ - SortLinkList sortList; /**< Task sortlink node */ - - UINT32 stackSize; /**< Task stack size */ - UINTPTR topOfStack; /**< Task stack top */ - UINT32 taskID; /**< Task ID */ - TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */ - VOID *joinRetval; /**< pthread adaption */ - VOID *taskMux; /**< Task-held mutex */ - VOID *taskEvent; /**< Task-held event */ - UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */ - CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */ - LOS_DL_LIST pendList; /**< Task pend node */ - LOS_DL_LIST threadList; /**< thread list */ - UINT32 eventMask; /**< Event mask */ - UINT32 eventMode; /**< Event mode */ - UINT32 priBitMap; /**< BitMap for recording the change of task priority, - the priority can not be greater than 31 */ -#ifdef LOSCFG_KERNEL_CPUP - OsCpupBase taskCpup; /**< task cpu usage */ -#endif - INT32 errorNo; /**< Error Num */ - UINT32 signal; /**< Task signal */ - sig_cb sig; -#ifdef LOSCFG_KERNEL_SMP - UINT16 currCpu; /**< CPU core number of this task is running on */ - UINT16 lastCpu; /**< CPU core number of this task is running on last time */ - UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores */ -#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC - UINT32 syncSignal; /**< Synchronization for signal handling */ -#endif -#ifdef LOSCFG_KERNEL_SMP_LOCKDEP - LockDep lockDep; -#endif -#endif -#ifdef LOSCFG_SCHED_DEBUG - SchedStat schedStat; /**< Schedule statistics */ -#endif - UINTPTR userArea; - UINTPTR userMapBase; - UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */ - UINT32 processID; /**< Which belong process */ - FutexNode futex; - LOS_DL_LIST joinList; /**< join list */ - LOS_DL_LIST lockList; /**< Hold the lock list */ - UINTPTR waitID; /**< Wait for the PID or GID of the child process */ - UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent, - a specific child process, or any child process */ -#ifdef LOSCFG_KERNEL_LITEIPC - IpcTaskInfo *ipcTaskInfo; -#endif -#ifdef LOSCFG_KERNEL_PERF - UINTPTR pc; - UINTPTR fp; -#endif -} LosTaskCB; typedef struct { LosTaskCB *runTask; @@ -416,21 +251,6 @@ typedef struct { UINT16 timeout; /**< Expiration duration */ } OsTaskRobin; -STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID) -{ - return (LosTaskCB *)ArchCurrTaskGet(); -} - -STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task) -{ - ArchCurrTaskSet(task); -} - -STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread) -{ - ArchCurrUserTaskSet(thread); -} - STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID) { return OS_TCB_FROM_TID(taskID); @@ -438,47 +258,17 @@ STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID) STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB) { - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { - return TRUE; - } - - return FALSE; -} - -STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB) -{ - if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { - return TRUE; - } - - return FALSE; -} - -STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) -{ - if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) { - return TRUE; - } - - return FALSE; -} - -STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB) -{ - if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { - return TRUE; - } - - return FALSE; + return ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED) != 0); } STATIC INLINE BOOL OsTaskIsKilled(const LosTaskCB *taskCB) { - if (taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) { - return TRUE; - } + return ((taskCB->taskStatus & OS_TASK_FLAG_EXIT_KILL) != 0); +} - return FALSE; +STATIC INLINE BOOL OsTaskIsUserMode(const LosTaskCB *taskCB) +{ + return ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) != 0); } #define OS_TID_CHECK_INVALID(taskID) ((UINT32)(taskID) >= g_taskMaxNum) @@ -529,21 +319,18 @@ extern VOID OsSetMainTask(VOID); extern UINT32 OsGetIdleTaskId(VOID); extern VOID OsTaskEntry(UINT32 taskID); extern VOID OsTaskProcSignal(VOID); -extern UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UINT32 intSave); -extern VOID OsTaskResourcesToFree(LosTaskCB *taskCB); -extern VOID OsRunTaskToDelete(LosTaskCB *taskCB); extern UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam); extern INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName); extern VOID OsTaskCBRecycleToFree(VOID); -extern VOID OsTaskExitGroup(UINT32 status); -extern VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status); -extern VOID OsExecDestroyTaskGroup(VOID); +extern VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status); extern UINT32 OsUserTaskOperatePermissionsCheck(LosTaskCB *taskCB); extern UINT32 OsUserProcessOperatePermissionsCheck(LosTaskCB *taskCB, UINT32 processID); extern INT32 OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info); extern VOID OsWriteResourceEvent(UINT32 events); extern VOID OsWriteResourceEventUnsafe(UINT32 events); extern UINT32 OsResourceFreeTaskCreate(VOID); +extern VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB); +extern VOID OsInactiveTaskDelete(LosTaskCB *taskCB); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/ipc/los_signal.c b/kernel/base/ipc/los_signal.c index 3a4eb579..dd179d86 100644 --- a/kernel/base/ipc/los_signal.c +++ b/kernel/base/ipc/los_signal.c @@ -695,8 +695,8 @@ VOID *OsSaveSignalContext(VOID *sp, VOID *newSp) return sp; } - if (task->taskStatus & OS_TASK_FLAG_EXIT_KILL) { - OsTaskToExit(task, 0); + if (OsTaskIsKilled(task)) { + OsRunningTaskToExit(task, 0); return sp; } diff --git a/kernel/base/misc/task_shellcmd.c b/kernel/base/misc/task_shellcmd.c index 854e2d6c..0659eedf 100644 --- a/kernel/base/misc/task_shellcmd.c +++ b/kernel/base/misc/task_shellcmd.c @@ -128,7 +128,6 @@ LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdSchedPolicy(UINT16 policy) LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellProcessStatus(UINT16 status) { - status = status & OS_PROCESS_STATUS_MASK; if (status & OS_PROCESS_STATUS_ZOMBIES) { return (UINT8 *)"Zombies"; } else if (status & OS_PROCESS_STATUS_INIT) { @@ -137,11 +136,8 @@ LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellProcessStatus(UINT16 status) return (UINT8 *)"Running"; } else if (status & OS_PROCESS_STATUS_READY) { return (UINT8 *)"Ready"; - } else if (status & OS_PROCESS_STATUS_PENDING) { - return (UINT8 *)"Pending"; } - - return (UINT8 *)"Invalid"; + return (UINT8 *)"Pending"; } STATIC VOID OsShellCmdProcessTitle(VOID *seqBuf, UINT16 flag) @@ -189,7 +185,7 @@ STATIC VOID OsShellCmdProcessInfoShow(const LosProcessCB *processCB, const INT32 processCpup1s[pid].usage % LOS_CPUP_PRECISION_MULT); #endif /* LOSCFG_KERNEL_CPUP */ PROCESS_INFO_SHOW(seqBuf, "%6s%9u%5d%10u%7s ", - OsShellCmdSchedPolicy(LOS_SCHED_RR), processCB->priority, + OsShellCmdSchedPolicy(LOS_SCHED_RR), OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio, (INT32)processCB->threadGroupID, processCB->threadNumber, OsShellCmdProcessMode(processCB->processMode)); } else { @@ -246,17 +242,28 @@ STATIC VOID OsProcessMemUsageGet(UINT32 *memArray) } #endif -STATIC UINT32 OsProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, UINT32 **memArray, UINT16 flag) +#define OS_TASK_STATUS_MASK 0x00FF +STATIC VOID OsProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, + UINT32 **memArray, LosTaskCB **tcbArray, + UINT16 flag) { - UINT32 len = OS_PROCESS_ALL_INFO_LEN; - LosProcessCB *processCB = NULL; - INT32 *user = NULL; - - (VOID)memcpy_s(*pcbArray, OS_PROCESS_INFO_LEN, g_processCBArray, OS_PROCESS_INFO_LEN); *group = (INT32 *)((UINTPTR)*pcbArray + OS_PROCESS_INFO_LEN); - user = (INT32 *)((UINTPTR)*group + OS_PROCESS_GROUP_INFO_LEN); + INT32 *user = (INT32 *)((UINTPTR)*group + OS_PROCESS_GROUP_INFO_LEN); + + for (UINT32 tid = 0; tid < g_taskMaxNum; tid++) { + LosTaskCB *taskCB = *tcbArray + tid; + if (OsTaskIsUnused(taskCB)) { + continue; + } + + LosProcessCB *processCB = *pcbArray + taskCB->processID; + if (!OsProcessIsDead(processCB) && !OsProcessIsInit(processCB)) { + processCB->processStatus |= (taskCB->taskStatus & OS_TASK_STATUS_MASK); + } + } + for (UINT32 pid = 0; pid < g_processMaxNum; ++pid) { - processCB = *pcbArray + pid; + LosProcessCB *processCB = *pcbArray + pid; if (OsProcessIsUnused(processCB)) { continue; } @@ -295,11 +302,8 @@ STATIC UINT32 OsProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, UINT32 ** if (flag & OS_PROCESS_MEM_INFO) { *memArray = (UINT32 *)((UINTPTR)*pcbArray + OS_PROCESS_ALL_INFO_LEN); OsProcessMemUsageGet(*memArray); - len += OS_PROCESS_MEM_ALL_INFO_LEN; } #endif - - return len; } STATIC VOID OsShellCmdProcessInfoData(const LosProcessCB *pcbArray, const INT32 *group, @@ -522,16 +526,24 @@ STATIC VOID OsProcessAndTaskInfoGet(LosProcessCB **pcbArray, INT32 **group, LosT { BOOL lockFlag = FALSE; UINT32 intSave = 0; - UINT32 processInfoLen; + UINT32 processInfoLen = OS_PROCESS_ALL_INFO_LEN; if (LOS_SpinHeld(&g_taskSpin) == FALSE) { SCHEDULER_LOCK(intSave); lockFlag = TRUE; } - processInfoLen = OsProcessInfoGet(pcbArray, group, memArray, flag); +#ifdef LOSCFG_KERNEL_VM + if (flag & OS_PROCESS_MEM_INFO) { + processInfoLen += OS_PROCESS_MEM_ALL_INFO_LEN; + } +#endif + + (VOID)memcpy_s(*pcbArray, OS_PROCESS_INFO_LEN, g_processCBArray, OS_PROCESS_INFO_LEN); *tcbArray = (LosTaskCB *)((UINTPTR)*pcbArray + processInfoLen); (VOID)memcpy_s(*tcbArray, OS_TASK_INFO_LEN, g_taskCBArray, OS_TASK_INFO_LEN); + + OsProcessInfoGet(pcbArray, group, memArray, tcbArray, flag); taskWaterLine = (UINT32 *)((UINTPTR)*tcbArray + OS_TASK_INFO_LEN); OsShellCmdTaskWaterLineGet(*tcbArray); if (lockFlag == TRUE) { diff --git a/kernel/base/sched/sched_sq/los_sched.c b/kernel/base/sched/sched_sq/los_sched.c index d0fb5660..c0a47100 100644 --- a/kernel/base/sched/sched_sq/los_sched.c +++ b/kernel/base/sched/sched_sq/los_sched.c @@ -60,7 +60,8 @@ #define OS_SCHED_READY_MAX 30 #define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */ -#define OS_CHECK_TASK_BLOCK (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PENDING | OS_TASK_STATUS_SUSPENDED) +#define OS_TASK_STATUS_BLOCKED (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \ + OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME) typedef struct { LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM]; @@ -421,18 +422,18 @@ STATIC INLINE VOID SchedPriQueueDelete(UINT32 proPriority, LOS_DL_LIST *priqueue } } -STATIC INLINE VOID SchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) +STATIC INLINE VOID SchedEnTaskQueue(LosTaskCB *taskCB) { LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY)); switch (taskCB->policy) { case LOS_SCHED_RR: { if (taskCB->timeSlice > OS_TIME_SLICE_MIN) { - SchedPriQueueEnHead(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnHead(taskCB->basePrio, &taskCB->pendList, taskCB->priority); } else { - taskCB->initTimeSlice = SchedCalculateTimeSlice(processCB->priority, taskCB->priority); + taskCB->initTimeSlice = SchedCalculateTimeSlice(taskCB->basePrio, taskCB->priority); taskCB->timeSlice = taskCB->initTimeSlice; - SchedPriQueueEnTail(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnTail(taskCB->basePrio, &taskCB->pendList, taskCB->priority); #ifdef LOSCFG_SCHED_DEBUG taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime; taskCB->schedStat.timeSliceCount++; @@ -443,11 +444,11 @@ STATIC INLINE VOID SchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) case LOS_SCHED_FIFO: { /* The time slice of FIFO is always greater than 0 unless the yield is called */ if ((taskCB->timeSlice > OS_TIME_SLICE_MIN) && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { - SchedPriQueueEnHead(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnHead(taskCB->basePrio, &taskCB->pendList, taskCB->priority); } else { taskCB->initTimeSlice = OS_SCHED_FIFO_TIMEOUT; taskCB->timeSlice = taskCB->initTimeSlice; - SchedPriQueueEnTail(processCB->priority, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnTail(taskCB->basePrio, &taskCB->pendList, taskCB->priority); } break; } @@ -463,63 +464,32 @@ STATIC INLINE VOID SchedEnTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED; taskCB->taskStatus |= OS_TASK_STATUS_READY; - - processCB->processStatus &= ~(OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_PENDING); - processCB->processStatus |= OS_PROCESS_STATUS_READY; - processCB->readyTaskNum++; -} - -STATIC INLINE VOID SchedDeTaskQueue(LosTaskCB *taskCB, LosProcessCB *processCB) -{ - if (taskCB->policy != LOS_SCHED_IDLE) { - SchedPriQueueDelete(processCB->priority, &taskCB->pendList, taskCB->priority); - } - taskCB->taskStatus &= ~OS_TASK_STATUS_READY; - - processCB->readyTaskNum--; - if (processCB->readyTaskNum == 0) { - processCB->processStatus &= ~OS_PROCESS_STATUS_READY; - } } VOID OsSchedTaskDeQueue(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - if (taskCB->taskStatus & OS_TASK_STATUS_READY) { - SchedDeTaskQueue(taskCB, processCB); - } - - if (processCB->processStatus & OS_PROCESS_STATUS_READY) { - return; - } - - /* If the current process has only the current thread running, - * the process becomes blocked after the thread leaves the scheduling queue - */ - if (OS_PROCESS_GET_RUNTASK_COUNT(processCB->processStatus) == 1) { - processCB->processStatus |= OS_PROCESS_STATUS_PENDING; + if (taskCB->policy != LOS_SCHED_IDLE) { + SchedPriQueueDelete(taskCB->basePrio, &taskCB->pendList, taskCB->priority); + } + taskCB->taskStatus &= ~OS_TASK_STATUS_READY; } } VOID OsSchedTaskEnQueue(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); #ifdef LOSCFG_SCHED_DEBUG if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) { taskCB->startTime = OsGetCurrSchedTimeCycle(); } #endif - SchedEnTaskQueue(taskCB, processCB); + SchedEnTaskQueue(taskCB); } VOID OsSchedTaskExit(LosTaskCB *taskCB) { - LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); - if (taskCB->taskStatus & OS_TASK_STATUS_READY) { OsSchedTaskDeQueue(taskCB); - processCB->processStatus &= ~OS_PROCESS_STATUS_PENDING; } else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) { LOS_ListDelete(&taskCB->pendList); taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING; @@ -554,7 +524,6 @@ VOID OsSchedDelay(LosTaskCB *runTask, UINT32 tick) UINT32 OsSchedTaskWait(LOS_DL_LIST *list, UINT32 ticks, BOOL needSched) { LosTaskCB *runTask = OsCurrTaskGet(); - OsSchedTaskDeQueue(runTask); runTask->taskStatus |= OS_TASK_STATUS_PENDING; LOS_ListTailInsert(list, &runTask->pendList); @@ -629,19 +598,15 @@ BOOL OsSchedModifyProcessSchedParam(UINT32 pid, UINT16 policy, UINT16 priority) BOOL needSched = FALSE; (VOID)policy; - if (processCB->processStatus & OS_PROCESS_STATUS_READY) { - LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { - if (taskCB->taskStatus & OS_TASK_STATUS_READY) { - SchedPriQueueDelete(processCB->priority, &taskCB->pendList, taskCB->priority); - SchedPriQueueEnTail(priority, &taskCB->pendList, taskCB->priority); - needSched = TRUE; - } + LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) { + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + SchedPriQueueDelete(taskCB->basePrio, &taskCB->pendList, taskCB->priority); + SchedPriQueueEnTail(priority, &taskCB->pendList, taskCB->priority); + needSched = TRUE; + } else if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + needSched = TRUE; } - } - - processCB->priority = priority; - if (processCB->processStatus & OS_PROCESS_STATUS_RUNNING) { - needSched = TRUE; + taskCB->basePrio = priority; } return needSched; @@ -714,7 +679,7 @@ BOOL OsSchedResume(LosTaskCB *taskCB) SchedUnfreezeTask(taskCB); taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED; - if (!(taskCB->taskStatus & OS_CHECK_TASK_BLOCK)) { + if (!OsTaskIsBlocked(taskCB)) { OsSchedTaskEnQueue(taskCB); needSched = TRUE; } @@ -904,6 +869,7 @@ VOID OsSchedTick(VOID) VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask) { + idleTask->basePrio = OS_TASK_PRIORITY_LOWEST; idleTask->policy = LOS_SCHED_IDLE; idleTask->initTimeSlice = OS_SCHED_FIFO_TIMEOUT; idleTask->timeSlice = idleTask->initTimeSlice; @@ -994,7 +960,7 @@ STATIC LosTaskCB *GetTopTask(SchedRunQue *rq) newTask = OS_TCB_FROM_TID(rq->idleTaskID); FIND_TASK: - SchedDeTaskQueue(newTask, OS_PCB_FROM_PID(newTask->processID)); + OsSchedTaskDeQueue(newTask); return newTask; } @@ -1013,11 +979,7 @@ VOID OsSchedStart(VOID) SchedRunQue *rq = OsSchedRunQue(); LosTaskCB *newTask = GetTopTask(rq); - LosProcessCB *newProcess = OS_PCB_FROM_PID(newTask->processID); - newTask->taskStatus |= OS_TASK_STATUS_RUNNING; - newProcess->processStatus |= OS_PROCESS_STATUS_RUNNING; - newProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_ADD(newProcess->processStatus); #ifdef LOSCFG_KERNEL_SMP /* @@ -1075,26 +1037,6 @@ STATIC INLINE VOID SchedSwitchCheck(LosTaskCB *runTask, LosTaskCB *newTask) OsHookCall(LOS_HOOK_TYPE_TASK_SWITCHEDIN, newTask, runTask); } -STATIC INLINE VOID OsSchedSwitchProcess(LosProcessCB *runProcess, LosProcessCB *newProcess) -{ - runProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_DEC(runProcess->processStatus); - newProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_ADD(newProcess->processStatus); - - LOS_ASSERT(!(OS_PROCESS_GET_RUNTASK_COUNT(newProcess->processStatus) > LOSCFG_KERNEL_CORE_NUM)); - if (OS_PROCESS_GET_RUNTASK_COUNT(runProcess->processStatus) == 0) { - runProcess->processStatus &= ~OS_PROCESS_STATUS_RUNNING; - } - - LOS_ASSERT(!(newProcess->processStatus & OS_PROCESS_STATUS_PENDING)); - newProcess->processStatus |= OS_PROCESS_STATUS_RUNNING; - -#ifdef LOSCFG_KERNEL_VM - if (OsProcessIsUserMode(newProcess)) { - LOS_ArchMmuContextSwitch(&newProcess->vmSpace->archMmu); - } -#endif -} - STATIC VOID SchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) { UINT64 endTime; @@ -1111,15 +1053,11 @@ STATIC VOID SchedTaskSwitch(LosTaskCB *runTask, LosTaskCB *newTask) #endif OsCurrTaskSet((VOID *)newTask); - LosProcessCB *newProcess = OS_PCB_FROM_PID(newTask->processID); - LosProcessCB *runProcess = OS_PCB_FROM_PID(runTask->processID); - if (runProcess != newProcess) { - OsSchedSwitchProcess(runProcess, newProcess); - } - - if (OsProcessIsUserMode(newProcess)) { - OsCurrUserTaskSet(newTask->userArea); +#ifdef LOSCFG_KERNEL_VM + if (newTask->archMmu != runTask->archMmu) { + LOS_ArchMmuContextSwitch((LosArchMmu *)newTask->archMmu); } +#endif #ifdef LOSCFG_KERNEL_CPUP OsCpupCycleEndStart(runTask->taskID, newTask->taskID); diff --git a/kernel/base/sched/sched_sq/los_sortlink.c b/kernel/base/sched/sched_sq/los_sortlink.c index 61733ece..af5d1592 100644 --- a/kernel/base/sched/sched_sq/los_sortlink.c +++ b/kernel/base/sched/sched_sq/los_sortlink.c @@ -99,7 +99,7 @@ VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node) LOS_SpinUnlock(&head->spinLock); } -UINT32 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList) +UINT64 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList) { if (currTime >= targetSortList->responseTime) { return 0; @@ -108,12 +108,12 @@ UINT32 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *target return (UINT32)(targetSortList->responseTime - currTime); } -UINT32 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader) +UINT64 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader) { LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink; if (LOS_ListEmpty(head)) { - return 0; + return OS_SORT_LINK_INVALID_TIME; } SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode); diff --git a/kernel/extended/dynload/include/los_load_elf.h b/kernel/extended/dynload/include/los_load_elf.h index 9187dd35..252d1eab 100644 --- a/kernel/extended/dynload/include/los_load_elf.h +++ b/kernel/extended/dynload/include/los_load_elf.h @@ -123,6 +123,7 @@ STATIC INLINE BOOL OsIsBadUserAddress(VADDR_T vaddr) return (vaddr >= USER_STACK_TOP_MAX); } +extern UINT32 OsGetRndOffset(INT32 randomDevFD); extern INT32 OsLoadELFFile(ELFLoadInfo *loadInfo); #ifdef __cplusplus diff --git a/kernel/extended/dynload/src/los_load_elf.c b/kernel/extended/dynload/src/los_load_elf.c index bfa1df06..65c2eeee 100644 --- a/kernel/extended/dynload/src/los_load_elf.c +++ b/kernel/extended/dynload/src/los_load_elf.c @@ -716,18 +716,18 @@ STATIC INT32 OsGetParamNum(CHAR *const *argv) return count; } -STATIC UINT32 OsGetRndOffset(const ELFLoadInfo *loadInfo) +UINT32 OsGetRndOffset(INT32 randomDevFD) { UINT32 randomValue = 0; #ifdef LOSCFG_ASLR - if (read(loadInfo->randomDevFD, &randomValue, sizeof(UINT32)) == sizeof(UINT32)) { + if (read(randomDevFD, &randomValue, sizeof(UINT32)) == sizeof(UINT32)) { randomValue &= RANDOM_MASK; } else { randomValue = (UINT32)random() & RANDOM_MASK; } #else - (VOID)loadInfo; + (VOID)randomDevFD; #endif return ROUNDDOWN(randomValue, PAGE_SIZE); @@ -805,7 +805,7 @@ STATIC INT32 OsSetArgParams(ELFLoadInfo *loadInfo, CHAR *const *argv, CHAR *cons if (((UINT32)loadInfo->stackProt & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)) { return -ENOEXEC; } - loadInfo->stackTopMax = USER_STACK_TOP_MAX - OsGetRndOffset(loadInfo); + loadInfo->stackTopMax = USER_STACK_TOP_MAX - OsGetRndOffset(loadInfo->randomDevFD); loadInfo->stackBase = loadInfo->stackTopMax - USER_STACK_SIZE; loadInfo->stackSize = USER_STACK_SIZE; loadInfo->stackParamBase = loadInfo->stackTopMax - USER_PARAM_BYTE_MAX; @@ -963,7 +963,7 @@ STATIC INT32 OsLoadELFSegment(ELFLoadInfo *loadInfo) loadInfo->loadAddr = 0; if (loadInfo->execInfo.elfEhdr.elfType == LD_ET_DYN) { - loadBase = EXEC_MMAP_BASE + OsGetRndOffset(loadInfo); + loadBase = EXEC_MMAP_BASE + OsGetRndOffset(loadInfo->randomDevFD); mapSize = OsGetAllocSize(elfPhdrTemp, loadInfo->execInfo.elfEhdr.elfPhNum); if (mapSize == 0) { PRINT_ERR("%s[%d], Failed to get allocation size of file: %s!\n", __FUNCTION__, __LINE__, @@ -1009,17 +1009,7 @@ STATIC INT32 OsLoadELFSegment(ELFLoadInfo *loadInfo) STATIC VOID OsFlushAspace(ELFLoadInfo *loadInfo) { - LosProcessCB *processCB = OsCurrProcessGet(); - - OsExecDestroyTaskGroup(); - - loadInfo->oldSpace = processCB->vmSpace; - processCB->vmSpace = loadInfo->newSpace; - processCB->vmSpace->heapBase += OsGetRndOffset(loadInfo); - processCB->vmSpace->heapNow = processCB->vmSpace->heapBase; - processCB->vmSpace->mapBase += OsGetRndOffset(loadInfo); - processCB->vmSpace->mapSize = loadInfo->stackBase - processCB->vmSpace->mapBase; - LOS_ArchMmuContextSwitch(&OsCurrProcessGet()->vmSpace->archMmu); + loadInfo->oldSpace = OsExecProcessVmSpaceReplace(loadInfo->newSpace, loadInfo->stackBase, loadInfo->randomDevFD); } STATIC VOID OsDeInitLoadInfo(ELFLoadInfo *loadInfo) @@ -1079,8 +1069,7 @@ INT32 OsLoadELFFile(ELFLoadInfo *loadInfo) ret = OsLoadELFSegment(loadInfo); if (ret != LOS_OK) { - OsCurrProcessGet()->vmSpace = loadInfo->oldSpace; - LOS_ArchMmuContextSwitch(&OsCurrProcessGet()->vmSpace->archMmu); + OsExecProcessVmSpaceRestore(loadInfo->oldSpace); goto OUT; } diff --git a/kernel/extended/liteipc/hm_liteipc.c b/kernel/extended/liteipc/hm_liteipc.c index 6cdc8584..fe061eb3 100644 --- a/kernel/extended/liteipc/hm_liteipc.c +++ b/kernel/extended/liteipc/hm_liteipc.c @@ -697,7 +697,10 @@ LITE_OS_SEC_TEXT STATIC BOOL IsTaskAlive(UINT32 taskID) return FALSE; } tcb = OS_TCB_FROM_TID(taskID); - if (!OsProcessIsUserMode(OS_PCB_FROM_PID(tcb->processID))) { + if (!OsTaskIsUserMode(tcb)) { + return FALSE; + } + if (OsTaskIsUnused(tcb)) { return FALSE; } if (OsTaskIsInactive(tcb)) { diff --git a/syscall/process_syscall.c b/syscall/process_syscall.c index 11c4bcf7..916ccbcf 100644 --- a/syscall/process_syscall.c +++ b/syscall/process_syscall.c @@ -948,7 +948,6 @@ EXIT: int SysUserThreadDetach(unsigned int taskID) { unsigned int intSave; - LosTaskCB *taskCB = NULL; unsigned int ret; if (OS_TID_CHECK_INVALID(taskID)) { @@ -956,14 +955,13 @@ int SysUserThreadDetach(unsigned int taskID) } SCHEDULER_LOCK(intSave); - taskCB = OS_TCB_FROM_TID(taskID); - ret = OsUserTaskOperatePermissionsCheck(taskCB); + ret = OsUserTaskOperatePermissionsCheck(OS_TCB_FROM_TID(taskID)); + SCHEDULER_UNLOCK(intSave); if (ret != LOS_OK) { - SCHEDULER_UNLOCK(intSave); return ret; } - ret = OsTaskDeleteUnsafe(taskCB, OS_PRO_EXIT_OK, intSave); + ret = LOS_TaskDelete(taskID); if (ret != LOS_OK) { return ESRCH; } @@ -997,12 +995,13 @@ EXIT: void SysUserExitGroup(int status) { - OsTaskExitGroup((unsigned int)status); + (void)status; + OsProcessThreadGroupDestroy(); } void SysThreadExit(int status) { - OsTaskToExit(OsCurrTaskGet(), (unsigned int)status); + OsRunningTaskToExit(OsCurrTaskGet(), (unsigned int)status); } int SysFutex(const unsigned int *uAddr, unsigned int flags, int val, diff --git a/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp b/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp index be10618b..c973ca66 100644 --- a/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp +++ b/testsuites/unittest/process/basic/process/smoke/process_test_010.cpp @@ -55,33 +55,60 @@ static int ProcessTest001(void) return 0; } +static int Child(void) +{ + int count = TEST_COUNT; + int status = 0; + + while (count > 0) { + int ret = fork(); + if (ret == 0) { + ret = ProcessTest001(); + exit(ret); + } else if (ret > 0) { + int pid = ret; + ret = wait(&status); + status = WEXITSTATUS(status); + if (ret != pid) { + printf("wait child %d failed, is %u!\n", pid, ret); + exit(__LINE__); + } + if (status != 255) { // 255, assert that function Result is equal to this. + printf("wait child status is 255, but is %d, child is error line :%d \n", status, status); + exit(__LINE__); + } + } else { + printf("fork failed!\n"); + exit(__LINE__); + } + + count--; + } + + return 0; +} + static int Testcase(void) { int ret; int status; int pid; - int count = TEST_COUNT; int temp = GetCpuCount(); if (temp <= 1) { return 0; } - while (count > 0) { - ret = fork(); - if (ret == 0) { - ret = ProcessTest001(); - exit(10); // 10, exit args - } else if (ret > 0) { - pid = ret; - ret = wait(&status); - status = WEXITSTATUS(status); - ICUNIT_ASSERT_EQUAL(ret, pid, ret); - ICUNIT_ASSERT_EQUAL(status, 255, status); // 255, assert that function Result is equal to this. - } - - ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. - count--; + ret = fork(); + ICUNIT_ASSERT_WITHIN_EQUAL(ret, 0, 100000, ret); // 100000, assert that function Result is equal to this. + if (ret == 0) { + exit(Child()); + } else if (ret > 0) { + pid = ret; + ret = waitpid(pid, &status, NULL); + status = WEXITSTATUS(status); + ICUNIT_ASSERT_EQUAL(ret, pid, ret); + ICUNIT_ASSERT_EQUAL(status, 0, status); } return 0;