From bbad89cfcc857f95d99b6a2e4309224b3564597c Mon Sep 17 00:00:00 2001 From: kuangyufei Date: Thu, 22 Oct 2020 20:53:09 +0800 Subject: [PATCH] =?UTF-8?q?=E9=B8=BF=E8=92=99=E6=BA=90=E7=A0=81=E5=88=86?= =?UTF-8?q?=E6=9E=90=E7=B3=BB=E5=88=97=E7=AF=87=20https://blog.csdn.net/ku?= =?UTF-8?q?angyufei=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20http?= =?UTF-8?q?s://my.oschina.net/u/3751245?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/base/core/los_process.c | 74 ++++++++++++++--------------- kernel/base/include/los_sched_pri.h | 22 +++++---- zzz/git/push.sh | 2 +- 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 3704989a..790ff166 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -830,15 +830,15 @@ LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID) STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name, UINT16 priority) { ProcessGroup *group = NULL; - UINT32 ret = OsInitPCB(processCB, flags, priority, LOS_SCHED_RR, name); + UINT32 ret = OsInitPCB(processCB, flags, priority, LOS_SCHED_RR, name);//初始化进程控制块 if (ret != LOS_OK) { goto EXIT; } #if (LOSCFG_KERNEL_LITEIPC == YES) - if (OsProcessIsUserMode(processCB)) { - ret = LiteIpcPoolInit(&(processCB->ipcInfo)); - if (ret != LOS_OK) { + if (OsProcessIsUserMode(processCB)) {//是否在用户模式 + ret = LiteIpcPoolInit(&(processCB->ipcInfo));//IPC池初始化 + if (ret != LOS_OK) {//异常处理 ret = LOS_ENOMEM; PRINT_ERR("LiteIpcPoolInit failed!\n"); goto EXIT; @@ -854,14 +854,14 @@ STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const C } #endif - group = OsCreateProcessGroup(processCB->processID); + group = OsCreateProcessGroup(processCB->processID);//创建进程组 if (group == NULL) { ret = LOS_ENOMEM; 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; @@ -875,7 +875,7 @@ STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const C return LOS_OK; EXIT: - OsDeInitPCB(processCB); + OsDeInitPCB(processCB);//删除进程控制块 return ret; } @@ -948,32 +948,32 @@ STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 p } if (which != LOS_PRIO_PROCESS) {//进程标识 - return LOS_EOPNOTSUPP; + return LOS_EOPNOTSUPP;//返回操作不支持 } - if (prio > OS_PROCESS_PRIORITY_LOWEST) { - return LOS_EINVAL; + if (prio > OS_PROCESS_PRIORITY_LOWEST) {//鸿蒙优先级是 0 -31级,0级最大 + return LOS_EINVAL;//返回无效参数 } - if ((policy != LOS_SCHED_FIFO) && (policy != LOS_SCHED_RR)) { - return LOS_EOPNOTSUPP; + if ((policy != LOS_SCHED_FIFO) && (policy != LOS_SCHED_RR)) {//调度方式既不是先进先得,也不是抢占式 + return LOS_EOPNOTSUPP;//返回操作不支持 } return LOS_OK; } -#ifdef LOSCFG_SECURITY_CAPABILITY +#ifdef LOSCFG_SECURITY_CAPABILITY //检查进程的安全许可证 STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, UINT16 prio) { - LosProcessCB *runProcess = OsCurrProcessGet(); + LosProcessCB *runProcess = OsCurrProcessGet();//获得当前进程 /* always trust kernel process */ - if (!OsProcessIsUserMode(runProcess)) { + if (!OsProcessIsUserMode(runProcess)) {//进程必须在内核模式下,也就是说在内核模式下是安全的. return TRUE; } /* user mode process can reduce the priority of itself */ - if ((runProcess->processID == processCB->processID) && (prio > processCB->priority)) { + if ((runProcess->processID == processCB->processID) && (prio > processCB->priority)) {//用户模式下进程阔以降低自己的优先级 return TRUE; } @@ -991,54 +991,54 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio UINT32 intSave; INT32 ret; - ret = OsProcessSchedlerParamCheck(which, pid, prio, policy); + ret = OsProcessSchedlerParamCheck(which, pid, prio, policy);//先参数检查 if (ret != LOS_OK) { return -ret; } - SCHEDULER_LOCK(intSave); + SCHEDULER_LOCK(intSave);//持有调度自旋锁,多CPU情况下调度期间需要原子处理 processCB = OS_PCB_FROM_PID(pid); - if (OsProcessIsInactive(processCB)) { + if (OsProcessIsInactive(processCB)) {//进程未活动的处理 ret = LOS_ESRCH; goto EXIT; } #ifdef LOSCFG_SECURITY_CAPABILITY - if (!OsProcessCapPermitCheck(processCB, prio)) { + if (!OsProcessCapPermitCheck(processCB, prio)) {//检查是否安全 ret = LOS_EPERM; goto EXIT; } #endif - if (policyFlag == TRUE) { - if (policy == LOS_SCHED_FIFO) { - processCB->timeSlice = 0; + if (policyFlag == TRUE) {//参数 policyFlag 表示调度方式要变吗? + if (policy == LOS_SCHED_FIFO) {//先进先出调度方式下 + processCB->timeSlice = 0;//不需要时间片 } - processCB->policy = policy; + processCB->policy = policy;//改变调度方式 } - if (processCB->processStatus & OS_PROCESS_STATUS_READY) { - OS_PROCESS_PRI_QUEUE_DEQUEUE(processCB); - processCB->priority = prio; - OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB); + if (processCB->processStatus & OS_PROCESS_STATUS_READY) {//进程处于就绪状态的处理 + OS_PROCESS_PRI_QUEUE_DEQUEUE(processCB);//先出进程队列 + processCB->priority = prio;//改变进程的优先级 + OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB);//再进入队列,排到新优先级队列的尾部 } else { - processCB->priority = prio; - if (!(processCB->processStatus & OS_PROCESS_STATUS_RUNNING)) { + processCB->priority = prio;//改变优先级,没其他操作了,为什么?因为队列就是给就绪状态准备的,其他状态是没有队列的! + if (!(processCB->processStatus & OS_PROCESS_STATUS_RUNNING)) {//不是就绪也不是运行状态 ret = LOS_OK; - goto EXIT; + goto EXIT;//直接goto退出 } } - SCHEDULER_UNLOCK(intSave); + SCHEDULER_UNLOCK(intSave);//还锁 - LOS_MpSchedule(OS_MP_CPU_ALL); - if (OS_SCHEDULER_ACTIVE) { - LOS_Schedule(); + LOS_MpSchedule(OS_MP_CPU_ALL);// + if (OS_SCHEDULER_ACTIVE) {//当前CPU是否激活了,激活才能调度 + LOS_Schedule();//真正的任务调度算法从LOS_Schedule始 } return LOS_OK; EXIT: - SCHEDULER_UNLOCK(intSave); + SCHEDULER_UNLOCK(intSave);//还锁 return -ret; } diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index b438f1f6..42601d94 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -42,20 +42,20 @@ extern "C" { #endif /* __cplusplus */ extern UINT32 g_taskScheduled; - +//调度标志,一个位代表一个CPU核,这么看鸿蒙最大支持32核,例如:4个CPU,每个4核 就一共16个核,足够了.该标志用于在调用OSStartToRun之前防止内核调度 /* * Schedule flag, one bit represents one core. * This flag is used to prevent kernel scheduling before OSStartToRun. */ #define OS_SCHEDULER_SET(cpuid) do { \ g_taskScheduled |= (1U << (cpuid)); \ -} while (0); +} while (0);//对应位设置为1 #define OS_SCHEDULER_CLR(cpuid) do { \ g_taskScheduled &= ~(1U << (cpuid)); \ -} while (0); +} while (0);//对应位设置为0 -#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) +#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))//代表位上是否为1 typedef enum { INT_NO_RESCH = 0, /* no needs to schedule */ @@ -70,13 +70,15 @@ STATIC INLINE BOOL OsPreemptable(VOID)//是否可抢占 * is called, needs mannually disable interrupt, to prevent current task from * being migrated to another core, and get the wrong preeptable status. */ - UINT32 intSave = LOS_IntLock(); + //与OsPreemptableInSched不同,当OsPreemptable时,中断可能不会被禁用,所以调用时,需要手动禁用中断,以防止当前任务 + //被迁移到另一个CPU核上,并得到错误的可接受状态。 + UINT32 intSave = LOS_IntLock();//手动禁用中断 BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0); if (!preemptable) { /* Set schedule flag if preemption is disabled */ - OsPercpuGet()->schedFlag = INT_PEND_RESCH; + OsPercpuGet()->schedFlag = INT_PEND_RESCH;//如果禁用抢占,则设置调度标志 } - LOS_IntRestore(intSave); + LOS_IntRestore(intSave);//手动恢复中断 return preemptable; } @@ -122,8 +124,8 @@ extern VOID OsSchedPreempt(VOID); */ STATIC INLINE VOID LOS_Schedule(VOID) { - if (OS_INT_ACTIVE) { - OsPercpuGet()->schedFlag = INT_PEND_RESCH; + if (OS_INT_ACTIVE) {//硬件中断是否激活,注意调度是需要切换任务上下文的 + OsPercpuGet()->schedFlag = INT_PEND_RESCH;// return; } @@ -132,7 +134,7 @@ STATIC INLINE VOID LOS_Schedule(VOID) * if neccessary, it will give up the timeslice more in time. * otherwhise, there's no other side effects. */ - OsSchedPreempt(); + OsSchedPreempt();//抢占式调度 } #ifdef __cplusplus diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 653b1050..19652f43 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,6 +1,6 @@ git add -A git commit -m '鸿蒙源码分析系列篇 https://blog.csdn.net/kuangyufei -https://my.oschina.net/u/3751245' + https://my.oschina.net/u/3751245' git push origin git push gitee_origin master git push github_origin master -- GitLab