|
|
|
@ -1,15 +1,25 @@
|
|
|
|
|
/*
|
|
|
|
|
进程模块主文件
|
|
|
|
|
/*!
|
|
|
|
|
* @file los_process.c
|
|
|
|
|
* @brief 进程模块主文件
|
|
|
|
|
* @link
|
|
|
|
|
@verbatim
|
|
|
|
|
|
|
|
|
|
并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,
|
|
|
|
|
看起来像同时运行,实际上是线程不停切换
|
|
|
|
|
并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行
|
|
|
|
|
单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行)
|
|
|
|
|
多核CPU线程间可以实现宏观和微观上的并行
|
|
|
|
|
LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段
|
|
|
|
|
|
|
|
|
|
@endverbatim
|
|
|
|
|
* @version
|
|
|
|
|
* @author weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
|
|
|
|
|
* @date 2021-12-15
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
|
|
|
|
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
|
|
|
|
|
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
|
|
|
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
|
* are permitted provided that the following conditions are met:
|
|
|
|
@ -68,15 +78,22 @@
|
|
|
|
|
#include "los_vm_phys.h"
|
|
|
|
|
#include "los_vm_syscall.h"
|
|
|
|
|
|
|
|
|
|
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;///< 空闲状态下的进程链表, .个人觉得应该取名为 g_freeProcessList @note_thinking
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @brief 将进程插入到空闲链表中
|
|
|
|
|
* @details
|
|
|
|
|
* @param argc 1
|
|
|
|
|
* @param[LosProcessCB] processCB 指定进程
|
|
|
|
|
* @return 函数执行结果
|
|
|
|
|
* - VOID 无
|
|
|
|
|
*/
|
|
|
|
|
STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_PID_CONTAINER
|
|
|
|
@ -156,7 +173,7 @@ ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pgroup->pgroupLeader = (UINTPTR)processCB;//指定进程负责人
|
|
|
|
|
pgroup->pgroupLeader = (UINTPTR)processCB;//指定进程组负责人
|
|
|
|
|
LOS_ListInit(&pgroup->processList);//初始化组员链表
|
|
|
|
|
LOS_ListInit(&pgroup->exitProcessList);//初始化僵死进程链表
|
|
|
|
|
|
|
|
|
@ -173,17 +190,19 @@ 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
|
|
|
|
|
LOS_ListDelete(&processCB->pgroup->groupList);//从全局进程组链表上把自己摘出去 记住它是 LOS_ListTailInsert(&g_processGroup->groupList, &group->groupList) 挂上去的
|
|
|
|
|
*pgroup = processCB->pgroup;
|
|
|
|
|
LOS_ListDelete(&processCB->pgroup->groupList);//从全局进程组链表上把自己摘出去 记住它是 LOS_ListTailInsert(&g_processGroup->groupList, &group->groupList) 挂上去的
|
|
|
|
|
*pgroup = processCB->pgroup;//????? 这步操作没看明白,谁能告诉我为何要这么做?
|
|
|
|
|
#ifdef LOSCFG_PID_CONTAINER
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
@ -196,6 +215,7 @@ STATIC VOID ExitProcessGroup(LosProcessCB *processCB, ProcessGroup **pgroup)
|
|
|
|
|
|
|
|
|
|
processCB->pgroup = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 通过指定组ID找到进程组 */
|
|
|
|
|
STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid)
|
|
|
|
|
{
|
|
|
|
@ -216,6 +236,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)
|
|
|
|
|
{
|
|
|
|
@ -309,6 +330,7 @@ STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, const
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 唤醒等待wakePID结束的任务 */
|
|
|
|
|
VOID OsWaitWakeTask(LosTaskCB *taskCB, UINTPTR wakePID)
|
|
|
|
|
{
|
|
|
|
@ -318,6 +340,7 @@ VOID OsWaitWakeTask(LosTaskCB *taskCB, UINTPTR wakePID)
|
|
|
|
|
LOS_MpSchedule(OS_MP_CPU_ALL);//向所有cpu发送调度指令
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 唤醒等待参数进程结束的任务 */
|
|
|
|
|
STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList)
|
|
|
|
|
{
|
|
|
|
@ -332,7 +355,7 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr
|
|
|
|
|
if (processID == 0) {
|
|
|
|
|
processID = taskCB->waitID;
|
|
|
|
|
find = TRUE;//找到了
|
|
|
|
|
} else {
|
|
|
|
|
} else {// @note_thinking 这个代码有点多余吧,会执行到吗?
|
|
|
|
|
processID = OS_INVALID_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -349,6 +372,7 @@ STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *pr
|
|
|
|
|
|
|
|
|
|
return find;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 检查父进程的等待任务并唤醒父进程去处理等待任务 */
|
|
|
|
|
STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB)
|
|
|
|
|
{
|
|
|
|
@ -360,7 +384,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro
|
|
|
|
|
if (LOS_ListEmpty(&parentCB->waitList)) {//父进程中是否有在等待子进程退出的任务?
|
|
|
|
|
return;//没有就退出
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
|
findSpecified = OsWaitWakeSpecifiedProcess(head, processCB, &list);//找到指定的任务
|
|
|
|
|
if (findSpecified == TRUE) {
|
|
|
|
|
/* No thread is waiting for any child process to finish */
|
|
|
|
@ -411,6 +435,7 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 回收指定进程的资源 */
|
|
|
|
|
LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
|
|
|
|
|
{
|
|
|
|
@ -420,10 +445,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;//重置指针为空
|
|
|
|
|
processCB->user = NULL; //重置指针为空
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -480,6 +505,7 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
|
|
|
|
|
processCB->resourceLimit = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 回收僵死状态进程的资源 */
|
|
|
|
|
STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **pgroup)
|
|
|
|
|
{
|
|
|
|
@ -497,9 +523,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中去,可用于重新分配了。
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 当一个进程自然退出的时候,它的孩子进程由两位老祖宗收养 */
|
|
|
|
|
STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
|
|
|
|
|
{
|
|
|
|
@ -513,7 +540,6 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (!LOS_ListEmpty(&processCB->childrenList)) {//如果存在孩子进程
|
|
|
|
|
childHead = processCB->childrenList.pstNext;//获取孩子链表
|
|
|
|
|
LOS_ListDelete(&(processCB->childrenList));//清空自己的孩子链表
|
|
|
|
@ -537,6 +563,7 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 回收指定进程的已经退出(死亡)的孩子进程所占资源 */
|
|
|
|
|
STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB)
|
|
|
|
|
{
|
|
|
|
@ -549,11 +576,13 @@ STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB)
|
|
|
|
|
(VOID)LOS_MemFree(m_aucSysMem1, pgroup);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 一个进程的自然消亡过程,参数是当前运行的任务*/
|
|
|
|
|
VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status)
|
|
|
|
|
{
|
|
|
|
|
OsChildProcessResourcesFree(processCB);//释放孩子进程的资源
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* is a child process */
|
|
|
|
|
if (processCB->parentProcess != NULL) {
|
|
|
|
|
LosProcessCB *parentCB = processCB->parentProcess;
|
|
|
|
@ -569,8 +598,8 @@ VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status)
|
|
|
|
|
|
|
|
|
|
OsDealAliveChildProcess(processCB);//孩子们要怎么处理,移交给(用户态和内核态)根进程
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES;//贴上僵死进程的标签
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
|
|
|
(VOID)OsSendSigToProcess(parentCB, SIGCHLD, OS_KERNEL_KILL_PERMISSION);
|
|
|
|
|
#endif
|
|
|
|
@ -638,6 +667,7 @@ UINT32 OsProcessInit(VOID)
|
|
|
|
|
SystemProcessEarlyInit(OsGetKernelInitProcess());
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 进程回收再利用过程*/
|
|
|
|
|
LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
|
|
|
|
|
{
|
|
|
|
@ -647,7 +677,7 @@ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
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节点位置
|
|
|
|
|
//OS_PCB_FROM_PENDLIST 代表的是通过pendlist节点找到 PCB实体,因为g_processRecyleList上面挂的是pendlist节点位置
|
|
|
|
|
if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) {//进程没有退出标签
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -683,6 +713,7 @@ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
|
|
|
|
|
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! 删除PCB块 其实是 PCB块回归进程池,先进入回收链表*/
|
|
|
|
|
STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
|
|
|
|
|
{
|
|
|
|
@ -698,7 +729,6 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
OsProcessResourcesToFree(processCB);//释放进程所占用的资源
|
|
|
|
|
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
@ -712,7 +742,7 @@ STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;//设置进程状态为非初始化
|
|
|
|
|
processCB->processStatus |= OS_PROCESS_FLAG_EXIT;//设置进程状态为退出
|
|
|
|
|
processCB->processStatus |= OS_PROCESS_FLAG_EXIT; //设置进程状态为退出
|
|
|
|
|
LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
|
|
|
|
@ -757,19 +787,19 @@ UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name)
|
|
|
|
|
/*! 初始化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);//初始化孩子任务/线程链表,上面挂的都是由此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);
|
|
|
|
|
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
|
|
|
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
|
|
|
if (OsProcessIsUserMode(processCB)) {//如果是用户态进程
|
|
|
|
|
processCB->vmSpace = OsCreateUserVmSpace();//创建用户空间
|
|
|
|
|
if (processCB->vmSpace == NULL) {
|
|
|
|
@ -788,14 +818,12 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name)
|
|
|
|
|
}
|
|
|
|
|
(VOID)memset_s(processCB->processCpup, sizeof(OsCpupBase), 0, sizeof(OsCpupBase));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_SECURITY_VID
|
|
|
|
|
status_t status = VidMapListInit(processCB);
|
|
|
|
|
if (status != LOS_OK) {
|
|
|
|
|
return LOS_ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_SECURITY_CAPABILITY
|
|
|
|
|
OsInitCapability(processCB);//初始化进程安全相关功能
|
|
|
|
|
#endif
|
|
|
|
@ -809,7 +837,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name)
|
|
|
|
|
//创建用户
|
|
|
|
|
#ifdef LOSCFG_SECURITY_CAPABILITY
|
|
|
|
|
STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)//参数size 表示组数量
|
|
|
|
|
{//(size - 1) * sizeof(UINT32) 用于 user->groups[..],这种设计节约了内存,不造成不需要的浪费
|
|
|
|
|
{ //(size - 1) * sizeof(UINT32) 用于 user->groups[..],这种设计节约了内存,不造成不需要的浪费
|
|
|
|
|
User *user = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + (size - 1) * sizeof(UINT32));
|
|
|
|
|
if (user == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
@ -820,7 +848,7 @@ STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)//参数size
|
|
|
|
|
user->gid = gid;
|
|
|
|
|
user->effGid = gid;
|
|
|
|
|
user->groupNumber = size;//用户组数量
|
|
|
|
|
user->groups[0] = gid;//用户组列表,一个用户可以属于多个用户组
|
|
|
|
|
user->groups[0] = gid; //用户组列表,一个用户可以属于多个用户组
|
|
|
|
|
return user;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -908,8 +936,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;
|
|
|
|
@ -917,7 +945,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;
|
|
|
|
@ -926,7 +954,7 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
|
|
|
|
|
EXIT:
|
|
|
|
|
OsDeInitPCB(processCB);
|
|
|
|
|
OsDeInitPCB(processCB);//删除进程控制块,归还内存
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
/*! 创建2,0号进程,即内核态进程的老祖宗*/
|
|
|
|
@ -962,7 +990,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
|
|
|
|
|
}
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
// 进程调度参数检查
|
|
|
|
|
/// 进程调度参数检查
|
|
|
|
|
INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *param)
|
|
|
|
|
{
|
|
|
|
|
if (param == NULL) {
|
|
|
|
@ -1006,7 +1034,7 @@ STATIC INLINE INT32 ProcessSchedulerParamCheck(INT32 which, INT32 pid, UINT16 po
|
|
|
|
|
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();//获得当前进程
|
|
|
|
@ -1028,7 +1056,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 };
|
|
|
|
@ -1090,12 +1118,12 @@ TO_SCHED:
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
@ -1139,7 +1167,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;
|
|
|
|
@ -1159,7 +1187,7 @@ LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio)
|
|
|
|
|
|
|
|
|
|
return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, (UINT16)policy, ¶m);
|
|
|
|
|
}
|
|
|
|
|
// 接口封装 - 获取进程优先级 which:标识进程,进程组,用户
|
|
|
|
|
/// 接口封装 - 获取进程优先级 which:标识进程,进程组,用户
|
|
|
|
|
LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -1192,11 +1220,12 @@ 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链表,表示这个任务在等待某个进程的退出
|
|
|
|
|
* 当被等待进程退出时候会将自己挂到父进程的退出子进程链表和进程组的退出进程链表.
|
|
|
|
@ -1232,7 +1261,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)
|
|
|
|
|
{
|
|
|
|
@ -1253,16 +1282,15 @@ 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) {//找到了,确实有一个已经退出的PID,注意一个进程退出时会挂到父进程的exitChildList上
|
|
|
|
|
if (*childCB != NULL) {//找到了,确实有一个已经退出的PID,注意一个进程退出时会挂到父进程的exitChildList上
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OsFindChildProcess(processCB, waitProcess) != LOS_OK) {
|
|
|
|
|
return LOS_ECHILD;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
runTask->waitFlag = OS_PROCESS_WAIT_PRO;//设置当前任务的等待类型
|
|
|
|
|
runTask->waitID = (UINTPTR)waitProcess;
|
|
|
|
|
if (OsFindChildProcess(processCB, waitProcess) != LOS_OK) {
|
|
|
|
|
return LOS_ECHILD;
|
|
|
|
|
}
|
|
|
|
|
runTask->waitFlag = OS_PROCESS_WAIT_PRO;//设置当前任务的等待类型
|
|
|
|
|
runTask->waitID = (UINTPTR)waitProcess;
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1294,9 +1322,9 @@ STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcess
|
|
|
|
|
if (childCB != NULL) {//找到了,确实有一个已经退出的PID
|
|
|
|
|
goto WAIT_BACK;
|
|
|
|
|
}
|
|
|
|
|
runTask->waitID = pid;
|
|
|
|
|
runTask->waitFlag = OS_PROCESS_WAIT_ANY;
|
|
|
|
|
} else { /* pid < -1 */
|
|
|
|
|
runTask->waitID = pid;//等待PID,这个PID可以和当前进程没有任何关系
|
|
|
|
|
runTask->waitFlag = OS_PROCESS_WAIT_ANY;//设置当前任务的等待类型
|
|
|
|
|
} else { /* pid < -1 */ //等待指定进程组内为|pid|的所有子进程
|
|
|
|
|
/* Wait for any child process whose group number is the pid absolute value. */
|
|
|
|
|
ProcessGroup *pgroup = OsFindProcessGroup(-pid);
|
|
|
|
|
if (pgroup == NULL) {
|
|
|
|
@ -1316,7 +1344,7 @@ WAIT_BACK:
|
|
|
|
|
*child = childCB;
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
// 等待回收孩子进程
|
|
|
|
|
/// 等待回收孩子进程 @note_thinking 这样写Porcess不太好吧
|
|
|
|
|
STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info)
|
|
|
|
|
{
|
|
|
|
|
ProcessGroup *pgroup = NULL;
|
|
|
|
@ -1336,7 +1364,7 @@ STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intS
|
|
|
|
|
|
|
|
|
|
if (status != NULL) {
|
|
|
|
|
if (mode == OS_USER_MODE) {//孩子为用户态进程
|
|
|
|
|
(VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32));
|
|
|
|
|
(VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32));//从内核空间拷贝退出码
|
|
|
|
|
} else {
|
|
|
|
|
*status = exitCode;
|
|
|
|
|
}
|
|
|
|
@ -1371,9 +1399,9 @@ 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;
|
|
|
|
|
}
|
|
|
|
@ -1399,8 +1427,8 @@ STATIC UINT32 OsWaitOptionsCheck(UINT32 options)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
//等待子进程结束并回收子进程,返回已经终止的子进程的进程ID号,并清除僵死进程。
|
|
|
|
|
}
|
|
|
|
|
///等待子进程结束并回收子进程,返回已经终止的子进程的进程ID号,并清除僵死进程。
|
|
|
|
|
STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage)
|
|
|
|
|
{
|
|
|
|
|
(VOID)rusage;
|
|
|
|
@ -1429,28 +1457,28 @@ 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) {//有LOS_WAIT_WNOHANG标签
|
|
|
|
|
runTask->waitFlag = 0;//等待标识置0
|
|
|
|
|
pid = 0;//这里置0,是为了 return 0
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
//等待孩子进程退出
|
|
|
|
|
OsWaitInsertWaitListInOrder(runTask, processCB);
|
|
|
|
|
//发起调度的目的是为了让出CPU,让其他进程/任务运行
|
|
|
|
|
|
|
|
|
|
//等待孩子进程退出
|
|
|
|
|
OsWaitInsertWaitListInOrder(runTask, processCB);//将当前任务挂入进程waitList链表
|
|
|
|
|
//发起调度的目的是为了让出CPU,让其他进程/任务运行
|
|
|
|
|
|
|
|
|
|
runTask->waitFlag = 0;
|
|
|
|
|
if (runTask->waitID == OS_INVALID_VALUE) {
|
|
|
|
|
pid = -LOS_ECHILD;//没有此子进程
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
//回收僵死进程
|
|
|
|
|
|
|
|
|
|
childCB = (LosProcessCB *)runTask->waitID;
|
|
|
|
|
if (!OsProcessIsDead(childCB)) {
|
|
|
|
|
pid = -LOS_ESRCH;
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//回收僵死进程
|
|
|
|
|
return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info);
|
|
|
|
|
|
|
|
|
|
ERROR:
|
|
|
|
@ -1536,7 +1564,7 @@ STATIC UINT32 OsSetProcessGroupCheck(const LosProcessCB *processCB, LosProcessCB
|
|
|
|
|
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;
|
|
|
|
@ -1653,12 +1681,12 @@ EXIT:
|
|
|
|
|
SCHEDULER_UNLOCK(intSave);
|
|
|
|
|
return gid;
|
|
|
|
|
}
|
|
|
|
|
// 获取当前进程的组ID
|
|
|
|
|
/// 获取当前进程的组ID
|
|
|
|
|
LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID)
|
|
|
|
|
{
|
|
|
|
|
return LOS_GetProcessGroupID(OsCurrProcessGet()->processID);
|
|
|
|
|
}
|
|
|
|
|
// 为用户态任务分配栈空间
|
|
|
|
|
/// 为用户态任务分配栈空间
|
|
|
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
|
|
|
STATIC LosProcessCB *OsGetFreePCB(VOID)
|
|
|
|
|
{
|
|
|
|
@ -1683,7 +1711,7 @@ STATIC VOID *OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size)
|
|
|
|
|
{
|
|
|
|
|
LosVmMapRegion *region = NULL;
|
|
|
|
|
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);//可使用可读可写区
|
|
|
|
@ -1781,12 +1809,12 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT;
|
|
|
|
|
processCB->processStatus |= OS_PROCESS_FLAG_ALREADY_EXEC;
|
|
|
|
|
processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT; //去掉进程退出标签
|
|
|
|
|
processCB->processStatus |= OS_PROCESS_FLAG_ALREADY_EXEC;//加上进程运行elf标签
|
|
|
|
|
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
// 执行用户态任务, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小
|
|
|
|
|
/// 执行用户态任务, 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;
|
|
|
|
@ -1798,18 +1826,18 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
|
|
|
|
|
if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) {//对齐
|
|
|
|
|
return LOS_NOK;
|
|
|
|
|
}
|
|
|
|
|
//注意 sp此时指向栈底,栈底地址要大于栈顶
|
|
|
|
|
//注意 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;//任务的入口函数
|
|
|
|
|
//初始化内核态栈
|
|
|
|
|
//初始化内核态栈
|
|
|
|
|
TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize,
|
|
|
|
|
(VOID *)taskCB->topOfStack, FALSE);
|
|
|
|
|
OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp);//初始化用户栈,将内核栈中上下文的 context->R[0] = sp ,context->sp = sp
|
|
|
|
@ -1818,7 +1846,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
// 用户进程开始初始化
|
|
|
|
|
/// 用户进程开始初始化
|
|
|
|
|
STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -1958,7 +1986,7 @@ ERROR:
|
|
|
|
|
OsDeInitPCB(processCB);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
// 拷贝用户信息 直接用memcpy_s
|
|
|
|
|
/// 拷贝用户信息 直接用memcpy_s
|
|
|
|
|
STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_SECURITY_CAPABILITY
|
|
|
|
@ -1983,10 +2011,10 @@ STATIC VOID GetCopyTaskParam(LosProcessCB *childProcessCB, UINTPTR entry, UINT32
|
|
|
|
|
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;//用户态栈大小
|
|
|
|
|
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)为内核态栈大小
|
|
|
|
@ -2028,7 +2056,7 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR
|
|
|
|
|
childTaskCB->taskStatus = runTask->taskStatus;//任务状态先同步,注意这里是赋值操作. ...01101001
|
|
|
|
|
childTaskCB->ops->schedParamModify(childTaskCB, ¶m);
|
|
|
|
|
if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//因只能有一个运行的task,所以如果一样要改4号位
|
|
|
|
|
childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING;//将四号位清0 ,变成 ...01100001
|
|
|
|
|
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);
|
|
|
|
@ -2051,16 +2079,15 @@ STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProces
|
|
|
|
|
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
|
if (childProcessCB->parentProcess == NULL) {
|
|
|
|
|
if (flags & CLONE_PARENT) { //这里指明 childProcessCB 和 runProcessCB 有同一个父亲,是兄弟关系
|
|
|
|
|
parentProcessCB = runProcessCB->parentProcess;
|
|
|
|
|
} else {
|
|
|
|
|
parentProcessCB = runProcessCB;//指认父亲,这个赋值代表从此是你儿了
|
|
|
|
|
}
|
|
|
|
|
childProcessCB->parentProcess = parentProcessCB;
|
|
|
|
|
LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);//通过我的兄弟姐妹节点,挂到父亲的孩子链表上,于我而言,父亲的这个链表上挂的都是我的兄弟姐妹
|
|
|
|
|
//不会被排序,老大,老二,老三 老天爷指定了。
|
|
|
|
|
if (flags & CLONE_PARENT) { //这里指明 childProcessCB 和 runProcessCB 有同一个父亲,是兄弟关系
|
|
|
|
|
parentProcessCB = runProcessCB->parentProcess;
|
|
|
|
|
} else {
|
|
|
|
|
parentProcessCB = runProcessCB;
|
|
|
|
|
}
|
|
|
|
|
childProcessCB->parentProcess = parentProcessCB;//指认父亲,这个赋值代表从此是你儿了
|
|
|
|
|
LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);//通过我的兄弟姐妹节点,挂到父亲的孩子链表上,于我而言,父亲的这个链表上挂的都是我的兄弟姐妹
|
|
|
|
|
//不会被排序,老大,老二,老三 老天爷指定了。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (childProcessCB->pgroup == NULL) {
|
|
|
|
|
childProcessCB->pgroup = parentProcessCB->pgroup;
|
|
|
|
|
LOS_ListTailInsert(&parentProcessCB->pgroup->processList, &childProcessCB->subordinateGroupList);
|
|
|
|
@ -2086,13 +2113,13 @@ STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status = LOS_VmSpaceClone(flags, runProcessCB->vmSpace, childProcessCB->vmSpace);
|
|
|
|
|
status = LOS_VmSpaceClone(flags, runProcessCB->vmSpace, childProcessCB->vmSpace);//虚拟空间clone
|
|
|
|
|
if (status != LOS_OK) {
|
|
|
|
|
return LOS_ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
// 拷贝进程文件描述符(proc_fd)信息
|
|
|
|
|
/// 拷贝进程文件描述符(proc_fd)信息
|
|
|
|
|
STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_FS_VFS
|
|
|
|
@ -2163,7 +2190,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;
|
|
|
|
@ -2184,7 +2211,7 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_LITEIPC
|
|
|
|
|
if (run->ipcInfo != NULL) {//重新初始化IPC池
|
|
|
|
|
if (run->ipcInfo != NULL) { //重新初始化IPC池
|
|
|
|
|
child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo));//@note_good 将沿用用户态空间地址(即线性区地址)
|
|
|
|
|
if (child->ipcInfo == NULL) {//因为整个进程虚拟空间都是拷贝的,ipc的用户态虚拟地址当然可以拷贝,但因进程不同了,所以需要重新申请ipc池和重新
|
|
|
|
|
return LOS_ENOMEM;//映射池中两个地址.
|
|
|
|
@ -2195,9 +2222,10 @@ STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProce
|
|
|
|
|
#ifdef LOSCFG_SECURITY_CAPABILITY
|
|
|
|
|
OsCopyCapability(run, child);//拷贝安全能力
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
// 拷贝进程
|
|
|
|
|
/// 拷贝进程
|
|
|
|
|
STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret, processID;
|
|
|
|
@ -2219,7 +2247,6 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
|
goto ERROR_INIT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_PLIMITS
|
|
|
|
|
ret = OsPLimitsAddProcess(run->plimits, child);
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
@ -2227,7 +2254,6 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ret = OsForkInitPCB(flags, child, name, sp, size);//初始化进程控制块
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
|
goto ERROR_INIT;
|
|
|
|
@ -2315,6 +2341,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;
|
|
|
|
@ -2346,7 +2373,6 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status)
|
|
|
|
|
UINT32 intSave;
|
|
|
|
|
|
|
|
|
|
(void)status;
|
|
|
|
|
|
|
|
|
|
/* The exit of a kernel - state process must be kernel - state and all threads must actively exit */
|
|
|
|
|
LosProcessCB *processCB = OsCurrProcessGet();
|
|
|
|
|
SCHEDULER_LOCK(intSave);
|
|
|
|
@ -2361,6 +2387,7 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status)
|
|
|
|
|
OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* @brief LOS_GetUsedPIDList
|
|
|
|
|
* 获取使用中的进程列表
|
|
|
|
@ -2413,12 +2440,12 @@ LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid)
|
|
|
|
|
return files->fdt;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
// 获取当前进程的进程ID
|
|
|
|
|
/// 获取当前进程的进程ID
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID)
|
|
|
|
|
{
|
|
|
|
|
return OsCurrProcessGet()->processID;
|
|
|
|
|
}
|
|
|
|
|
// 按指定状态退出指定进程
|
|
|
|
|
/// 按指定状态退出指定进程
|
|
|
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
|
|
|
STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB)
|
|
|
|
|
{
|
|
|
|
@ -2491,12 +2518,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来的
|
|
|
|
|
/// 获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的
|
|
|
|
|
LITE_OS_SEC_TEXT LosProcessCB *OsGetUserInitProcess(VOID)
|
|
|
|
|
{
|
|
|
|
|
return &g_processCBArray[OS_USER_ROOT_PROCESS_ID];
|
|
|
|
@ -2506,7 +2533,7 @@ LITE_OS_SEC_TEXT LosProcessCB *OsGetKernelInitProcess(VOID)
|
|
|
|
|
{
|
|
|
|
|
return &g_processCBArray[OS_KERNEL_ROOT_PROCESS_ID];
|
|
|
|
|
}
|
|
|
|
|
// 获取空闲进程,0号进程为空闲进程,该进程不干活,专给CPU休息的。
|
|
|
|
|
/// 获取空闲进程,0号进程为空闲进程,该进程不干活,专给CPU休息的。
|
|
|
|
|
LITE_OS_SEC_TEXT LosProcessCB *OsGetIdleProcess(VOID)
|
|
|
|
|
{
|
|
|
|
|
return &g_processCBArray[OS_KERNEL_IDLE_PROCESS_ID];
|
|
|
|
|