鸿蒙内核源码分析(CPU篇) | 内核是如何描述CPU的 ?

    百万汉字注解 + 百篇博客分析 -> 鸿蒙内核源码
上级 f9280fc9
...@@ -9,7 +9,7 @@ ...@@ -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 @@ ...@@ -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) * (并发并行篇) | 内核如何管理多个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) * (调度机制篇) | 任务是如何被调度执行的?[< CSDN](https://blog.csdn.net/kuangyufei/article/details/108705968) [ | OSCHINA >](https://my.oschina.net/u/3751245/blog/4623040)
...@@ -158,11 +160,11 @@ ...@@ -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)
### **喜欢就请收藏吧** ### **喜欢就大方 点赞+关注+收藏 吧**
各大站点搜 **"鸿蒙内核源码分析"** ,快速找到组织. 各大站点搜 **"鸿蒙内核源码分析"** ,快速找到组织.
......
...@@ -231,7 +231,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskPriModify(LosTaskCB *taskCB, UINT16 priority) ...@@ -231,7 +231,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskPriModify(LosTaskCB *taskCB, UINT16 priority)
taskCB->priority = priority; taskCB->priority = priority;
} }
} }
//把任务加到定时器链表中 //把任务加到CPU等待链表中
LITE_OS_SEC_TEXT STATIC INLINE VOID OsAdd2TimerList(LosTaskCB *taskCB, UINT32 timeOut) LITE_OS_SEC_TEXT STATIC INLINE VOID OsAdd2TimerList(LosTaskCB *taskCB, UINT32 timeOut)
{ {
SET_SORTLIST_VALUE(&taskCB->sortList, timeOut);//设置idxRollNum的值为timeOut SET_SORTLIST_VALUE(&taskCB->sortList, timeOut);//设置idxRollNum的值为timeOut
......
...@@ -50,15 +50,13 @@ typedef enum { ...@@ -50,15 +50,13 @@ typedef enum {
} ExcFlag; } ExcFlag;
#endif #endif
typedef struct { typedef struct {//内核对cpu的描述
SortLinkAttribute taskSortLink; /* task sort link */ //每个CPU core 都有一个task排序链表 SortLinkAttribute taskSortLink; /* task sort link */ //task wait/delay 排序链表
SortLinkAttribute swtmrSortLink; /* swtmr sort link */ //每个CPU core 都有一个定时器排序链表 SortLinkAttribute swtmrSortLink; /* swtmr sort link */ //定时器排序链表
UINT32 idleTaskID; /* idle task id */ //空闲任务ID 见于 OsIdleTaskCreate UINT32 idleTaskID; /* idle task id */ //空闲任务ID 见于 OsIdleTaskCreate
UINT32 taskLockCnt; /* task lock flag */ //任务锁的数量,当 > 0 的时候,需要重新调度了 UINT32 taskLockCnt; /* task lock flag */ //任务锁的数量,当 > 0 的时候,需要重新调度了
UINT32 swtmrHandlerQueue; /* software timer timeout queue id */ //软时钟超时队列句柄 UINT32 swtmrHandlerQueue; /* software timer timeout queue id */ //软时钟超时队列句柄
UINT32 swtmrTaskID; /* software timer task id */ //软时钟任务ID UINT32 swtmrTaskID; /* software timer task id */ //软时钟任务ID
UINT32 schedFlag; /* pending scheduler flag */ //调度标识 INT_NO_RESCH INT_PEND_RESCH UINT32 schedFlag; /* pending scheduler flag */ //调度标识 INT_NO_RESCH INT_PEND_RESCH
#if (LOSCFG_KERNEL_SMP == YES) #if (LOSCFG_KERNEL_SMP == YES)
UINT32 excFlag; /* cpu halt or exc flag */ //CPU处于停止或运行的标识 UINT32 excFlag; /* cpu halt or exc flag */ //CPU处于停止或运行的标识
......
/* /*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device 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, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* 3. Neither the name of the copyright holder nor the names of its contributors may be used * 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 * to endorse or promote products derived from this software without specific prior written
* permission. * permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _LOS_SCHED_PRI_H #ifndef _LOS_SCHED_PRI_H
#define _LOS_SCHED_PRI_H #define _LOS_SCHED_PRI_H
#include "los_percpu_pri.h" #include "los_percpu_pri.h"
#include "los_hwi.h" #include "los_hwi.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __cplusplus */ #endif /* __cplusplus */
extern UINT32 g_taskScheduled; extern UINT32 g_taskScheduled;
//调度标志,一个位代表一个CPU核,这么看鸿蒙最大支持32核,例如:4个CPU,每个4核 就一共16个核,足够了.该标志用于在调用OSStartToRun之前防止内核调度 //调度标志,一个位代表一个CPU核,这么看鸿蒙最大支持32核,例如:4个CPU,每个4核 就一共16个核,足够了.该标志用于在调用OSStartToRun之前防止内核调度
/* /*
* Schedule flag, one bit represents one core. * Schedule flag, one bit represents one core.
* This flag is used to prevent kernel scheduling before OSStartToRun. * This flag is used to prevent kernel scheduling before OSStartToRun.
*/ */
#define OS_SCHEDULER_SET(cpuid) do { \ #define OS_SCHEDULER_SET(cpuid) do { \
g_taskScheduled |= (1U << (cpuid)); \ g_taskScheduled |= (1U << (cpuid)); \
} while (0);//对应位设置为1 } while (0);//对应位设置为1
#define OS_SCHEDULER_CLR(cpuid) do { \ #define OS_SCHEDULER_CLR(cpuid) do { \
g_taskScheduled &= ~(1U << (cpuid)); \ g_taskScheduled &= ~(1U << (cpuid)); \
} while (0);//对应位设置为0 } while (0);//对应位设置为0
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))//代表位上是否为1 #define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))//代表位上是否为1
typedef enum { typedef enum {
INT_NO_RESCH = 0, /* no needs to schedule */ INT_NO_RESCH = 0, /* no needs to schedule */
INT_PEND_RESCH, /* pending schedule flag */ INT_PEND_RESCH, /* pending schedule flag */
} SchedFlag; } SchedFlag;
/* Check if preemptable with counter flag */ /* Check if preemptable with counter flag */
STATIC INLINE BOOL OsPreemptable(VOID)//是否可抢占 STATIC INLINE BOOL OsPreemptable(VOID)//是否可抢占
{ {
/* /*
* Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable
* is called, needs mannually disable interrupt, to prevent current task from * is called, needs mannually disable interrupt, to prevent current task from
* being migrated to another core, and get the wrong preeptable status. * being migrated to another core, and get the wrong preeptable status.
*/ */
//与OsPreemptableInSched不同,当OsPreemptable时,中断可能不会被禁用,所以调用时,需要手动禁用中断,以防止当前任务 //与OsPreemptableInSched不同,当OsPreemptable时,中断可能不会被禁用,所以调用时,需要手动禁用中断,以防止当前任务
//被迁移到另一个CPU核上,并得到错误的可接受状态。 //被迁移到另一个CPU核上,并得到错误的可接受状态。
UINT32 intSave = LOS_IntLock();//手动禁用中断 UINT32 intSave = LOS_IntLock();//手动禁用中断
BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0); BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0);
if (!preemptable) { if (!preemptable) {
/* Set schedule flag if preemption is disabled */ /* 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; return preemptable;
} }
STATIC INLINE BOOL OsPreemptableInSched(VOID) STATIC INLINE BOOL OsPreemptableInSched(VOID)
{ {
BOOL preemptable = FALSE; BOOL preemptable = FALSE;
#if (LOSCFG_KERNEL_SMP == YES) #if (LOSCFG_KERNEL_SMP == YES)
/* /*
* For smp systems, schedule must hold the task spinlock, and this counter * For smp systems, schedule must hold the task spinlock, and this counter
* will increase by 1 in that case. * will increase by 1 in that case.
*/ */
preemptable = (OsPercpuGet()->taskLockCnt == 1);//SMP时 taskLockCnt=1 才能执行调度任务 preemptable = (OsPercpuGet()->taskLockCnt == 1);//SMP时 taskLockCnt=1 才能执行调度任务
#else #else
preemptable = (OsPercpuGet()->taskLockCnt == 0); preemptable = (OsPercpuGet()->taskLockCnt == 0);
#endif #endif
if (!preemptable) { if (!preemptable) {
/* Set schedule flag if preemption is disabled */ /* Set schedule flag if preemption is disabled */
OsPercpuGet()->schedFlag = INT_PEND_RESCH;//重新调度 OsPercpuGet()->schedFlag = INT_PEND_RESCH;//重新调度
} }
return preemptable; return preemptable;
} }
/* /*
* This function simply picks the next task and switches to it. * This function simply picks the next task and switches to it.
* Current task needs to already be in the right state or the right * Current task needs to already be in the right state or the right
* queues it needs to be in. * queues it needs to be in.
*/ */
extern VOID OsSchedResched(VOID); extern VOID OsSchedResched(VOID);
/* /*
* This function put the current task back to the ready queue and * This function put the current task back to the ready queue and
* try to do the schedule. However, the schedule won't be definitely * try to do the schedule. However, the schedule won't be definitely
* taken place while there're no other higher priority tasks or locked. * taken place while there're no other higher priority tasks or locked.
*/ */
extern VOID OsSchedPreempt(VOID); extern VOID OsSchedPreempt(VOID);
/* /*
* Just like OsSchedPreempt, except this function will do the OS_INT_ACTIVE * 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. * check, in case the schedule taken place in the middle of an interrupt.
*/ */
STATIC INLINE VOID LOS_Schedule(VOID) STATIC INLINE VOID LOS_Schedule(VOID)
{ {
if (OS_INT_ACTIVE) {//硬件中断是否激活,注意调度是需要切换任务上下文的 if (OS_INT_ACTIVE) {//发生硬件中断,调度被阻塞
OsPercpuGet()->schedFlag = INT_PEND_RESCH;// OsPercpuGet()->schedFlag = INT_PEND_RESCH;//
return; return;
} }
/* /*
* trigger schedule in task will also do the slice check * trigger schedule in task will also do the slice check
* if neccessary, it will give up the timeslice more in time. * if neccessary, it will give up the timeslice more in time.
* otherwhise, there's no other side effects. * otherwhise, there's no other side effects.
*/ */
OsSchedPreempt();//抢占式调度 OsSchedPreempt();//抢占式调度
} }
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* _LOS_SCHED_PRI_H */ #endif /* _LOS_SCHED_PRI_H */
...@@ -311,7 +311,7 @@ typedef struct { ...@@ -311,7 +311,7 @@ typedef struct {
CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */ //任务的名称 CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */ //任务的名称
LOS_DL_LIST pendList; /**< Task pend node */ //如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时 LOS_DL_LIST pendList; /**< Task pend node */ //如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时
LOS_DL_LIST threadList; /**< thread list */ //挂到所属进程的线程链表上 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 eventMask; /**< Event mask */ //对哪些事件进行屏蔽
UINT32 eventMode; /**< Event mode */ //事件三种模式(LOS_WAITMODE_AND,LOS_WAITMODE_OR,LOS_WAITMODE_CLR) UINT32 eventMode; /**< Event mode */ //事件三种模式(LOS_WAITMODE_AND,LOS_WAITMODE_OR,LOS_WAITMODE_CLR)
UINT32 priBitMap; /**< BitMap for recording the change of task priority, //任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化 UINT32 priBitMap; /**< BitMap for recording the change of task priority, //任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化
......
git add -A git add -A
git commit -m '鸿蒙内核源码分析(定时器机制篇) | 内核最高优先级任务是谁??? git commit -m '鸿蒙内核源码分析(CPU篇) | 内核是如何描述CPU的 ?
百万汉字注解 + 百篇博客分析 -> 鸿蒙内核源码 百万汉字注解 + 百篇博客分析 -> 鸿蒙内核源码
' '
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册