当前位置: 首页 > 科技观察

鸿蒙轻内核A核心源码分析系列流程管理

时间:2023-03-19 19:21:39 科技观察

更多内容请访问:与华为官方共同建立的鸿蒙技术社区https://ost.51cto.com本文将继续分析流程和任务管理模块。本文涉及的源代码以OpenHarmonyLiteOS-A内核为例,可在开源站点https://gitee.com/openharmony/kernel_liteos_a获取。如果涉及到开发板,默认以hispark_taurus为例。本文首先熟悉进程管理文件kernel\base\core\los_process.c中的内部接口,阅读代码,做一些记录。1、LiteOS-A内核进程全局变量(1)是进程池??,里面存放了各个进程控制块LosProcessCB的信息。(2)开头的g_freeProcess是一个空闲进程链表,挂载每个空闲进程控制块;g_processRecycleList是一个待回收的进程控制块链表,挂载每个等待回收的进程控制块。⑶开始的g_userInitProcess为用户root进程的进程号,其值固定为1。g_kernelInitProcess为内核进程,内核进程的进程号固定为2。g_kernelIdleProcess为内核空闲进程,进程号固定为0。⑷开头的g_processMaxNum表示配置的最大进程数,g_processGroup维护进程组信息,所有进程组都会挂载到全局进程组链表节点g_processGroup->groupList.⑴LITE_OS_SEC_BSSLosProcessCB*g_processCBArray=NULL;⑵LITE_OS_SEC_DATA_INITSTATICLOS_DL_LISTg_freeProcess;LITE_OS_SEC_DATA_INITSTATICLOS_DL_LISTg_processRecycleList;⑶LITE_OS_SEC_BSSUINT32g_userInitProcess=OS_INVALID_VALUE;LITE_OS_SEC_BSSUINT32g_kernelInitProcess=OS_INVALID_VALUE;LITE_OS_SEC_BSSUINT32g_kernelIdleProcess=OS_INVALID_VALUE;⑷LITE_OS_SEC_BSSUINT32g_processMaxNum;LITE_OS_SEC_BSSProcessGroup*g_processGroup=NULL;2、涉及空闲进程链表内部操作空闲进程块链接操作涉及初始化OsProcessInit,插入空闲进程块OsInsertPCBToFreeList,从链表中获取空闲进程块OsGetFreePCB。我们先看看OsInsertPCBToFreeList和OsGetFreePCB。初始化链表是在进程初始化的时候看的。1.OsInsertPCBToFreeListOsInsertPCBToFreeList函数将进程控制块插入到空闲进程块链表中。功能比较简单,清空进程结构块,然后放入进程块链表。有一个有趣的细节需要了解。⑴记下工序号,然后把工序块留空。(2)进程号设置为进程块结构,进程号的个数是固定的。⑶开始将进程设置为未使用状态,更新定时器号,没有无效值,然后插入到空闲进程块链表中。STATICINLINEVOIDOsInsertPCBToFreeList(LosProcessCB*processCB){⑴UINT32pid=processCB->processID;(VOID)memset_s(processCB,sizeof(LosProcessCB),0,sizeof(LosProcessCB));⑵processCB->processID=pid;⑶processCB>processStatus=OS_PROCESS_FLAG_UNUSED;processCB->timerID=(timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;LOS_ListTailInsert(&g_freeProcess,&processCB->pendList);}2.OsGetFreePCBOsGetFreePCB函数用于从空闲进程列表中获取进程块,该函数只有在启用KERLOSCF时才有效。(1)当空闲进程链表为空时,返回NULL。(2)获取空闲进程块指针,然后从空闲进程块链表中删除。STATICLosProcessCB*OsGetFreePCB(VOID){LosProcessCB*processCB=NULL;UINT32intSave;SCHEDULER_LOCK(intSave);⑴if(LOS_ListEmpty(&g_freeProcess)){SCHEDULER_UNLOCK(intSave);PRINT_ERR("系统中无空闲PCB!\n");返回空值;}⑵processCB=OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_freeProcess));LOS_ListDelete(&processCB->pendList);SCHEDULER_UNLOCK(intSave);删除OsDeleteTaskFromProcess,也包括线程进入进程OsProcessAddNewTask。1.OsDeleteTaskFromProcessOsDeleteTaskFromProcess函数用于从进程中删除一个线程。(1)可见,每个线程/任务控制块都维护了一个进程号,根据进程号可以得到进程控制块。每个线程控制块都通过自己的成员变量threadList挂载到进程的线程列表中。(2)从进程的线程列表中删除,然后将进程的线程数减1。(3)将任务控制块插入到待恢复链表中。VOIDOsDeleteTaskFromProcess(LosTaskCB*taskCB){⑴LosProcessCB*processCB=OS_PCB_FROM_PID(taskCB->processID);⑵LOS_ListDelete(&taskCB->threadList);processCB->threadNumber--;⑶OsTaskInsertToRecycleList(taskProcessAddcB);线程与进程相关联,需要两个参数,进程号和线程控制块。需要注意返回值,返回值表示在关联新线程之前进程中的线程数。⑴获取进程块。(2)将线程块关联的进程号设置为参数中输入的进程号,然后将线程控制块挂载到进程的线程列表中。可以看出,线程块的threadList用于挂载进程的线程列表,进程块的threadSiblingList节点用于挂载进程下的各种线程。(3)如果是用户态进程,则将线程的状态标记为用户态线程。⑷如果进程的线程数大于0,则设置线程的基本优先级basePrio与进程主线程的优先级相同,否则设置为最大优先级。(5)如果是内核进程,线程的基本优先级设置为当前线程的优先级。(6)如果启用了虚拟内存,将线程的MMU结构信息设置为进程虚拟地址空间维护的MMU。(7)如果进程中的线程数为0,则将该线程设置为进程的主线程。然后把进程的线程数加1。(8)获取进程已经有的线程数,然后把进程的线程数加1。然后返回进程关联new之前的线程数线。UINT32OsProcessAddNewTask(UINT32pid,LosTaskCB*taskCB){UINT32intSave;UINT16numCount;⑴LosProcessCB*processCB=OS_PCB_FROM_PID(pid);SCHEDULER_LOCK(intSave);⑵taskCB->processID=pid;LOS_ListTailInsert(&(processCB->threadSiblingList),&(taskCB->threadList));⑶if(OsProcessIsUserMode(processCB)){taskCB->taskStatus|=OS_TASK_FLAG_USER_MODE;⑷if(processCB->threadNumber>0){taskCB->basePrio=OS_TCB_FROM_TID(processCB->threadGroupID)->basePrio;}else{taskCB->basePrio=OS_USER_PROCESS_PRIORITY_HIGHEST;}}else{⑩taskCB->basePrio=OsCurrTaskGet()->basePrio;}#ifdefLOSCFG_KERNEL_VM⑹taskCB->archMmu=(UINTPTR)&processCB->vmSpace->archMmu;#endifif(!processCB->threadNumber){⑺processCB->threadGroupID=taskCB->taskID;}processCB->threadNumber++;⑻numCount=processCB->threadCount;processCB->threadCount++;SCHEDULER_UNLOCK(intSave);返回数;进程组创建OsCreateProcessGroup,进程组退出OsExitProcessGroup,进程组查找OsExitProcessGroup1,OsCreateProcessGroupOsCreateProcessGroup函数用于根据进程号创建进程组,返回值为创建的进程组指针。进程组是动态创建的。(1)为进程组控制块申请动态内存。(2)进程组的groupId为创建进程组的进程号,然后初始化进程组的两个链表。⑶获取进程控制块,然后执行。⑷将进程挂载到进程组的processList进程列表中,使用的挂载点是进程控制块的subordinateGroupList列表节点,所以看到这个成员变量,就把它想象成同一个进程中各个进程的链接关系进程组。然后更新进程的进程组信息,更新进程状态为进程组组长。(5)如果有全局进程组,将创建的进程组挂载到全局进程组变量中。STATICProcessGroup*OsCreateProcessGroup(UINT32pid){LosProcessCB*processCB=NULL;⑴ProcessGroup*group=LOS_MemAlloc(m_aucSysMem1,sizeof(ProcessGroup));如果(组==NULL){返回NULL;⑵group->groupID=pid;LOS_ListInit(&group->processList);LOS_ListInit(&group->exitProcessList);⑶processCB=OS_PCB_FROM_PID(pid);⑷LOS_ListTailInsert(&group->processList,&processCB->subordinateGroupList);processCB->group=group;processCB->processStat=OS_PROCESS_FLAG_GROUP_LEADER;(5)if(g_processGroup!=NULL){LOS_ListTailInsert(&g_processGroup->groupList,&group->groupList);}返回组;}2。OsExitProcessGroupOsExitProcessGroup函数用于从进程组中退出进程,第一个参数指定进程控制块,第二个为输出参数,记录进程所在的进程组。(1)根据进程,获取其所在的进程组,然后获取进程组的主进程,再获取主进程的进程控制块。(2)从进程组中删除进程。⑶表示如果进程组下没有挂载的进程,并且进程组下也没有挂载退出的进程,则执行。(4)从全局进程组链表中删除进程组。然后,设置进程组的主进程状态为非主进程OS_PROCESS_FLAG_GROUP_LEADER。(5)如果主进程没有被使用,且主进程不处于退出状态,则将主进程从阻塞列表中删除,然后插入到idle空闲进程列表中。⑩由于进程启动了一个进程组,所以需要更新进程所属的进程组为NULL。STATICVOIDOsExitProcessGroup(LosProcessCB*processCB,ProcessGroup**group){⑴LosProcessCB*groupProcessCB=OS_PCB_FROM_PID(processCB->group->groupID);⑵LOS_ListDelete(&processCB->subordinateGroupList);⑶if(LOS_List-ListEmpty(&progup>processList)&&LOS_ListEmpty(&processCB->group->exitProcessList)){⑷LOS_ListDelete(&processCB->group->groupList);groupProcessCB->processStatus&=~OS_PROCESS_FLAG_GROUP_LEADER;)&&!(groupProcessCB->processStatus&OS_PROCESS_FLAG_EXIT)){LOS_ListDelete(&groupProcessCB->pendList);OsInsertPCBToFreeList(groupProcessCB);}}⑴processCB->group=NULL;指针。(1)如果它等于全局进程组的编号,则全局进程组指针无论如何。(2)遍历全局进程组下的各个进程组,判断遍历的进程组数是否与传入的进程组数相等,相等则返回。如果实施。⑶、表示没有查询到指定进程组号的进程组信息。STATICProcessGroup*OsFindProcessGroup(UINT32gid){ProcessGroup*group=NULL;⑴if(g_processGroup->groupID==gid){returng_processGroup;⑵LOS_DL_LIST_FOR_EACH_ENTRY(group,&g_processGroup->groupList,ProcessGroup,groupListup){if(gro>groupID==gid){返回组;}}⑶PRINT_INFO("%s是查找组:%u失败!\n",__FUNCTION__,gid);返回空值;}参考站点:OpenHarmony/docs流程管理。kernel_liteos_alos_process.h。kernel_liteos_alos_process.c。kernel_liteos_alos_process_pri.h。总结本文介绍进程管理文件。本文首先熟悉进程管理文件kernel\base\core\los_process.c中的一些内部接口。更多信息请访问:与华为官方共建的鸿蒙技术社区https://ost.51cto.com

最新推荐
猜你喜欢