From f59cf2a3a630e6b1397139caba552e77caaaa297 Mon Sep 17 00:00:00 2001 From: dancer <2905764690@qq.com> Date: Fri, 19 Jan 2024 09:48:07 +0800 Subject: [PATCH] core --- .../kernel/base/core/los_process.c | 641 +++++++++--------- .../kernel/base/core/los_swtmr.c | 156 ++--- .../kernel/base/core/los_task.c | 413 ++++++----- .../kernel/base/core/los_tick.c | 14 +- 4 files changed, 641 insertions(+), 583 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/core/los_process.c b/src/kernel_liteos_a/kernel/base/core/los_process.c index 2ab53116..40fed7dd 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_process.c +++ b/src/kernel_liteos_a/kernel/base/core/los_process.c @@ -1,3 +1,12 @@ +/* +进程模块主文件 + 并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程, + 看起来像同时运行,实际上是线程不停切换 + 并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行 + 单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行) + 多核CPU线程间可以实现宏观和微观上的并行 + LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段 + */ /* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. @@ -59,46 +68,28 @@ #include "los_vm_phys.h" #include "los_vm_syscall.h" -/* - @brief 进程模块主文件 - - 并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,看起来像同时运行,实际上是线程不停切换 - 并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行 - 单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行) - 多核CPU线程间可以实现宏观和微观上的并行 - LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段 -*/ - -/* - bss 是英文 Block by Symbol 的简称。 - 通常用来存放程序中未初始化和初始化为 - 0的全局变量的一块内存区域,在程序载入时由内核清零。 -*/ - -LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL; //进程池数组 -LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess; //空闲状态下的进程链表 -LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList; //需要回收的进程列表 -LITE_OS_SEC_BSS UINT32 g_processMaxNum; //进程最大数量,默认64个 +LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL;//进程池数组 +LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;//空闲状态下的进程链表, +LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList;//需要收回的进程列表 +LITE_OS_SEC_BSS UINT32 g_processMaxNum;//进程最大数量,默认64个 #ifndef LOSCFG_PID_CONTAINER -LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL; //全局进程组,负责管理所有进程组 +LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;//全局进程组,负责管理所有的进程组 #define OS_ROOT_PGRP(processCB) (g_processGroup) #endif -// 将进程插入到空闲列表当中 STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB) { #ifdef LOSCFG_PID_CONTAINER OsPidContainerDestroy(processCB->container, processCB); #endif - UINT32 pid = processCB->processID; // 获取进程ID - (VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB)); // 进程描述符数据清0 - processCB->processID = pid; - processCB->processStatus = OS_PROCESS_FLAG_UNUSED; // 设置状态为未使用 - processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; - LOS_ListTailInsert(&g_freeProcess, &processCB->pendList); // 将进程插入到空闲列表当中 + UINT32 pid = processCB->processID;//获取进程ID + (VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB));//进程描述符数据清0 + processCB->processID = pid;//进程ID + processCB->processStatus = OS_PROCESS_FLAG_UNUSED;//设置为进程未使用 + processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;//timeID初始化值 + LOS_ListTailInsert(&g_freeProcess, &processCB->pendList);//进程节点挂入g_freeProcess以分配给后续进程使用 } -// 从进程当中删除任务 VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB) { LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB); @@ -108,7 +99,6 @@ VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB) OsTaskInsertToRecycleList(taskCB); } -// 进程当中添加任务 UINT32 OsProcessAddNewTask(UINTPTR processID, LosTaskCB *taskCB, SchedParam *param, UINT32 *numCount) { UINT32 intSave; @@ -151,8 +141,6 @@ UINT32 OsProcessAddNewTask(UINTPTR processID, LosTaskCB *taskCB, SchedParam *par SCHEDULER_UNLOCK(intSave); return LOS_OK; } - -// 创建进程组 /** * @brief 创建进程组 * @details @@ -163,18 +151,18 @@ UINT32 OsProcessAddNewTask(UINTPTR processID, LosTaskCB *taskCB, SchedParam *par */ ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB) { - ProcessGroup *pgroup = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessGroup)); + ProcessGroup *pgroup = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessGroup));//分配一个进程组 if (pgroup == NULL) { return NULL; } - pgroup->pgroupLeader = (UINTPTR)processCB; - LOS_ListInit(&pgroup->processList); - LOS_ListInit(&pgroup->exitProcessList); + pgroup->pgroupLeader = (UINTPTR)processCB;//指定进程负责人 + LOS_ListInit(&pgroup->processList);//初始化组员链表 + LOS_ListInit(&pgroup->exitProcessList);//初始化僵死进程链表 LOS_ListTailInsert(&pgroup->processList, &processCB->subordinateGroupList); processCB->pgroup = pgroup; - processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER; + processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER;//进程状态贴上当老大的标签 ProcessGroup *rootPGroup = OS_ROOT_PGRP(processCB); if (rootPGroup == NULL) { @@ -185,13 +173,12 @@ ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB) } return pgroup; } - -/*! 退出进程组,参数是进程地址和进程组地址的地址 */ +//退出进程组,参数是进程地址和进程组地址的地址 STATIC VOID ExitProcessGroup(LosProcessCB *processCB, ProcessGroup **pgroup) { LosProcessCB *pgroupCB = OS_GET_PGROUP_LEADER(processCB->pgroup); LOS_ListDelete(&processCB->subordinateGroupList);//从进程组进程链表上摘出去 - if (LOS_ListEmpty(&processCB->pgroup->processList) && LOS_ListEmpty(&processCB->pgroup->exitProcessList)) {//进程组进程链表和退出进程链表都为空时 + if (LOS_ListEmpty(&processCB->pgroup->processList) && LOS_ListEmpty(&processCB->pgroup->exitProcessList)) { #ifdef LOSCFG_PID_CONTAINER if (processCB->pgroup != OS_ROOT_PGRP(processCB)) { #endif @@ -201,16 +188,15 @@ STATIC VOID ExitProcessGroup(LosProcessCB *processCB, ProcessGroup **pgroup) } #endif pgroupCB->processStatus &= ~OS_PROCESS_FLAG_GROUP_LEADER; - if (OsProcessIsUnused(pgroupCB) && !(pgroupCB->processStatus & OS_PROCESS_FLAG_EXIT)) { - LOS_ListDelete(&pgroupCB->pendList); //进程从全局进程链表上摘除 - OsInsertPCBToFreeList(pgroupCB); //释放进程的资源,回到freelist再利用 + if (OsProcessIsUnused(pgroupCB) && !(pgroupCB->processStatus & OS_PROCESS_FLAG_EXIT)) {//组长进程时退出的标签 + LOS_ListDelete(&pgroupCB->pendList);//进程从全局进程链表上摘除 + OsInsertPCBToFreeList(pgroupCB);//释放进程的资源,回到freelist再利用 } } processCB->pgroup = NULL; } - -// 根据gid 寻找进程组 +/*! 通过指定组ID找到进程组 */ STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid) { ProcessGroup *pgroup = NULL; @@ -230,8 +216,7 @@ STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid) PRINT_INFO("%s failed! pgroup id = %u\n", __FUNCTION__, gid); return NULL; } - -// 发送信号去查清楚进程组状态 +/*! 给指定进程组发送信号 */ STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *pgroup, siginfo_t *info, INT32 permission) { INT32 ret, success, err; @@ -252,7 +237,6 @@ STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *pgroup, siginfo_t * return success ? LOS_OK : ret; } -// 向所有的进程发送信号 LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission) { INT32 ret, success, err; @@ -273,7 +257,6 @@ LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permissio return success ? LOS_OK : ret; } -// 向进程组发送信号 LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission) { ProcessGroup *pgroup = NULL; @@ -288,7 +271,6 @@ LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, IN return OsSendSignalToSpecifyProcessGroup(pgroup, info, permission); } -// 查找推出的进程 STATIC LosProcessCB *OsFindGroupExitProcess(ProcessGroup *pgroup, INT32 pid) { LosProcessCB *childCB = NULL; @@ -302,7 +284,6 @@ STATIC LosProcessCB *OsFindGroupExitProcess(ProcessGroup *pgroup, INT32 pid) return NULL; } -// 找到子进程 STATIC UINT32 OsFindChildProcess(const LosProcessCB *processCB, const LosProcessCB *wait) { LosProcessCB *childCB = NULL; @@ -328,23 +309,16 @@ STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, const return NULL; } -/// @brief 唤醒等待wakepid结束的task -/// @param taskCB -/// @param wakePID -/// @return +/*! 唤醒等待wakePID结束的任务 */ VOID OsWaitWakeTask(LosTaskCB *taskCB, UINTPTR wakePID) { - taskCB->waitID = wakePID; // waitID 置为唤醒 - taskCB->ops->wake(taskCB); // 唤醒taskCB + taskCB->waitID = wakePID; + taskCB->ops->wake(taskCB); #ifdef LOSCFG_KERNEL_SMP - LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_MpSchedule(OS_MP_CPU_ALL);//向所有cpu发送调度指令 #endif } -/// @brief 唤醒等待参数进程结束的任务 -/// @param head -/// @param processCB -/// @param anyList -/// @return +/*! 唤醒等待参数进程结束的任务 */ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList) { LOS_DL_LIST *list = head; @@ -352,12 +326,12 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr UINTPTR processID = 0; BOOL find = FALSE; - while (list->pstNext != head) { // 遍历 process->waitlist - taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list)); + while (list->pstNext != head) {//遍历等待链表 processCB->waitList + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));//一个一个来 if ((taskCB->waitFlag == OS_PROCESS_WAIT_PRO) && (taskCB->waitID == (UINTPTR)processCB)) { if (processID == 0) { processID = taskCB->waitID; - find = TRUE; + find = TRUE;//找到了 } else { processID = OS_INVALID_VALUE; } @@ -375,11 +349,7 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr return find; } - -/// @brief 检查父进程的等待任务并唤醒父进程去处理任务 -/// @param parentCB -/// @param processCB -/// @return +/*! 检查父进程的等待任务并唤醒父进程去处理等待任务 */ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB) { LOS_DL_LIST *head = &parentCB->waitList; @@ -387,7 +357,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro LosTaskCB *taskCB = NULL; BOOL findSpecified = FALSE; - if (LOS_ListEmpty(&parentCB->waitList)) { // 父进程当中是否有在等待子进程退出的任务 + if (LOS_ListEmpty(&parentCB->waitList)) {//父进程中是否有在等待子进程退出的任务? return;//没有就退出 } @@ -395,11 +365,11 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro if (findSpecified == TRUE) { /* No thread is waiting for any child process to finish */ if (LOS_ListEmpty(&parentCB->waitList)) {//没有线程正在等待任何子进程结束 - return; + return;//已经处理完了,注意在OsWaitWakeSpecifiedProcess中做了频繁的任务切换 } else if (!LOS_ListEmpty(&parentCB->childrenList)) { /* Other child processes exist, and other threads that are waiting * for the child to finish continue to wait - *////存在其他子进程,正在等待它们的子进程结束而将继续等待 + *///存在其他子进程,正在等待它们的子进程结束而将继续等待 return; } } @@ -441,9 +411,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro return; } -/// @brief 回收指定进程的资源 -/// @param processCB -/// @return +/*! 回收指定进程的资源 */ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) { #ifdef LOSCFG_KERNEL_VM @@ -452,10 +420,10 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) } #endif -#ifdef LOSCFG_SECURITY_CAPABILITY // 安全开关 +#ifdef LOSCFG_SECURITY_CAPABILITY//安全开关 if (processCB->user != NULL) { - (VOID)LOS_MemFree(m_aucSysMem1, processCB->user);// 删除用户 - processCB->user = NULL; // 重置指针为空 + (VOID)LOS_MemFree(m_aucSysMem1, processCB->user);//删除用户 + processCB->user = NULL;//重置指针为空 } #endif @@ -512,18 +480,14 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) processCB->resourceLimit = NULL; } } - -/// @brief 回收僵死状态的资源 -/// @param childCB -/// @param pgroup -/// @return +/*! 回收僵死状态进程的资源 */ STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **pgroup) { - ExitProcessGroup(childCB, pgroup); // 推出进程组 - LOS_ListDelete(&childCB->siblingList); ////从子孙链表上摘除 + ExitProcessGroup(childCB, pgroup);//退出进程组 + LOS_ListDelete(&childCB->siblingList);//从父亲大人的子孙链表上摘除 if (OsProcessIsDead(childCB)) { - OsDeleteTaskFromProcess(childCB->threadGroup);//去掉僵死标签 - childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES; + OsDeleteTaskFromProcess(childCB->threadGroup); + childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES;//去掉僵死标签 childCB->processStatus |= OS_PROCESS_FLAG_UNUSED;//贴上没使用标签,进程由进程池分配,进程退出后重新回到空闲进程池 } @@ -533,13 +497,10 @@ STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **pgroup } else if (OsProcessIsPGroupLeader(childCB)) { LOS_ListTailInsert(&g_processRecycleList, &childCB->pendList);//从尾部插入,意思就是组长尽量最后一个处理 } else { - OsInsertPCBToFreeList(childCB);//直接插到freeList中去,可用于重新分配了。 + OsInsertPCBToFreeList(childCB);//直接插到freeList中去,可用于重新分配了 } } - -/// @brief 进程退出时子进程由其父进程处理 -/// @param processCB -/// @return +/*! 当一个进程自然退出的时候,它的孩子进程由两位老祖宗收养 */ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB) { LosProcessCB *childCB = NULL; @@ -553,33 +514,30 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB) } #endif - if (!LOS_ListEmpty(&processCB->childrenList)) { - childHead = processCB->childrenList.pstNext; - LOS_ListDelete(&(processCB->childrenList)); - if (OsProcessIsUserMode(processCB)) { + if (!LOS_ListEmpty(&processCB->childrenList)) {//如果存在孩子进程 + childHead = processCB->childrenList.pstNext;//获取孩子链表 + LOS_ListDelete(&(processCB->childrenList));//清空自己的孩子链表 + if (OsProcessIsUserMode(processCB)) {//是用户态进程 parentCB = OS_PCB_FROM_PID(OS_USER_ROOT_PROCESS_ID); } else { parentCB = OsGetKernelInitProcess(); } - for (nextList = childHead; ;) { - childCB = OS_PCB_FROM_SIBLIST(nextList); + for (nextList = childHead; ;) {//遍历孩子链表 + childCB = OS_PCB_FROM_SIBLIST(nextList);//找到孩子的真身 childCB->parentProcess = parentCB; - nextList = nextList->pstNext; - if (nextList == childHead) { + nextList = nextList->pstNext;//找下一个孩子进程 + if (nextList == childHead) {//一圈下来,孩子们都磕完头了 break; } } - LOS_ListTailInsertList(&parentCB->childrenList, childHead); + LOS_ListTailInsertList(&parentCB->childrenList, childHead);//挂到老祖宗的孩子链表上 } return; } - -/// @brief 回收指定进程的已经退出(死亡)的子进程所占资源 -/// @param processCB -/// @return +/*! 回收指定进程的已经退出(死亡)的孩子进程所占资源 */ STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB) { LosProcessCB *childCB = NULL; @@ -591,34 +549,32 @@ STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB) (VOID)LOS_MemFree(m_aucSysMem1, pgroup); } } -/// @brief 一个进程的自然消亡过程,参数是当前运行的任务 -/// @param processCB -/// @param status -/// @return +/*! 一个进程的自然消亡过程,参数是当前运行的任务*/ VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status) { - OsChildProcessResourcesFree(processCB); + OsChildProcessResourcesFree(processCB);//释放孩子进程的资源 /* is a child process */ if (processCB->parentProcess != NULL) { LosProcessCB *parentCB = processCB->parentProcess; - LOS_ListDelete(&processCB->siblingList); - if (!OsProcessExitCodeSignalIsSet(processCB)) { - OsProcessExitCodeSet(processCB, status); + LOS_ListDelete(&processCB->siblingList);//将自己从兄弟链表中摘除,家人们,永别了! + if (!OsProcessExitCodeSignalIsSet(processCB)) {//是否设置了退出码? + OsProcessExitCodeSet(processCB, status);//将进程状态设为退出码 } - LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList); - LOS_ListDelete(&processCB->subordinateGroupList); - LOS_ListTailInsert(&processCB->pgroup->exitProcessList, &processCB->subordinateGroupList); + LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList);//挂到父进程的孩子消亡链表,家人中,永别的可不止我一个. + LOS_ListDelete(&processCB->subordinateGroupList);//和志同道合的朋友们永别了,注意家里可不一定是朋友的,所有各有链表. + LOS_ListTailInsert(&processCB->pgroup->exitProcessList, &processCB->subordinateGroupList);//挂到进程组消亡链表,朋友中,永别的可不止我一个. + + OsWaitCheckAndWakeParentProcess(parentCB, processCB);//检查父进程的等待任务链表并唤醒对应的任务,此处将会频繁的切到其他任务运行. - OsWaitCheckAndWakeParentProcess(parentCB, processCB); + OsDealAliveChildProcess(processCB);//孩子们要怎么处理,移交给(用户态和内核态)根进程 - OsDealAliveChildProcess(processCB); - processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES; + processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES;//贴上僵死进程的标签 #ifdef LOSCFG_KERNEL_VM (VOID)OsSendSigToProcess(parentCB, SIGCHLD, OS_KERNEL_KILL_PERMISSION); #endif - LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList); + LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);//将进程通过其阻塞节点挂入全局进程回收链表 return; } @@ -632,36 +588,33 @@ STATIC VOID SystemProcessEarlyInit(LosProcessCB *processCB) #ifdef LOSCFG_KERNEL_CONTAINER OsContainerInitSystemProcess(processCB); #endif - if (processCB == OsGetKernelInitProcess()) { - OsSetMainTaskProcess((UINTPTR)processCB); + if (processCB == OsGetKernelInitProcess()) {//2号进程 + OsSetMainTaskProcess((UINTPTR)processCB);//将内核根进程设为主任务所属进程 } } - -/// @brief 进程模块初始化,被编译放在代码段 .init -/// @param -/// @return +/*! 进程模块初始化,被编译放在代码段 .init 中*/ UINT32 OsProcessInit(VOID) { UINT32 index; UINT32 size; UINT32 ret; - g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT; + g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT;//默认支持64个进程 size = (g_processMaxNum + 1) * sizeof(LosProcessCB); - g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size); + g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);// 进程池,占用内核堆,内存池分配 if (g_processCBArray == NULL) { return LOS_NOK; } - (VOID)memset_s(g_processCBArray, size, 0, size); + (VOID)memset_s(g_processCBArray, size, 0, size);//安全方式重置清0 - LOS_ListInit(&g_freeProcess); - LOS_ListInit(&g_processRecycleList); + LOS_ListInit(&g_freeProcess);//进程空闲链表初始化,创建一个进程时从g_freeProcess中申请一个进程描述符使用 + LOS_ListInit(&g_processRecycleList);//进程回收链表初始化,回收完成后进入g_freeProcess等待再次被申请使用 - for (index = 0; index < g_processMaxNum; index++) { - g_processCBArray[index].processID = index; - g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED; - LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList); + for (index = 0; index < g_processMaxNum; index++) {//进程池循环创建 + g_processCBArray[index].processID = index;//进程ID[0-g_processMaxNum-1]赋值 + g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED;// 默认都是白纸一张,贴上未使用标签 + LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList);//注意g_freeProcess挂的是pendList节点,所以使用要通过OS_PCB_FROM_PENDLIST找到进程实体. } /* Default process to prevent thread PCB from being empty */ @@ -680,23 +633,22 @@ UINT32 OsProcessInit(VOID) #ifdef LOSCFG_KERNEL_PLIMITS OsProcLimiterSetInit(); #endif - SystemProcessEarlyInit(OsGetIdleProcess()); + SystemProcessEarlyInit(OsGetIdleProcess());//初始化 0,1,2号进程 SystemProcessEarlyInit(OsGetUserInitProcess()); SystemProcessEarlyInit(OsGetKernelInitProcess()); return LOS_OK; } -/// @brief 进程回收再利用过程 -/// @param -/// @return +/*! 进程回收再利用过程*/ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID) { UINT32 intSave; LosProcessCB *processCB = NULL; SCHEDULER_LOCK(intSave); - while (!LOS_ListEmpty(&g_processRecycleList)) { - processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList)); - if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) { + while (!LOS_ListEmpty(&g_processRecycleList)) {//循环任务回收链表,直到为空 + processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList));//找到回收链表中第一个进程实体 + //OS_PCB_FROM_PENDLIST 代表的是通过pendlist节点找到 PCB实体,因为g_processRecyleList上面挂的是pendlist节点位置 + if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) {//进程没有退出标签 break; } SCHEDULER_UNLOCK(intSave); @@ -704,27 +656,27 @@ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID) OsTaskCBRecycleToFree(); SCHEDULER_LOCK(intSave); - processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT; + processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT;//给进程撕掉退出标签,(可能进程并没有这个标签) #ifdef LOSCFG_KERNEL_VM LosVmSpace *space = NULL; - if (OsProcessIsUserMode(processCB)) { - space = processCB->vmSpace; + if (OsProcessIsUserMode(processCB)) {//进程是否是用户态进程 + space = processCB->vmSpace;//只有用户态的进程才需要释放虚拟内存空间 } processCB->vmSpace = NULL; #endif /* OS_PROCESS_FLAG_GROUP_LEADER: The lead process group cannot be recycled without destroying the PCB. * !OS_PROCESS_FLAG_UNUSED: Parent process does not reclaim child process resources. */ - LOS_ListDelete(&processCB->pendList); + LOS_ListDelete(&processCB->pendList);//将进程从进程链表上摘除 if (OsProcessIsPGroupLeader(processCB) || OsProcessIsDead(processCB)) { - LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList); + LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList);//将进程挂到进程回收链表上,因为组长不能走啊 } else { /* Clear the bottom 4 bits of process status */ - OsInsertPCBToFreeList(processCB); + OsInsertPCBToFreeList(processCB);//进程回到可分配池中,再分配利用 } #ifdef LOSCFG_KERNEL_VM SCHEDULER_UNLOCK(intSave); - (VOID)LOS_VmSpaceFree(space); + (VOID)LOS_VmSpaceFree(space);//释放用户态进程的虚拟内存空间,因为内核只有一个虚拟空间,因此不需要释放虚拟空间. SCHEDULER_LOCK(intSave); #endif } @@ -747,11 +699,11 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB) } #endif - OsProcessResourcesToFree(processCB); + OsProcessResourcesToFree(processCB);//释放进程所占用的资源 SCHEDULER_LOCK(intSave); if (processCB->parentProcess != NULL) { - LOS_ListDelete(&processCB->siblingList); + LOS_ListDelete(&processCB->siblingList);//将进程从兄弟链表中摘除 processCB->parentProcess = NULL; } @@ -759,8 +711,8 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB) ExitProcessGroup(processCB, &pgroup); } - processCB->processStatus &= ~OS_PROCESS_STATUS_INIT; - processCB->processStatus |= OS_PROCESS_FLAG_EXIT; + processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;//设置进程状态为非初始化 + processCB->processStatus |= OS_PROCESS_FLAG_EXIT;//设置进程状态为退出 LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList); SCHEDULER_UNLOCK(intSave); @@ -768,10 +720,8 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB) OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE); return; } -/// @brief /*! 设置进程的名字*/ -/// @param processCB -/// @param name -/// @return + +/*! 设置进程的名字*/ UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name) { errno_t errRet; @@ -803,31 +753,32 @@ UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name) } return LOS_OK; } + /*! 初始化PCB(进程控制块)*/ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name) { - processCB->processMode = mode; - processCB->processStatus = OS_PROCESS_STATUS_INIT; + processCB->processMode = mode;//用户态进程还是内核态进程 + processCB->processStatus = OS_PROCESS_STATUS_INIT;//进程初始状态 processCB->parentProcess = NULL; processCB->threadGroup = NULL; - processCB->umask = OS_PROCESS_DEFAULT_UMASK; + processCB->umask = OS_PROCESS_DEFAULT_UMASK;//掩码 processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; - LOS_ListInit(&processCB->threadSiblingList); - LOS_ListInit(&processCB->childrenList); - LOS_ListInit(&processCB->exitChildList); - LOS_ListInit(&(processCB->waitList)); + LOS_ListInit(&processCB->threadSiblingList);//初始化孩子任务/线程链表,上面挂的都是由此fork的孩子线程 见于 OsTaskCBInit LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList)); + LOS_ListInit(&processCB->childrenList);//初始化孩子进程链表,上面挂的都是由此fork的孩子进程 见于 OsCopyParent LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList); + LOS_ListInit(&processCB->exitChildList);//初始化记录退出孩子进程链表,上面挂的是哪些exit 见于 OsProcessNaturalExit LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList); + LOS_ListInit(&(processCB->waitList));//初始化等待任务链表 上面挂的是处于等待的 见于 OsWaitInsertWaitLIstInOrder LOS_ListHeadInsert(&processCB->waitList, &runTask->pendList); #ifdef LOSCFG_KERNEL_VM - if (OsProcessIsUserMode(processCB)) { - processCB->vmSpace = OsCreateUserVmSpace(); + if (OsProcessIsUserMode(processCB)) {//如果是用户态进程 + processCB->vmSpace = OsCreateUserVmSpace();//创建用户空间 if (processCB->vmSpace == NULL) { processCB->processStatus = OS_PROCESS_FLAG_UNUSED; return LOS_ENOMEM; } } else { - processCB->vmSpace = LOS_GetKVmSpace(); - } + processCB->vmSpace = LOS_GetKVmSpace();//从这里也可以看出,所有内核态进程是共享一个进程空间的 + }//在鸿蒙内核态进程只有kprocess 和 kidle 两个 #endif #ifdef LOSCFG_KERNEL_CPUP @@ -846,7 +797,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name) #endif #ifdef LOSCFG_SECURITY_CAPABILITY - OsInitCapability(processCB); + OsInitCapability(processCB);//初始化进程安全相关功能 #endif if (OsSetProcessName(processCB, name) != LOS_OK) { @@ -855,10 +806,10 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name) return LOS_OK; } - +//创建用户 #ifdef LOSCFG_SECURITY_CAPABILITY -STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size) -{ +STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)//参数size 表示组数量 +{//(size - 1) * sizeof(UINT32) 用于 user->groups[..],这种设计节约了内存,不造成不需要的浪费 User *user = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + (size - 1) * sizeof(UINT32)); if (user == NULL) { return NULL; @@ -868,11 +819,12 @@ STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size) user->effUserID = userID; user->gid = gid; user->effGid = gid; - user->groupNumber = size; - user->groups[0] = gid; + user->groupNumber = size;//用户组数量 + user->groups[0] = gid;//用户组列表,一个用户可以属于多个用户组 return user; } +/*! 检查参数群组ID是否在当前用户所属群组中*/ LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid) { UINT32 intSave; @@ -880,8 +832,8 @@ LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid) User *user = NULL; SCHEDULER_LOCK(intSave); - user = OsCurrUserGet(); - for (count = 0; count < user->groupNumber; count++) { + user = OsCurrUserGet();//当前进程所属用户 + for (count = 0; count < user->groupNumber; count++) {//循环对比 if (user->groups[count] == gid) { SCHEDULER_UNLOCK(intSave); return TRUE; @@ -893,6 +845,7 @@ LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid) } #endif +/*! 获取当前进程的用户ID*/ LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID) { #ifdef LOSCFG_SECURITY_CAPABILITY @@ -912,6 +865,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID) #endif } +/*! 获取当前进程的用户组ID*/ LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID) { #ifdef LOSCFG_SECURITY_CAPABILITY @@ -932,6 +886,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID) #endif } +/*! 进程创建初始化*/ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name) { UINT32 ret = OsInitPCB(processCB, flags, name); @@ -940,7 +895,7 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C } #ifdef LOSCFG_FS_VFS - processCB->files = alloc_files(); + processCB->files = alloc_files();//分配进程的文件的管理器 if (processCB->files == NULL) { ret = LOS_ENOMEM; goto EXIT; @@ -953,8 +908,8 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C goto EXIT; } -#ifdef LOSCFG_SECURITY_CAPABILITY - processCB->user = OsCreateUser(0, 0, 1); +#ifdef LOSCFG_SECURITY_CAPABILITY //用户安全宏 + processCB->user = OsCreateUser(0, 0, 1); //创建用户 if (processCB->user == NULL) { ret = LOS_ENOMEM; goto EXIT; @@ -962,7 +917,7 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C #endif #ifdef LOSCFG_KERNEL_PLIMITS - ret = OsPLimitsAddProcess(NULL, processCB); + ret = OsPLimitsAddProcess(NULL, processCB);//删除进程控制块,归还内存 if (ret != LOS_OK) { ret = LOS_ENOMEM; goto EXIT; @@ -974,7 +929,7 @@ EXIT: OsDeInitPCB(processCB); return ret; } - +/*! 创建2,0号进程,即内核态进程的老祖宗*/ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) { LosProcessCB *kerInitProcess = OsGetKernelInitProcess(); @@ -982,22 +937,22 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) if (ret != LOS_OK) { return ret; } - kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; + kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;//去掉初始化标签 LosProcessCB *idleProcess = OsGetIdleProcess(); - ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle"); + ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle");//创建内核态0号进程 if (ret != LOS_OK) { return ret; } idleProcess->parentProcess = kerInitProcess; - LOS_ListTailInsert(&kerInitProcess->childrenList, &idleProcess->siblingList); + LOS_ListTailInsert(&kerInitProcess->childrenList, &idleProcess->siblingList);//挂到内核态祖宗进程的子孙链接上 idleProcess->pgroup = kerInitProcess->pgroup; LOS_ListTailInsert(&kerInitProcess->pgroup->processList, &idleProcess->subordinateGroupList); #ifdef LOSCFG_SECURITY_CAPABILITY - idleProcess->user = kerInitProcess->user; + idleProcess->user = kerInitProcess->user;//共享用户 #endif #ifdef LOSCFG_FS_VFS - idleProcess->files = kerInitProcess->files; + idleProcess->files = kerInitProcess->files;//共享文件 #endif idleProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; @@ -1007,7 +962,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID) } return LOS_OK; } - +// 进程调度参数检查 INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *param) { if (param == NULL) { @@ -1040,24 +995,24 @@ INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *p STATIC INLINE INT32 ProcessSchedulerParamCheck(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *param) { - if (OS_PID_CHECK_INVALID(pid)) { + if (OS_PID_CHECK_INVALID(pid)) {//进程ID是否有效,默认 g_processMaxNum = 64 return LOS_EINVAL; } - if (which != LOS_PRIO_PROCESS) { + if (which != LOS_PRIO_PROCESS) {//进程标识 return LOS_EINVAL; } return OsSchedulerParamCheck(policy, FALSE, param); } -#ifdef LOSCFG_SECURITY_CAPABILITY +#ifdef LOSCFG_SECURITY_CAPABILITY//检查进程的安全许可证 STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 policy, UINT16 prio) { - LosProcessCB *runProcess = OsCurrProcessGet(); + LosProcessCB *runProcess = OsCurrProcessGet();//获得当前进程 /* always trust kernel process */ - if (!OsProcessIsUserMode(runProcess)) { + if (!OsProcessIsUserMode(runProcess)) {//进程必须在内核模式下,也就是说在内核模式下是安全的. return TRUE; } @@ -1073,7 +1028,7 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedPa return FALSE; } #endif - +// 设置进程调度计划 LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *schedParam) { SchedParam param = { 0 }; @@ -1086,8 +1041,8 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 poli } LosProcessCB *processCB = OS_PCB_FROM_PID(pid); - SCHEDULER_LOCK(intSave); - if (OsProcessIsInactive(processCB)) { + SCHEDULER_LOCK(intSave);//持有调度自旋锁,多CPU情况下调度期间需要原子处理 + if (OsProcessIsInactive(processCB)) {//进程未活动的处理 SCHEDULER_UNLOCK(intSave); return -LOS_ESRCH; } @@ -1127,20 +1082,20 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 poli needSched = taskCB->ops->schedParamModify(taskCB, ¶m); TO_SCHED: - SCHEDULER_UNLOCK(intSave); + SCHEDULER_UNLOCK(intSave);//还锁 - LOS_MpSchedule(OS_MP_CPU_ALL); + LOS_MpSchedule(OS_MP_CPU_ALL);//核间中断 if (needSched && OS_SCHEDULER_ACTIVE) { - LOS_Schedule(); + LOS_Schedule();//发起调度 } return LOS_OK; } - +// 设置指定进程的调度参数,包括优先级和调度策略 LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, const LosSchedParam *schedParam) { return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, policy, schedParam); } - +// 获得指定进程的调度策略 LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSchedParam *schedParam) { UINT32 intSave; @@ -1184,7 +1139,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSche } return LOS_OK; } - +// 接口封装 - 设置进程优先级 LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio) { INT32 ret; @@ -1204,7 +1159,7 @@ LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio) return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, (UINT16)policy, ¶m); } - +// 接口封装 - 获取进程优先级 which:标识进程,进程组,用户 LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) { UINT32 intSave; @@ -1237,12 +1192,15 @@ LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) SCHEDULER_UNLOCK(intSave); return param.basePrio; } - +// 接口封装 - 获取指定进程优先级 LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid) { return OsGetProcessPriority(LOS_PRIO_PROCESS, pid); } - +/*! +* 将任务挂入进程的waitList链表,表示这个任务在等待某个进程的退出 +* 当被等待进程退出时候会将自己挂到父进程的退出子进程链表和进程组的退出进程链表. +*/ STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *processCB) { LOS_DL_LIST *head = &processCB->waitList; @@ -1274,7 +1232,7 @@ STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *proces (VOID)runTask->ops->wait(runTask, list->pstNext, LOS_WAIT_FOREVER); return; } - +// 设置等待子进程退出方式方法 STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask, const LosProcessCB *processCB, LosProcessCB **childCB) { @@ -1295,7 +1253,7 @@ STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask, #endif /* Wait for the child process whose process number is pid. */ *childCB = OsFindExitChildProcess(processCB, waitProcess); - if (*childCB != NULL) { + if (*childCB != NULL) {//找到了,确实有一个已经退出的PID,注意一个进程退出时会挂到父进程的exitChildList上 return LOS_OK; } @@ -1303,7 +1261,7 @@ STATIC UINT32 WaitFindSpecifiedProcess(UINT32 pid, LosTaskCB *runTask, return LOS_ECHILD; } - runTask->waitFlag = OS_PROCESS_WAIT_PRO; + runTask->waitFlag = OS_PROCESS_WAIT_PRO;//设置当前任务的等待类型 runTask->waitID = (UINTPTR)waitProcess; return LOS_OK; } @@ -1322,18 +1280,18 @@ STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcess if (childCB != NULL) { goto WAIT_BACK; } - } else if (pid == 0) { + } else if (pid == 0) {//等待同一进程组中的任何子进程 /* Wait for any child process in the same process group */ childCB = OsFindGroupExitProcess(processCB->pgroup, OS_INVALID_VALUE); - if (childCB != NULL) { - goto WAIT_BACK; + if (childCB != NULL) {//找到了,确实有一个已经退出的PID + goto WAIT_BACK;//直接成功返回 } runTask->waitID = (UINTPTR)OS_GET_PGROUP_LEADER(processCB->pgroup); - runTask->waitFlag = OS_PROCESS_WAIT_GID; - } else if (pid == -1) { + runTask->waitFlag = OS_PROCESS_WAIT_GID;//设置当前任务的等待类型 + } else if (pid == -1) {//等待任意子进程 /* Wait for any child process */ childCB = OsFindExitChildProcess(processCB, NULL); - if (childCB != NULL) { + if (childCB != NULL) {//找到了,确实有一个已经退出的PID goto WAIT_BACK; } runTask->waitID = pid; @@ -1351,14 +1309,14 @@ STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcess } runTask->waitID = (UINTPTR)OS_GET_PGROUP_LEADER(pgroup); - runTask->waitFlag = OS_PROCESS_WAIT_GID; + runTask->waitFlag = OS_PROCESS_WAIT_GID;//设置当前任务的等待类型 } WAIT_BACK: *child = childCB; return LOS_OK; } - +// 等待回收孩子进程 STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info) { ProcessGroup *pgroup = NULL; @@ -1377,7 +1335,7 @@ STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intS SCHEDULER_UNLOCK(intSave); if (status != NULL) { - if (mode == OS_USER_MODE) { + if (mode == OS_USER_MODE) {//孩子为用户态进程 (VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32)); } else { *status = exitCode; @@ -1413,14 +1371,14 @@ STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intS (VOID)LOS_MemFree(m_aucSysMem1, pgroup); return pid; } - +// 检查要等待的孩子进程 STATIC UINT32 OsWaitChildProcessCheck(LosProcessCB *processCB, INT32 pid, LosProcessCB **childCB) -{ +{//当进程没有孩子且没有退出的孩子进程 if (LOS_ListEmpty(&(processCB->childrenList)) && LOS_ListEmpty(&(processCB->exitChildList))) { return LOS_ECHILD; } - return OsWaitSetFlag(processCB, pid, childCB); + return OsWaitSetFlag(processCB, pid, childCB);//设置等待子进程退出方式方法 } STATIC UINT32 OsWaitOptionsCheck(UINT32 options) @@ -1428,21 +1386,21 @@ STATIC UINT32 OsWaitOptionsCheck(UINT32 options) UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WUNTRACED | LOS_WAIT_WCONTINUED; flag = ~flag & options; - if (flag != 0) { - return LOS_EINVAL; + if (flag != 0) {//三种方式中一种都没有 + return LOS_EINVAL;//无效参数 } - if ((options & (LOS_WAIT_WCONTINUED | LOS_WAIT_WUNTRACED)) != 0) { - return LOS_EOPNOTSUPP; + if ((options & (LOS_WAIT_WCONTINUED | LOS_WAIT_WUNTRACED)) != 0) {//暂不支持这两种方式. + return LOS_EOPNOTSUPP;//不支持 } - if (OS_INT_ACTIVE) { - return LOS_EINTR; + if (OS_INT_ACTIVE) {//中断发生期间 + return LOS_EINTR;//中断提示 } return LOS_OK; } - +//等待子进程结束并回收子进程,返回已经终止的子进程的进程ID号,并清除僵死进程。 STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage) { (VOID)rusage; @@ -1453,13 +1411,13 @@ STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 LosProcessCB *processCB = OsCurrProcessGet(); LosTaskCB *runTask = OsCurrTaskGet(); SCHEDULER_LOCK(intSave); - ret = OsWaitChildProcessCheck(processCB, pid, &childCB); + ret = OsWaitChildProcessCheck(processCB, pid, &childCB);//先检查下看能不能找到参数要求的退出子进程 if (ret != LOS_OK) { pid = -ret; goto ERROR; } - if (childCB != NULL) { + if (childCB != NULL) {//找到了进程 #ifdef LOSCFG_PID_CONTAINER if (childCB == processCB) { SCHEDULER_UNLOCK(intSave); @@ -1471,21 +1429,22 @@ STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 #endif return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info); } - - if ((options & LOS_WAIT_WNOHANG) != 0) { - runTask->waitFlag = 0; - pid = 0; + //没有找到,看是否要返回还是去做个登记 + if ((options & LOS_WAIT_WNOHANG) != 0) {//有LOS_WAIT_WNOHANG标签 + runTask->waitFlag = 0;//等待标识置0 + pid = 0;//这里置0,是为了 return 0 goto ERROR; } - + //等待孩子进程退出 OsWaitInsertWaitListInOrder(runTask, processCB); + //发起调度的目的是为了让出CPU,让其他进程/任务运行 runTask->waitFlag = 0; if (runTask->waitID == OS_INVALID_VALUE) { - pid = -LOS_ECHILD; + pid = -LOS_ECHILD;//没有此子进程 goto ERROR; } - + //回收僵死进程 childCB = (LosProcessCB *)runTask->waitID; if (!OsProcessIsDead(childCB)) { pid = -LOS_ESRCH; @@ -1572,12 +1531,12 @@ UINT32 OsGetProcessGroupCB(UINT32 pid, UINTPTR *ppgroupLeader) STATIC UINT32 OsSetProcessGroupCheck(const LosProcessCB *processCB, LosProcessCB *pgroupCB) { - LosProcessCB *runProcessCB = OsCurrProcessGet(); + LosProcessCB *runProcessCB = OsCurrProcessGet();//拿到当前运行进程 - if (OsProcessIsInactive(processCB)) { + if (OsProcessIsInactive(processCB)) {//进程是否活动 return LOS_ESRCH; } - + //参数进程不在用户态或者组长不在用户态 #ifdef LOSCFG_PID_CONTAINER if ((processCB->processID == OS_USER_ROOT_PROCESS_ID) || OS_PROCESS_CONTAINER_CHECK(processCB, runProcessCB)) { return LOS_EPERM; @@ -1694,12 +1653,12 @@ EXIT: SCHEDULER_UNLOCK(intSave); return gid; } - +// 获取当前进程的组ID LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID) { return LOS_GetProcessGroupID(OsCurrProcessGet()->processID); } - +// 为用户态任务分配栈空间 #ifdef LOSCFG_KERNEL_VM STATIC LosProcessCB *OsGetFreePCB(VOID) { @@ -1723,19 +1682,19 @@ STATIC LosProcessCB *OsGetFreePCB(VOID) STATIC VOID *OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size) { LosVmMapRegion *region = NULL; - UINT32 stackSize = ALIGN(OS_USER_TASK_STACK_SIZE, PAGE_SIZE); - + UINT32 stackSize = ALIGN(OS_USER_TASK_STACK_SIZE, PAGE_SIZE);//1M栈空间 按页对齐 + //线性区分配虚拟内存 region = LOS_RegionAlloc(processCB->vmSpace, 0, stackSize, VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | - VM_MAP_REGION_FLAG_PERM_WRITE, 0); + VM_MAP_REGION_FLAG_PERM_WRITE, 0);//可使用可读可写区 if (region == NULL) { return NULL; } - LOS_SetRegionTypeAnon(region); - region->regionFlags |= VM_MAP_REGION_FLAG_STACK; + LOS_SetRegionTypeAnon(region);//匿名映射 + region->regionFlags |= VM_MAP_REGION_FLAG_STACK;//标记该线性区为栈区 - *size = stackSize; + *size = stackSize;//记录栈大小 return (VOID *)(UINTPTR)region->range.base; } @@ -1770,6 +1729,14 @@ LITE_OS_SEC_TEXT LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, U return oldSpace; } +/** + * @brief 进程的回收再利用,被LOS_DoExecveFile调用 + * @param processCB + * @param name + * @param oldSpace + * @param oldFiles + * @return LITE_OS_SEC_TEXT + */ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldSpace, UINTPTR oldFiles) { @@ -1819,7 +1786,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR return LOS_OK; } - +// 执行用户态任务, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小 LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize) { UINT32 intSave; @@ -1828,29 +1795,30 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT return LOS_NOK; } - if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) { + if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) {//对齐 return LOS_NOK; } - - if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) { + //注意 sp此时指向栈底,栈底地址要大于栈顶 + if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) {//参数检查 return LOS_NOK; } - LosTaskCB *taskCB = OsCurrTaskGet(); - - SCHEDULER_LOCK(intSave); - taskCB->userMapBase = mapBase; - taskCB->userMapSize = mapSize; - taskCB->taskEntry = (TSK_ENTRY_FUNC)entry; + LosTaskCB *taskCB = OsCurrTaskGet();//获取当前任务 + SCHEDULER_LOCK(intSave);//拿自旋锁 + taskCB->userMapBase = mapBase;//用户态栈顶位置 + taskCB->userMapSize = mapSize;//用户态栈 + taskCB->taskEntry = (TSK_ENTRY_FUNC)entry;//任务的入口函数 + //初始化内核态栈 TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize, (VOID *)taskCB->topOfStack, FALSE); - OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp); - SCHEDULER_UNLOCK(intSave); + OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp);//初始化用户栈,将内核栈中上下文的 context->R[0] = sp ,context->sp = sp + //这样做的目的是将用户栈SP保存到内核栈中, + SCHEDULER_UNLOCK(intSave);//解锁 return LOS_OK; } #endif - +// 用户进程开始初始化 STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param) { UINT32 intSave; @@ -1871,7 +1839,7 @@ STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S * processCB->processStatus &= ~OS_PROCESS_STATUS_INIT; SCHEDULER_UNLOCK(intSave); - ret = LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST); + ret = LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST);//调度器:设置为抢占式调度和最低任务优先级(31级) if (ret != LOS_OK) { PRINT_ERR("User init process set scheduler failed! ERROR:%d \n", ret); goto EXIT; @@ -1990,7 +1958,7 @@ ERROR: OsDeInitPCB(processCB); return ret; } - +// 拷贝用户信息 直接用memcpy_s STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB) { #ifdef LOSCFG_SECURITY_CAPABILITY @@ -2005,6 +1973,7 @@ STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB) return LOS_OK; } +//拷贝一个Task过程 STATIC VOID GetCopyTaskParam(LosProcessCB *childProcessCB, UINTPTR entry, UINT32 size, TSK_INIT_PARAM_S *taskParam, SchedParam *param) { @@ -2012,15 +1981,15 @@ STATIC VOID GetCopyTaskParam(LosProcessCB *childProcessCB, UINTPTR entry, UINT32 LosTaskCB *runTask = OsCurrTaskGet(); SCHEDULER_LOCK(intSave); - if (OsProcessIsUserMode(childProcessCB)) { - taskParam->pfnTaskEntry = runTask->taskEntry; - taskParam->uwStackSize = runTask->stackSize; - taskParam->userParam.userArea = runTask->userArea; - taskParam->userParam.userMapBase = runTask->userMapBase; - taskParam->userParam.userMapSize = runTask->userMapSize; - } else { - taskParam->pfnTaskEntry = (TSK_ENTRY_FUNC)entry; - taskParam->uwStackSize = size; + if (OsProcessIsUserMode(childProcessCB)) {//用户态进程 + taskParam->pfnTaskEntry = runTask->taskEntry;//拷贝当前任务入口地址 + taskParam->uwStackSize = runTask->stackSize;//栈空间大小 + taskParam->userParam.userArea = runTask->userArea;//用户态栈区栈顶位置 + taskParam->userParam.userMapBase = runTask->userMapBase;//用户态栈底 + taskParam->userParam.userMapSize = runTask->userMapSize;//用户态栈大小 + } else {//注意内核态进程创建任务的入口由外界指定,例如 OsCreateIdleProcess 指定了OsIdleTask + taskParam->pfnTaskEntry = (TSK_ENTRY_FUNC)entry;//参数(sp)为内核态入口地址 + taskParam->uwStackSize = size;//参数(size)为内核态栈大小 } if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { taskParam->uwResved = LOS_TASK_ATTR_JOINABLE; @@ -2056,25 +2025,25 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR } LosTaskCB *childTaskCB = childProcessCB->threadGroup; - childTaskCB->taskStatus = runTask->taskStatus; + childTaskCB->taskStatus = runTask->taskStatus;//任务状态先同步,注意这里是赋值操作. ...01101001 childTaskCB->ops->schedParamModify(childTaskCB, ¶m); - if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) { - childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING; - } else { - if (OS_SCHEDULER_ACTIVE) { + if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//因只能有一个运行的task,所以如果一样要改4号位 + childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING;//将四号位清0 ,变成 ...01100001 + } else {//非运行状态下会发生什么? + if (OS_SCHEDULER_ACTIVE) {//克隆线程发生错误未运行 LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus); } - childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED; + childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED;//干净的Task } - if (OsProcessIsUserMode(childProcessCB)) { + if (OsProcessIsUserMode(childProcessCB)) {//是否是用户进程 SCHEDULER_LOCK(intSave); OsUserCloneParentStack(childTaskCB->stackPointer, entry, runTask->topOfStack, runTask->stackSize); SCHEDULER_UNLOCK(intSave); } return LOS_OK; } - +//拷贝父亲大人的遗传基因信息 STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) { UINT32 intSave; @@ -2082,13 +2051,14 @@ STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProces SCHEDULER_LOCK(intSave); if (childProcessCB->parentProcess == NULL) { - if (flags & CLONE_PARENT) { + if (flags & CLONE_PARENT) { //这里指明 childProcessCB 和 runProcessCB 有同一个父亲,是兄弟关系 parentProcessCB = runProcessCB->parentProcess; } else { - parentProcessCB = runProcessCB; + parentProcessCB = runProcessCB;//指认父亲,这个赋值代表从此是你儿了 } childProcessCB->parentProcess = parentProcessCB; - LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList); + LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);//通过我的兄弟姐妹节点,挂到父亲的孩子链表上,于我而言,父亲的这个链表上挂的都是我的兄弟姐妹 + //不会被排序,老大,老二,老三 老天爷指定了。 } if (childProcessCB->pgroup == NULL) { @@ -2098,20 +2068,20 @@ STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProces SCHEDULER_UNLOCK(intSave); return LOS_OK; } - +//拷贝虚拟空间 STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) { status_t status; UINT32 intSave; - if (!OsProcessIsUserMode(childProcessCB)) { + if (!OsProcessIsUserMode(childProcessCB)) {//不是用户模式,直接返回,什么意思?内核虚拟空间只有一个,无需COPY !!! return LOS_OK; } - if (flags & CLONE_VM) { + if (flags & CLONE_VM) {//贴有虚拟内存的标签 SCHEDULER_LOCK(intSave); - childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb; - childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb; + childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb;//TTB虚拟地址基地址,即L1表存放位置,virtTtb是个指针,进程的虚拟空间是指定的范围的 + childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb;//TTB物理地址基地址,physTtb是个值,取决于运行时映射到物理内存的具体哪个位置. SCHEDULER_UNLOCK(intSave); return LOS_OK; } @@ -2122,7 +2092,7 @@ STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB } return LOS_OK; } - +// 拷贝进程文件描述符(proc_fd)信息 STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) { #ifdef LOSCFG_FS_VFS @@ -2152,7 +2122,7 @@ STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessC #endif #endif - childProcessCB->consoleID = runProcessCB->consoleID; + childProcessCB->consoleID = runProcessCB->consoleID;//控制台也是文件 childProcessCB->umask = runProcessCB->umask; return LOS_OK; } @@ -2160,16 +2130,16 @@ STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessC STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINTPTR sp, UINT32 size) { UINT32 ret; - LosProcessCB *run = OsCurrProcessGet(); + LosProcessCB *run = OsCurrProcessGet();//获取当前进程 - ret = OsCopyParent(flags, child, run); + ret = OsCopyParent(flags, child, run);//拷贝父亲大人的基因信息 if (ret != LOS_OK) { return ret; } - return OsCopyTask(flags, child, name, sp, size); + return OsCopyTask(flags, child, name, sp, size);//拷贝任务,设置任务入口函数,栈大小 } - +//设置进程组和加入进程调度就绪队列 STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *run) { UINT32 intSave; @@ -2193,7 +2163,7 @@ STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB * (VOID)LOS_MemFree(m_aucSysMem1, pgroup); return LOS_OK; } - +// 拷贝进程资源 STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProcessCB *run) { UINT32 ret; @@ -2203,49 +2173,49 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce return ret; } - ret = OsCopyMM(flags, child, run); + ret = OsCopyMM(flags, child, run);//拷贝虚拟空间 if (ret != LOS_OK) { return ret; } - ret = OsCopyFile(flags, child, run); + ret = OsCopyFile(flags, child, run);//拷贝文件信息 if (ret != LOS_OK) { return ret; } #ifdef LOSCFG_KERNEL_LITEIPC - if (run->ipcInfo != NULL) { - child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo)); - if (child->ipcInfo == NULL) { - return LOS_ENOMEM; + if (run->ipcInfo != NULL) {//重新初始化IPC池 + child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo));//@note_good 将沿用用户态空间地址(即线性区地址) + if (child->ipcInfo == NULL) {//因为整个进程虚拟空间都是拷贝的,ipc的用户态虚拟地址当然可以拷贝,但因进程不同了,所以需要重新申请ipc池和重新 + return LOS_ENOMEM;//映射池中两个地址. } } #endif #ifdef LOSCFG_SECURITY_CAPABILITY - OsCopyCapability(run, child); + OsCopyCapability(run, child);//拷贝安全能力 #endif return LOS_OK; } - +// 拷贝进程 STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size) { UINT32 ret, processID; - LosProcessCB *run = OsCurrProcessGet(); // 获取当前进程 + LosProcessCB *run = OsCurrProcessGet();//获取当前进程 - LosProcessCB *child = OsGetFreePCB(); // 指向新的进程块 + LosProcessCB *child = OsGetFreePCB();//从进程池中申请一个进程控制块,鸿蒙进程池默认64 if (child == NULL) { return -LOS_EAGAIN; } - processID = child->processID; // 进程ID(cpid) + processID = child->processID; - ret = OsInitPCB(child, run->processMode, name); // 初始化PCB + ret = OsInitPCB(child, run->processMode, name); if (ret != LOS_OK) { goto ERROR_INIT; } #ifdef LOSCFG_KERNEL_CONTAINER - ret = OsCopyContainers(flags, child, run, &processID); + ret = OsCopyContainers(flags, child, run, &processID); if (ret != LOS_OK) { goto ERROR_INIT; } @@ -2258,24 +2228,24 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si #endif #endif - ret = OsForkInitPCB(flags, child, name, sp, size); + ret = OsForkInitPCB(flags, child, name, sp, size);//初始化进程控制块 if (ret != LOS_OK) { goto ERROR_INIT; } - ret = OsCopyProcessResources(flags, child, run); //.. 拷贝进程的资源 + ret = OsCopyProcessResources(flags, child, run);//拷贝进程的资源,包括虚拟空间,文件,安全,IPC == if (ret != LOS_OK) { goto ERROR_TASK; } - ret = OsChildSetProcessGroupAndSched(child, run); // 设置进程组和加入进程调度就绪队列 + ret = OsChildSetProcessGroupAndSched(child, run);//设置进程组和加入进程调度就绪队列 if (ret != LOS_OK) { goto ERROR_TASK; } - LOS_MpSchedule(OS_MP_CPU_ALL); // 给CPU发送接收调度的 - if (OS_SCHEDULER_ACTIVE) { - LOS_Schedule(); + LOS_MpSchedule(OS_MP_CPU_ALL);//给各CPU发送准备接受调度信号 + if (OS_SCHEDULER_ACTIVE) {//当前CPU core处于活动状态 + LOS_Schedule();// 申请调度 } return processID; @@ -2286,6 +2256,7 @@ ERROR_INIT: OsDeInitPCB(child); return -ret; } + /*! * @brief OsClone 进程克隆 * @@ -2302,7 +2273,6 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) #ifdef LOSCFG_KERNEL_CONTAINER #ifdef LOSCFG_PID_CONTAINER cloneFlag |= CLONE_NEWPID; - // 指向当前进程控制块的指针 LosProcessCB *curr = OsCurrProcessGet(); if (((flags & CLONE_NEWPID) != 0) && ((flags & (CLONE_PARENT | CLONE_THREAD)) != 0)) { return -LOS_EINVAL; @@ -2345,7 +2315,7 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) return OsCopyProcess(cloneFlag & flags, NULL, sp, size); } - +//著名的 fork 函数 记得前往 https://gitee.com/weharmony/kernel_liteos_a_note fork一下 :) LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize) { UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES; @@ -2355,7 +2325,7 @@ LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_ } flags |= CLONE_FILES; - return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize); + return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize);//拷贝一个进程 } #else LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) @@ -2364,6 +2334,14 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) } #endif +/*! + * @brief LOS_Exit + * 进程退出 + * @param status + * @return + * + * @see + */ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) { UINT32 intSave; @@ -2373,7 +2351,7 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) /* The exit of a kernel - state process must be kernel - state and all threads must actively exit */ LosProcessCB *processCB = OsCurrProcessGet(); SCHEDULER_LOCK(intSave); - if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) { + if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) {//内核态下进程的退出方式,必须是所有的任务都退出了 SCHEDULER_UNLOCK(intSave); PRINT_ERR("Kernel-state processes with multiple threads are not allowed to exit directly\n"); return; @@ -2384,24 +2362,33 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK); } +/*! + * @brief LOS_GetUsedPIDList + * 获取使用中的进程列表 + * @param pidList + * @param pidMaxNum + * @return + * + * @see + */ LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum) { LosProcessCB *pcb = NULL; INT32 num = 0; UINT32 intSave; UINT32 pid = 1; - // TSK_ENTRY_FUNC s + if (pidList == NULL) { return 0; } SCHEDULER_LOCK(intSave); - while (OsProcessIDUserCheckInvalid(pid) == false) { + while (OsProcessIDUserCheckInvalid(pid) == false) {//遍历进程池 pcb = OS_PCB_FROM_PID(pid); pid++; - if (OsProcessIsUnused(pcb)) { + if (OsProcessIsUnused(pcb)) {//未使用的不算 continue; } - pidList[num] = pcb->processID; + pidList[num] = pcb->processID;//由参数带走 num++; if (num >= pidMaxNum) { break; @@ -2427,12 +2414,12 @@ LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid) return files->fdt; } #endif - +// 获取当前进程的进程ID LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID) { return OsCurrProcessGet()->processID; } - +// 按指定状态退出指定进程 #ifdef LOSCFG_KERNEL_VM STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB) { @@ -2505,12 +2492,12 @@ LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID) #endif return; } - +// 获取系统支持的最大进程数目 LITE_OS_SEC_TEXT UINT32 LOS_GetSystemProcessMaximum(VOID) { return g_processMaxNum; } - +// 获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的 LITE_OS_SEC_TEXT LosProcessCB *OsGetUserInitProcess(VOID) { return &g_processCBArray[OS_USER_ROOT_PROCESS_ID]; @@ -2520,7 +2507,7 @@ LITE_OS_SEC_TEXT LosProcessCB *OsGetKernelInitProcess(VOID) { return &g_processCBArray[OS_KERNEL_ROOT_PROCESS_ID]; } - +// 获取空闲进程,0号进程为空闲进程,该进程不干活,专给CPU休息的。 LITE_OS_SEC_TEXT LosProcessCB *OsGetIdleProcess(VOID) { return &g_processCBArray[OS_KERNEL_IDLE_PROCESS_ID]; diff --git a/src/kernel_liteos_a/kernel/base/core/los_swtmr.c b/src/kernel_liteos_a/kernel/base/core/los_swtmr.c index 893cabd0..b648553c 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_swtmr.c +++ b/src/kernel_liteos_a/kernel/base/core/los_swtmr.c @@ -28,12 +28,7 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/*! -* @file los_swtmr.c -* @brief 软定时器主文件 -* @details -* @attention @verbatim -基本概念 +/*基本概念 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick数后,会触发用户自定义的回调函数。 硬件定时器受硬件的限制,数量上不足以满足用户的实际需求。因此为了满足用户需求,提供更多的定时器, 软件定时器功能,支持如下特性: @@ -88,9 +83,7 @@ 系统可配置的软件定时器个数是指:整个系统可使用的软件定时器总个数,并非用户可使用的软件定时器个数。 例如:系统多占用一个软件定时器,那么用户能使用的软件定时器资源就会减少一个。 创建单次不自删除属性的定时器,用户需要自行调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 - 软件定时器的定时精度与系统Tick时钟的周期有关。 - @endverbatim -*/ + 软件定时器的定时精度与系统Tick时钟的周期有关。*/ #include "los_swtmr_pri.h" #include "los_init.h" #include "los_process_pri.h" @@ -113,14 +106,14 @@ LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Han LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */ /* spinlock for swtmr module, only available on SMP mode */ -LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin); -#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state)) -#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state)) +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);//初始化软件钟自旋锁,只有SMP情况才需要,只要是自旋锁都是由于CPU多核的同步 +#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))//持有软时钟自旋锁 +#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))//释放软时钟自旋锁 typedef struct { SortLinkAttribute swtmrSortLink; - LosTaskCB *swtmrTask; /* software timer task id */ - LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id */ + LosTaskCB *swtmrTask; /* software timer task id *///定时器任务ID + LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id *///定时器超时队列 } SwtmrRunqueue; STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM]; @@ -316,7 +309,7 @@ STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq) LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave); return; } - +//软时钟的入口函数,拥有任务的最高优先级0级 STATIC VOID SwtmrTask(VOID) { SwtmrHandlerItem swtmrHandle; @@ -325,7 +318,7 @@ STATIC VOID SwtmrTask(VOID) SwtmrRunqueue *srq = &g_swtmrRunqueue[ArchCurrCpuid()]; LOS_DL_LIST *head = &srq->swtmrHandlerQueue; - for (;;) { + for (;;) {//死循环获取队列item,一直读干净为止 waitTime = OsSortLinkGetNextExpireTime(OsGetCurrSchedTimeCycle(), &srq->swtmrSortLink); if (waitTime != 0) { SCHEDULER_LOCK(intSave); @@ -341,29 +334,30 @@ STATIC VOID SwtmrTask(VOID) LOS_ListDelete(&swtmrHandlePtr->node); (VOID)memcpy_s(&swtmrHandle, sizeof(SwtmrHandlerItem), swtmrHandlePtr, sizeof(SwtmrHandlerItem)); - (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr); + (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);//静态释放内存,注意在鸿蒙内核只有软时钟注册用到了静态内存 SwtmrHandler(&swtmrHandle); } } } +//创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务 STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID) { UINT32 ret; TSK_INIT_PARAM_S swtmrTask; - (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask; - swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - swtmrTask.pcName = "Swt_Task"; - swtmrTask.usTaskPrio = 0; - swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED; + (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0 + swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;//入口函数 + swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16k默认内核任务栈 + swtmrTask.pcName = "Swt_Task";//任务名称 + swtmrTask.usTaskPrio = 0;// + swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;//分离模式 #ifdef LOSCFG_KERNEL_SMP - swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid); + swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);//交给当前CPU执行这个任务 #endif - ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask); + ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask);//创建任务并申请调度 if (ret == LOS_OK) { - OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; + OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//告知这是个任务系统 } return ret; @@ -381,16 +375,16 @@ BOOL OsIsSwtmrTask(const LosTaskCB *taskCB) } return FALSE; } - +//回收指定进程的软时钟 LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINTPTR ownerID) { - for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) { + for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {//一个进程往往会有多个定时器 if (g_swtmrCBArray[index].uwOwnerPid == ownerID) { - LOS_SwtmrDelete(index); + LOS_SwtmrDelete(index);//删除定时器 } } } - +//软时钟初始化,注意函数在多CPU情况下会执行多次 STATIC UINT32 SwtmrBaseInit(VOID) { UINT32 ret; @@ -400,15 +394,15 @@ STATIC UINT32 SwtmrBaseInit(VOID) return LOS_ERRNO_SWTMR_NO_MEMORY; } - (VOID)memset_s(swtmr, size, 0, size); - g_swtmrCBArray = swtmr; - LOS_ListInit(&g_swtmrFreeList); + (VOID)memset_s(swtmr, size, 0, size);//清0 + g_swtmrCBArray = swtmr;//软时钟 + LOS_ListInit(&g_swtmrFreeList);//初始化空间链表 for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { - swtmr->usTimerID = index; - LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); + swtmr->usTimerID = index;//按顺序赋值 + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表 } - - size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE); + //想要用静态内存池管理,就必须要使用LOS_MEMBOX_SIZE来计算申请列表的内存大小,因为需要点前缀内存承载头部信息 + size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//规划一片内存区域作为软时钟处理函数的静态内存池 g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, size); /* system resident resource */ if (g_swtmrHandlerPool == NULL) { return LOS_ERRNO_SWTMR_NO_MEMORY; @@ -536,14 +530,14 @@ STATIC UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid) if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || (swtmr->ucMode == LOS_SWTMR_MODE_OPP) || - (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) { - ticks = swtmr->uwExpiry; + (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {//如果是一次性的定时器 + ticks = swtmr->uwExpiry;//获取定时间隔 } else { ticks = swtmr->uwInterval; } - swtmr->ucState = OS_SWTMR_STATUS_TICKING; + swtmr->ucState = OS_SWTMR_STATUS_TICKING;//获取周期性定时器时间间隔 - UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK; + UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK;//计数状态 UINT64 responseTime = swtmr->startTime + period; UINT64 currTime = OsGetCurrSchedTimeCycle(); if (responseTime < currTime) { @@ -584,7 +578,7 @@ STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr) STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr) { /* insert to free list */ - LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//直接插入空闲链表中,回收再利用 swtmr->ucState = OS_SWTMR_STATUS_UNUSED; swtmr->uwOwnerPid = OS_INVALID_VALUE; @@ -703,7 +697,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr) } return (UINT32)time; } - +//创建定时器,设置定时器的定时时长、定时模式、回调函数、并返回定时器ID LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, @@ -732,7 +726,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, } SWTMR_LOCK(intSave); - if (LOS_ListEmpty(&g_swtmrFreeList)) { + if (LOS_ListEmpty(&g_swtmrFreeList)) {//空闲列表不能为空 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_MAXSIZE; } @@ -743,19 +737,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, SWTMR_UNLOCK(intSave); swtmr->uwOwnerPid = (UINTPTR)OsCurrProcessGet(); - swtmr->pfnHandler = handler; - swtmr->ucMode = mode; + swtmr->pfnHandler = handler;//时间到了的回调函数 + swtmr->ucMode = mode;//定时模式 swtmr->uwOverrun = 0; - swtmr->uwInterval = interval; - swtmr->uwExpiry = interval; - swtmr->uwArg = arg; - swtmr->ucState = OS_SWTMR_STATUS_CREATED; + swtmr->uwInterval = interval;//周期性超时间隔 + swtmr->uwExpiry = interval;//一次性超时间隔 + swtmr->uwArg = arg;//回调函数的参数 + swtmr->ucState = OS_SWTMR_STATUS_CREATED;//已创建状态 SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME); *swtmrID = swtmr->usTimerID; OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr); return LOS_OK; } - +//接口函数 启动定时器 参数定时任务ID LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) { SWTMR_CTRL_S *swtmr = NULL; @@ -767,27 +761,27 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) return LOS_ERRNO_SWTMR_ID_INVALID; } - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - swtmr = g_swtmrCBArray + swtmrCBID; + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 SWTMR_LOCK(intSave); - if (swtmr->usTimerID != swtmrID) { + if (swtmr->usTimerID != swtmrID) {//ID必须一样 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } - switch (swtmr->ucState) { + switch (swtmr->ucState) {//判断定时器状态 case OS_SWTMR_STATUS_UNUSED: ret = LOS_ERRNO_SWTMR_NOT_CREATED; break; - /* + /*如果定时器的状态为启动中,应先停止定时器再重新启动 * If the status of swtmr is timing, it should stop the swtmr first, * then start the swtmr again. */ - case OS_SWTMR_STATUS_TICKING: - SwtmrStop(swtmr); + case OS_SWTMR_STATUS_TICKING://正在计数的定时器 + SwtmrStop(swtmr);//先停止定时器,注意这里没有break;在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CRWEATED接下来就是执行启动了 /* fall-through */ - case OS_SWTMR_STATUS_CREATED: + case OS_SWTMR_STATUS_CREATED://已经创建好了 SwtmrStart(swtmr); break; default: @@ -799,7 +793,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr); return ret; } - +//接口函数 停止计时器 参加定时任务ID LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) { SWTMR_CTRL_S *swtmr = NULL; @@ -811,24 +805,24 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) return LOS_ERRNO_SWTMR_ID_INVALID; } - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - swtmr = g_swtmrCBArray + swtmrCBID; + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 SWTMR_LOCK(intSave); - if (swtmr->usTimerID != swtmrID) { + if (swtmr->usTimerID != swtmrID) {//ID必须一样 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } - switch (swtmr->ucState) { + switch (swtmr->ucState) {//判断定时器状态 case OS_SWTMR_STATUS_UNUSED: - ret = LOS_ERRNO_SWTMR_NOT_CREATED; + ret = LOS_ERRNO_SWTMR_NOT_CREATED;//返回没有创建 break; case OS_SWTMR_STATUS_CREATED: - ret = LOS_ERRNO_SWTMR_NOT_STARTED; + ret = LOS_ERRNO_SWTMR_NOT_STARTED;//返回没有开始 break; - case OS_SWTMR_STATUS_TICKING: - SwtmrStop(swtmr); + case OS_SWTMR_STATUS_TICKING://正在计数 + SwtmrStop(swtmr);//执行正在停止计时器操作 break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; @@ -839,7 +833,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr); return ret; } - +//接口函数 获得软件定时器剩余Tick数 通过 *tick 带走 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) { SWTMR_CTRL_S *swtmr = NULL; @@ -855,11 +849,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) return LOS_ERRNO_SWTMR_TICK_PTR_NULL; } - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - swtmr = g_swtmrCBArray + swtmrCBID; + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 SWTMR_LOCK(intSave); - if (swtmr->usTimerID != swtmrID) { + if (swtmr->usTimerID != swtmrID) {//ID必须一样 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } @@ -870,8 +864,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) case OS_SWTMR_STATUS_CREATED: ret = LOS_ERRNO_SWTMR_NOT_STARTED; break; - case OS_SWTMR_STATUS_TICKING: - *tick = OsSwtmrTimeGet(swtmr); + case OS_SWTMR_STATUS_TICKING://正在计数的定时器 + *tick = OsSwtmrTimeGet(swtmr);//获取 break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; @@ -880,7 +874,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) SWTMR_UNLOCK(intSave); return ret; } - +//接口函数 删除定时器 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) { SWTMR_CTRL_S *swtmr = NULL; @@ -892,11 +886,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) return LOS_ERRNO_SWTMR_ID_INVALID; } - swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - swtmr = g_swtmrCBArray + swtmrCBID; + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模 + swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体 SWTMR_LOCK(intSave); - if (swtmr->usTimerID != swtmrID) { + if (swtmr->usTimerID != swtmrID) {//ID必须一样 SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } @@ -905,10 +899,10 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) case OS_SWTMR_STATUS_UNUSED: ret = LOS_ERRNO_SWTMR_NOT_CREATED; break; - case OS_SWTMR_STATUS_TICKING: + case OS_SWTMR_STATUS_TICKING://正在计数就先停止在删除,这里没有break SwtmrStop(swtmr); /* fall-through */ - case OS_SWTMR_STATUS_CREATED: + case OS_SWTMR_STATUS_CREATED://再删除定时器 SwtmrDelete(swtmr); break; default: @@ -921,4 +915,4 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) return ret; } -#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */ +#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */ \ No newline at end of file diff --git a/src/kernel_liteos_a/kernel/base/core/los_task.c b/src/kernel_liteos_a/kernel/base/core/los_task.c index 2bd80726..d0091651 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_task.c +++ b/src/kernel_liteos_a/kernel/base/core/los_task.c @@ -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);//资源回收任务初始化 diff --git a/src/kernel_liteos_a/kernel/base/core/los_tick.c b/src/kernel_liteos_a/kernel/base/core/los_tick.c index b5c2794e..4e9c4575 100644 --- a/src/kernel_liteos_a/kernel/base/core/los_tick.c +++ b/src/kernel_liteos_a/kernel/base/core/los_tick.c @@ -37,30 +37,30 @@ #endif -LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; -LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; -LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; +LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; //系统时钟,绝大部分部件工作的时钟源,以及所有外设的始终来源 +LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; //每秒Tick数,harmony默认为每秒100次即10ms +LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; //将周期转为纳秒级 /* spinlock for task module */ -LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); //节拍器自旋锁 /* * Description : Tick interruption handler */ -LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) +LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)//节拍中断处理函数,harmony默认1ms触发一次 { #ifdef LOSCFG_SCHED_TICK_DEBUG OsSchedDebugRecordData(); #endif #ifdef LOSCFG_KERNEL_VDSO - OsVdsoTimevalUpdate(); + OsVdsoTimevalUpdate(); //更新vdso数据页时间,vsdo可以直接在用户进程空间绕过系统调用获取系统时间 #endif #ifdef LOSCFG_BASE_CORE_TICK_HW_TIME HalClockIrqClear(); /* diff from every platform */ #endif - OsSchedTick(); + OsSchedTick();//由时钟发起的调度 }