diff --git a/README.md b/README.md index 6858dfb61d0b68de30df3bea791cb325fb0b2cd4..269290be7febca7a59712de1642a48c7290e4225 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## **百万汉字注解** -**[kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note)** 是在鸿蒙官方开源项目 **[kernel\_liteos\_a](https://gitee.com/openharmony/kernel_liteos_a)** 基础上给源码加上中文注解的版本,目前几大核心模块加注已基本完成, **整体加注完成70%**, 正持续加注完善中 ... +**[kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note)** 是在鸿蒙官方开源项目 **[kernel\_liteos\_a](https://gitee.com/openharmony/kernel_liteos_a)** 基础上给源码加上中文注解的版本,目前几大核心模块加注已基本完成, **整体加注完成70%** ### **为何要精读内核源码?** @@ -67,6 +67,8 @@ ### **进程/线程** +* (CPU篇) | 内核是如何描述CPU的 ?[< CSDN](https://blog.csdn.net/kuangyufei/article/details/113782749) [ | OSCHINA >](https://my.oschina.net/weharmony/blog/4952034) + * (并发并行篇) | 内核如何管理多个CPU?[< CSDN](https://blog.csdn.net/kuangyufei/article/details/113516222) [ | OSCHINA >](https://my.oschina.net/u/3751245/blog/4940329) * (调度机制篇) | 任务是如何被调度执行的?[< CSDN](https://blog.csdn.net/kuangyufei/article/details/108705968) [ | OSCHINA >](https://my.oschina.net/u/3751245/blog/4623040) @@ -158,11 +160,11 @@ ### **参与贡献** -* 1. Fork 本仓库 >> 新建 Feat_xxx 分支 >> 提交代码注解 >> [新建 Pull Request](https://gitee.com/weharmony/kernel_liteos_a_note/pull/new/weharmony:master...weharmony:master) +* Fork 本仓库 >> 新建 Feat_xxx 分支 >> 提交代码注解 >> [新建 Pull Request](https://gitee.com/weharmony/kernel_liteos_a_note/pull/new/weharmony:master...weharmony:master) -* 2. [新建 Issue](https://gitee.com/weharmony/kernel_liteos_a_note/issues) +* [新建 Issue](https://gitee.com/weharmony/kernel_liteos_a_note/issues) -### **喜欢就请收藏吧** +### **喜欢就大方 点赞+关注+收藏 吧** 各大站点搜 **"鸿蒙内核源码分析"** ,快速找到组织. diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index 142bee813df262cdf1b596d8e4275caedb33f366..2a5749d3bfae4898afd3a6151897a6c1249acb53 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -231,7 +231,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskPriModify(LosTaskCB *taskCB, UINT16 priority) taskCB->priority = priority; } } -//把任务加到定时器链表中 +//把任务加到CPU等待链表中 LITE_OS_SEC_TEXT STATIC INLINE VOID OsAdd2TimerList(LosTaskCB *taskCB, UINT32 timeOut) { SET_SORTLIST_VALUE(&taskCB->sortList, timeOut);//设置idxRollNum的值为timeOut diff --git a/kernel/base/include/los_percpu_pri.h b/kernel/base/include/los_percpu_pri.h index 494db97a344f9fdef55f9c74fbb40ed390df737a..53d4ac3b4140602f70de7c61b731a569449f7e09 100644 --- a/kernel/base/include/los_percpu_pri.h +++ b/kernel/base/include/los_percpu_pri.h @@ -50,15 +50,13 @@ typedef enum { } ExcFlag; #endif -typedef struct { - SortLinkAttribute taskSortLink; /* task sort link */ //每个CPU core 都有一个task排序链表 - SortLinkAttribute swtmrSortLink; /* swtmr sort link */ //每个CPU core 都有一个定时器排序链表 - +typedef struct {//内核对cpu的描述 + SortLinkAttribute taskSortLink; /* task sort link */ //task wait/delay 排序链表 + SortLinkAttribute swtmrSortLink; /* swtmr sort link */ //定时器排序链表 UINT32 idleTaskID; /* idle task id */ //空闲任务ID 见于 OsIdleTaskCreate UINT32 taskLockCnt; /* task lock flag */ //任务锁的数量,当 > 0 的时候,需要重新调度了 UINT32 swtmrHandlerQueue; /* software timer timeout queue id */ //软时钟超时队列句柄 UINT32 swtmrTaskID; /* software timer task id */ //软时钟任务ID - UINT32 schedFlag; /* pending scheduler flag */ //调度标识 INT_NO_RESCH INT_PEND_RESCH #if (LOSCFG_KERNEL_SMP == YES) UINT32 excFlag; /* cpu halt or exc flag */ //CPU处于停止或运行的标识 diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index 42601d948d7556620e6a4ff854d28734d9b61657..24a032359b902bafbcc86d7c3390c5a38cf1369a 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -1,146 +1,146 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, 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: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _LOS_SCHED_PRI_H -#define _LOS_SCHED_PRI_H - -#include "los_percpu_pri.h" -#include "los_hwi.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#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);//对应位设置为1 - -#define OS_SCHEDULER_CLR(cpuid) do { \ - g_taskScheduled &= ~(1U << (cpuid)); \ -} while (0);//对应位设置为0 - -#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))//代表位上是否为1 - -typedef enum { - INT_NO_RESCH = 0, /* no needs to schedule */ - INT_PEND_RESCH, /* pending schedule flag */ -} SchedFlag; - -/* Check if preemptable with counter flag */ -STATIC INLINE BOOL OsPreemptable(VOID)//是否可抢占 -{ - /* - * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable - * is called, needs mannually disable interrupt, to prevent current task from - * being migrated to another core, and get the wrong preeptable status. - */ - //与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;//如果禁用抢占,则设置调度标志 - } - LOS_IntRestore(intSave);//手动恢复中断 - return preemptable; -} - -STATIC INLINE BOOL OsPreemptableInSched(VOID) -{ - BOOL preemptable = FALSE; - -#if (LOSCFG_KERNEL_SMP == YES) - /* - * For smp systems, schedule must hold the task spinlock, and this counter - * will increase by 1 in that case. - */ - preemptable = (OsPercpuGet()->taskLockCnt == 1);//SMP时 taskLockCnt=1 才能执行调度任务 - -#else - preemptable = (OsPercpuGet()->taskLockCnt == 0); -#endif - if (!preemptable) { - /* Set schedule flag if preemption is disabled */ - OsPercpuGet()->schedFlag = INT_PEND_RESCH;//重新调度 - } - - return preemptable; -} - -/* - * This function simply picks the next task and switches to it. - * Current task needs to already be in the right state or the right - * queues it needs to be in. - */ -extern VOID OsSchedResched(VOID); - -/* - * This function put the current task back to the ready queue and - * try to do the schedule. However, the schedule won't be definitely - * taken place while there're no other higher priority tasks or locked. - */ -extern VOID OsSchedPreempt(VOID); - -/* - * Just like OsSchedPreempt, except this function will do the OS_INT_ACTIVE - * check, in case the schedule taken place in the middle of an interrupt. - */ -STATIC INLINE VOID LOS_Schedule(VOID) -{ - if (OS_INT_ACTIVE) {//硬件中断是否激活,注意调度是需要切换任务上下文的 - OsPercpuGet()->schedFlag = INT_PEND_RESCH;// - return; - } - - /* - * trigger schedule in task will also do the slice check - * if neccessary, it will give up the timeslice more in time. - * otherwhise, there's no other side effects. - */ - OsSchedPreempt();//抢占式调度 -} - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_SCHED_PRI_H */ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SCHED_PRI_H +#define _LOS_SCHED_PRI_H + +#include "los_percpu_pri.h" +#include "los_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#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);//对应位设置为1 + +#define OS_SCHEDULER_CLR(cpuid) do { \ + g_taskScheduled &= ~(1U << (cpuid)); \ +} while (0);//对应位设置为0 + +#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))//代表位上是否为1 + +typedef enum { + INT_NO_RESCH = 0, /* no needs to schedule */ + INT_PEND_RESCH, /* pending schedule flag */ +} SchedFlag; + +/* Check if preemptable with counter flag */ +STATIC INLINE BOOL OsPreemptable(VOID)//是否可抢占 +{ + /* + * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable + * is called, needs mannually disable interrupt, to prevent current task from + * being migrated to another core, and get the wrong preeptable status. + */ + //与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;//如果禁用抢占,则设置调度标志 + } + LOS_IntRestore(intSave);//手动恢复中断 + return preemptable; +} + +STATIC INLINE BOOL OsPreemptableInSched(VOID) +{ + BOOL preemptable = FALSE; + +#if (LOSCFG_KERNEL_SMP == YES) + /* + * For smp systems, schedule must hold the task spinlock, and this counter + * will increase by 1 in that case. + */ + preemptable = (OsPercpuGet()->taskLockCnt == 1);//SMP时 taskLockCnt=1 才能执行调度任务 + +#else + preemptable = (OsPercpuGet()->taskLockCnt == 0); +#endif + if (!preemptable) { + /* Set schedule flag if preemption is disabled */ + OsPercpuGet()->schedFlag = INT_PEND_RESCH;//重新调度 + } + + return preemptable; +} + +/* + * This function simply picks the next task and switches to it. + * Current task needs to already be in the right state or the right + * queues it needs to be in. + */ +extern VOID OsSchedResched(VOID); + +/* + * This function put the current task back to the ready queue and + * try to do the schedule. However, the schedule won't be definitely + * taken place while there're no other higher priority tasks or locked. + */ +extern VOID OsSchedPreempt(VOID); + +/* + * Just like OsSchedPreempt, except this function will do the OS_INT_ACTIVE + * check, in case the schedule taken place in the middle of an interrupt. + */ +STATIC INLINE VOID LOS_Schedule(VOID) +{ + if (OS_INT_ACTIVE) {//发生硬件中断,调度被阻塞 + OsPercpuGet()->schedFlag = INT_PEND_RESCH;// + return; + } + + /* + * trigger schedule in task will also do the slice check + * if neccessary, it will give up the timeslice more in time. + * otherwhise, there's no other side effects. + */ + OsSchedPreempt();//抢占式调度 +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SCHED_PRI_H */ diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h index c5233a8d6f5c50c43d2984c750cc075ca361a7dd..da09fae9763ff7ee5b9fcc14d2601aeb2c84f4c7 100644 --- a/kernel/base/include/los_task_pri.h +++ b/kernel/base/include/los_task_pri.h @@ -311,7 +311,7 @@ typedef struct { CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */ //任务的名称 LOS_DL_LIST pendList; /**< Task pend node */ //如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时 LOS_DL_LIST threadList; /**< thread list */ //挂到所属进程的线程链表上 - SortLinkList sortList; /**< Task sortlink node */ //挂到cpu core 的任务执行链表上 + SortLinkList sortList; /**< Task sortlink node */ //task wait,delay时挂到cpu core的taskSortLink链表上 UINT32 eventMask; /**< Event mask */ //对哪些事件进行屏蔽 UINT32 eventMode; /**< Event mode */ //事件三种模式(LOS_WAITMODE_AND,LOS_WAITMODE_OR,LOS_WAITMODE_CLR) UINT32 priBitMap; /**< BitMap for recording the change of task priority, //任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化 diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 314ca8ebb9008d3f91f4f6a1e6138ed304051ac0..c0b50a3846a026085721a003b43ecac897056537 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,5 +1,5 @@ git add -A -git commit -m '鸿蒙内核源码分析(定时器机制篇) | 内核最高优先级任务是谁??? +git commit -m '鸿蒙内核源码分析(CPU篇) | 内核是如何描述CPU的 ? 百万汉字注解 + 百篇博客分析 -> 鸿蒙内核源码 '