静态内存管理中节点处的实现很巧妙,点赞!

搜索 @note_pic 方便理解画的字符图
搜索 @note_why 尚未看明白的地方,如果您看明白了,请告知完善
搜索 @note_thinking 一点思考和吐槽的地方
搜索 @note_#if0 由第三方项目提供不由内核源码中定义的极为重要的结构体,为方便理解而添加的
搜索 @note_good 给源码点赞
上级 90a0c35d
......@@ -15,12 +15,16 @@
- ### **为何想给鸿蒙源码加上中文注释**
源于大学时阅读linux 2.6 内核痛苦经历,一直有个心愿,如何让更多对内核感兴趣的同学减少阅读时间,加速对计算机系统级的理解,而不至于过早的放弃.但因过程种种,一直没有行动,基本要放弃这件事了. 但 2020/9/10 鸿蒙正式开源,重新激活了注者多年的心愿,就有那么点一发不可收拾了. 然工作量巨大,知识点巨多,期间会反复修正完善,力求言简意赅,词达本意.肯定会有诸多错漏之处,请多包涵. :|P
源于大学时阅读linux 2.6 内核痛苦经历,一直有个心愿,如何让更多对内核感兴趣的同学减少阅读时间,加速对计算机系统级的理解,而不至于过早的放弃.但因过程种种,一直没有行动,基本要放弃这件事了. 但 2020/9/10 鸿蒙正式开源,重新激活了注者多年的心愿,就有那么点一发不可收拾了. :|P
- ### **致敬鸿蒙内核开发者**
感谢开放原子开源基金会,鸿蒙内核开发者提供了如此优秀的源码,一了多年的夙愿,津津乐道于此.越深入精读内核源码,越能感受到设计者的精巧用心,创新突破, 向开发者致敬. 可以毫不夸张的说鸿蒙内核源码可作为大学C语言,数据结构,操作系统,汇编语言 四门课程的教学项目.如此宝库,不深入研究实在是暴殄天物,于心不忍.
- ### **通过fork及时同步最新注解内容**
注解几乎占用了所有的空闲时间,每天都在更新,注者本人每天对内核源码都有新感悟,一行行源码在不断的刷新和拓展对内核知识的认知边界. 对已经关注和fork的同学请及时同步最新的注解内容. 内核知识点体量实在太过巨大,过程会反复修正完善,力求言简意赅,词达本意.肯定会有诸多错漏之处,请多包涵. :)
- ### **在加注的源码中有哪些特殊的记号**
搜索 **[@note_pic]()** 可查看绘制的全部字符图
......@@ -45,41 +49,49 @@
第二: **专业概念抽象级** 对抽象的专业逻辑概念具体化认知, 比如虚拟内存,老百姓是听不懂的,学过计算机的人都懂,具体怎么实现的很多人又都不懂了,但这并不妨碍成为一个优秀的上层应用程序员,因为虚拟内存已经被抽象出来,目的是要屏蔽上层对它的现实认知.笔者试图用 **[鸿蒙源码分析系列篇 【 CSDN](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages)** 去拆解那些已经被抽象出来的专业概念, 希望能卷入更多对内核感兴趣的应用软件人才流入基础软件生态, 应用软件咱们是无敌宇宙,但基础软件却很薄弱.
第三: **具体微观代码级** 这一级是具体到每一行代码的实现,到了用代码指令级的地步,这段代码是什么意思?为什么要这么设计? **[kernel\_liteos\_a_note:鸿蒙内核源码注释中文版](https://gitee.com/weharmony/kernel_liteos_a_note)** 试图从细微处去解释代码实现层,英文真的是天生适合设计成编程语言的人类语言,计算机的01码映射到人类世界的26个字母,诞生了太多的伟大奇迹.但我们的母语注定了很大部分人存在着自然语言层级的理解映射,希望注释中文版能让更多爱好者快速的理解内核.
鸿蒙是面向未来设计的系统,高瞻远瞩,格局远大,设计精良, 海量知识点, 目前做的只是冰山一角,把研究过程心得写成鸿蒙源码分析系列篇,如此源码中文注释+系列篇文章 将加速理解鸿蒙内核实现过程.
第三: **具体微观代码级** 这一级是具体到每一行代码的实现,到了用代码指令级的地步,这段代码是什么意思?为什么要这么设计? **[kernel\_liteos\_a_note:鸿蒙内核源码注释中文版](https://gitee.com/weharmony/kernel_liteos_a_note)** 试图从细微处去解释代码实现层,英文真的是天生适合设计成编程语言的人类语言,计算机的01码映射到人类世界的26个字母,诞生了太多的伟大奇迹.但我们的母语注定了很大部分人存在着自然语言层级的理解映射,希望注释中文版能让更多爱好者快速的理解内核,共同进步.
- ### **加注释方式是怎样的?**
因鸿蒙内核6W+代码量,本身只有很少的注释, 中文注解以不对原有代码侵入为前提,源码中所有英文部分都是原有鸿蒙注释,所有中文部分都是笔者的注释,尽量不去增加代码的行数,不破坏文件的结构,笔者试图把知识讲透彻,注释多类似以下的方式, 如图举例: 这是申请互斥锁的主体函数,不可谓不重要,而官方注释仅有一行.
因鸿蒙内核6W+代码量,本身只有较少的注释, 中文注解以不对原有代码侵入为前提,源码中所有英文部分都是原有鸿蒙注释,所有中文部分都是笔者的注释,尽量不去增加代码的行数,不破坏文件的结构,笔者试图把知识讲透彻,注释多类似以下的方式:
在每个模块的.c文件开始位置先对模块功能做整体的介绍,例如异常接管模块注解 如图所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210104173532255.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2t1YW5neXVmZWk=,size_16,color_FFFFFF,t_70)
注解过程中查阅了很多的资料和书籍,在具体代码处都附上了参考链接.
而函数级注解会详细到重点行,甚至每一行, 例如申请互斥锁的主体函数,不可谓不重要,而官方注释仅有一行,如图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020102821375267.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2t1YW5neXVmZWk=,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210104173532225.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2t1YW5neXVmZWk=,size_16,color_FFFFFF,t_70)
另外用字符画了一些图方便理解,直接嵌入到头文件中,比如虚拟内存的全景图,因没有这些图是很难理解内存是如何管理的,后续还会陆续加入更多的图方便理解.
另外画了一些字符图方便理解,直接嵌入到头文件中,比如虚拟内存的全景图,因没有这些图是很难理解虚拟内存是如何管理的.
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201028154344813.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2t1YW5neXVmZWk=,size_16,color_FFFFFF,t_70#pic_center)
- ### **系列博客更新到哪里了?**
鸿蒙是面向未来设计的系统,高瞻远瞩,格局远大,设计精良, 海量知识点, 目前做的只是冰山一角,把研究过程心得写成鸿蒙源码分析系列篇,如此源码中文注释+系列篇文章,将加速理解鸿蒙内核实现过程,因时间有限,博文更新较慢,会反复修正.
- **[鸿蒙源码分析系列(总目录) | 持续更新中... 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4626852)**
* **[|- 鸿蒙内核源码分析(源码结构篇) | 内核500问你能答对多少? 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/111938348) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4869137)**
* **[|- 鸿蒙内核源码分析(物理内存篇) | 伙伴算法像极了在卖标准猪肉块【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/111765600) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4842408)**
* **[|- 鸿蒙内核源码分析(物理内存篇) | 伙伴算法是在卖标准猪肉块吗?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/111765600) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4842408)**
* **[|- 鸿蒙内核源码分析(内存规则篇) | 内存管理到底在管什么?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/109437223) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4698384)**
* **[|- 鸿蒙内核源码分析(源码注释篇) | 精读内核源码有哪些好处?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/109251754) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4686747)**
* **[|- 鸿蒙内核源码分析(内存映射篇) | 虚拟内存<->物理内存是怎么映射的?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/109032636) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4694841)**
* **[|- 鸿蒙内核源码分析(内存映射篇) | 虚拟内存-物理内存是如何映射的?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/109032636) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4694841)**
* **[|- 鸿蒙内核源码分析(内存汇编篇) | 内存实现涉及哪些汇编代码?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108994081) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4692156)**
* **[|- 鸿蒙内核源码分析(内存汇编篇) | 什么是虚拟内存的实现基础?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108994081) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4692156)**
* **[|- 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108989906) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4646802)**
* **[|- 鸿蒙内核源码分析(内存管理篇) | 虚拟内存和物理内存是怎么管理的?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108821442) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4652284)**
* **[|- 鸿蒙内核源码分析(内存管理篇) | 鸿蒙虚拟内存全景图是怎样的?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108821442) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4652284)**
* **[|- 鸿蒙内核源码分析(内存概念篇) | 手眼通天的虚拟内存【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108723672) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4646802)**
* **[|- 鸿蒙内核源码分析(内存概念篇) | 虚拟内存虚在哪里?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108723672) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4646802)**
* **[|- 鸿蒙内核源码分析(必读故事篇) | 张大爷的故事 | 用故事说内核持续更新中...【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108745174) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4634668)**
......@@ -89,7 +101,7 @@
* **[|- 鸿蒙内核源码分析(任务管理篇) | 任务是内核调度的单元【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108621428) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4603919)**
* **[|- 鸿蒙内核源码分析(时钟管理篇) | 触发调度最大的源动力【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108603468) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4574493)**
* **[|- 鸿蒙内核源码分析(时钟管理篇) | 触发调度最大的动力来自哪里?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108603468) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4574493)**
* **[|- 鸿蒙内核源码分析(进程管理篇) | 进程是内核资源管理单元【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108595941) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4574429)**
......
......@@ -68,7 +68,6 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/******************************************************************************
基本概念
异常接管是操作系统对运行期间发生的异常情况(芯片硬件异常)进行处理的一系列动作,
......@@ -105,6 +104,9 @@ extern "C" {
注意事项
要查看调用栈信息,必须添加编译选项宏-fno-omit-frame-pointer支持stack frame,否则编译时FP寄存器是关闭的。
参考
https://gitee.com/LiteOS/LiteOS/blob/master/doc/Huawei_LiteOS_Kernel_Developer_Guide_zh.md
******************************************************************************/
#define INVALID_CPUID 0xFFFF
#define OS_EXC_VMM_NO_REGION 0x0U
......@@ -867,20 +869,20 @@ STATIC VOID OsAllCpuStatusOutput(VOID)
for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {
switch (g_percpu[i].excFlag) {
case CPU_RUNNING:
case CPU_RUNNING://处于运行状态
PrintExcInfo("cpu%u is running.\n", i);
break;
case CPU_HALT:
case CPU_HALT://处于停止状态
PrintExcInfo("cpu%u is halted.\n", i);
break;
case CPU_EXC:
case CPU_EXC://处于异常接管状态
PrintExcInfo("cpu%u is in exc.\n", i);
break;
default:
break;
}
}
PrintExcInfo("The current handling the exception is cpu%u !\n", ArchCurrCpuid());
PrintExcInfo("The current handling the exception is cpu%u !\n", ArchCurrCpuid());//当前正在处理异常的CPU是:
}
//等待所有CPU停止
STATIC VOID WaitAllCpuStop(UINT32 cpuID)
......@@ -923,13 +925,13 @@ STATIC VOID OsWaitOtherCoresHandleExcEnd(UINT32 currCpuID)
LOS_Mdelay(EXC_WAIT_INTER);
}
}
//检查所CPU的状态
//检查所CPU的状态
STATIC VOID OsCheckAllCpuStatus(UINTPTR taskStackPointer)
{
UINT32 currCpuID = ArchCurrCpuid();
UINT32 ret, target;
OsPercpuGet()->excFlag = CPU_EXC;
OsPercpuGet()->excFlag = CPU_EXC;//CPU处于异常接管状态
LOCKDEP_CLEAR_LOCKS();
LOS_SpinLock(&g_excSerializerSpin);
......
......@@ -192,14 +192,14 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
swtmr->usTimerID = index;//按顺序赋值
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表
}
//想要用静态内存池管理,就必须要使用LOS_MEMBOX_SIZE来计算申请的内存大小,因为需要点前缀内存承载头部信息.
swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//计算所有注册函数内存大小
//规划一片内存区域作为软时钟处理函数的静态内存池。
g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource *///常驻内存
if (g_swtmrHandlerPool == NULL) {
return LOS_ERRNO_SWTMR_NO_MEMORY;
}
ret = LOS_MemboxInit(g_swtmrHandlerPool, swtmrHandlePoolSize, sizeof(SwtmrHandlerItem));//初始化软时钟注册池
if (ret != LOS_OK) {
return LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM;
......@@ -294,7 +294,7 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID)//扫描定时器,如果碰到超时的,
LOS_ListDelete(&sortList->sortLinkNode);
swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool);
swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool);//取出一个可用的软时钟处理项
if (swtmrHandler != NULL) {
swtmrHandler->handler = swtmr->pfnHandler;
swtmrHandler->arg = swtmr->uwArg;
......
/*
* 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_PERCPU_PRI_H
#define _LOS_PERCPU_PRI_H
#include "los_base.h"
#include "los_hw_cpu.h"
#include "los_sortlink_pri.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#if (LOSCFG_KERNEL_SMP == YES)
typedef enum {
CPU_RUNNING = 0, /* cpu is running */ //CPU正在运行状态
CPU_HALT, /* cpu in the halt */ //CPU处于空闲状态
CPU_EXC /* cpu in the exc */ //CPU处于异常状态
} ExcFlag;
#endif
typedef struct {
SortLinkAttribute taskSortLink; /* task sort link */ //每个CPU core 都有一个task排序链表
SortLinkAttribute swtmrSortLink; /* swtmr sort link */ //每个CPU core 都有一个定时器排序链表
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处于停止或运行的标识
#endif
} Percpu;
/* the kernel per-cpu structure */
extern Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM];//每个cpu的内核描述符
//获得当前运行CPU的信息
STATIC INLINE Percpu *OsPercpuGet(VOID)
{
return &g_percpu[ArchCurrCpuid()];
}
//获得参数CPU的信息
STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid)
{
return &g_percpu[cpuid];
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_PERCPU_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_PERCPU_PRI_H
#define _LOS_PERCPU_PRI_H
#include "los_base.h"
#include "los_hw_cpu.h"
#include "los_sortlink_pri.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#if (LOSCFG_KERNEL_SMP == YES)
typedef enum {
CPU_RUNNING = 0, /* cpu is running */ //CPU正在运行状态
CPU_HALT, /* cpu in the halt */ //CPU处于暂停状态
CPU_EXC /* cpu in the exc */ //CPU处于异常状态
} ExcFlag;
#endif
typedef struct {
SortLinkAttribute taskSortLink; /* task sort link */ //每个CPU core 都有一个task排序链表
SortLinkAttribute swtmrSortLink; /* swtmr sort link */ //每个CPU core 都有一个定时器排序链表
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处于停止或运行的标识
#endif
} Percpu;
/* the kernel per-cpu structure */
extern Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM];//每个cpu的内核描述符
//获得当前运行CPU的信息
STATIC INLINE Percpu *OsPercpuGet(VOID)
{
return &g_percpu[ArchCurrCpuid()];
}
//获得参数CPU的信息
STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid)
{
return &g_percpu[cpuid];
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_PERCPU_PRI_H */
......@@ -395,7 +395,7 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
/* This is for mutex macro initialization. */
mutex->muxCount = 0;//锁计数器清0
mutex->owner = NULL;//锁没有归属任务
LOS_ListInit(&mutex->muxList);//初始化mux链表[]
LOS_ListInit(&mutex->muxList);//初始化锁的任务链表,后续申请这把锁任务都会挂上去
}
if (mutex->muxCount == 0) {//无task用锁时,肯定能拿到锁了.在里面返回
......@@ -405,7 +405,7 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
if ((runTask->priority > mutex->attr.prioceiling) && (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT)) {//看保护协议的做法是怎样的?
LOS_BitmapSet(&runTask->priBitMap, runTask->priority);//1.priBitMap是记录任务优先级变化的位图,这里把任务当前的优先级记录在priBitMap
OsTaskPriModify(runTask, mutex->attr.prioceiling);//2.把高优先级的mutex->attr.prioceiling设为当前任务的优先级.
}//注意任务优先级有32个, 是0最高,31最低!!!这里等于提高了任务的优先级,目的是让其在下次调度中继续提高被选中的概率,从而快速的释放锁.您明白了吗? :|)
}//注意任务优先级有32个, 是0最高,31最低!!!这里等于提高了任务的优先级,目的是让其在下次调度中继续提高被选中的概率,从而快速的释放锁.
return LOS_OK;
}
//递归锁muxCount>0 如果是递归锁就要处理两种情况 1.runtask持有锁 2.锁被别的任务拿走了
......@@ -422,11 +422,11 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
return LOS_EDEADLK;//返回错误,自旋锁被别的CPU core 持有
}
OsMuxBitmapSet(mutex, runTask, (LosTaskCB *)mutex->owner);//设置bitmap,尽可能的提高锁持有任务的优先级
OsMuxBitmapSet(mutex, runTask, (LosTaskCB *)mutex->owner);//设置锁位图,尽可能的提高锁持有任务的优先级
owner = (LosTaskCB *)mutex->owner; //记录持有锁的任务
runTask->taskMux = (VOID *)mutex; //记下当前任务在等待这把锁
node = OsMuxPendFindPos(runTask, mutex);//在都等锁阻塞链表上找一个适当的位置,在OsTaskWait中把自己从这个入口挂上去
node = OsMuxPendFindPos(runTask, mutex);//在等锁链表中找到一个优先级比当前任务更低的任务
ret = OsTaskWait(node, timeout, TRUE);//task陷入等待状态 TRUE代表需要调度
if (ret == LOS_ERRNO_TSK_TIMEOUT) {//这行代码虽和OsTaskWait挨在一起,但要过很久才会执行到,因为在OsTaskWait中CPU切换了任务上下文
runTask->taskMux = NULL;// 所以重新回到这里时可能已经超时了
......@@ -434,7 +434,7 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
}
if (timeout != LOS_WAIT_FOREVER) {//不是永远等待的情况
OsMuxBitmapRestore(mutex, runTask, owner);//恢复bitmap
OsMuxBitmapRestore(mutex, runTask, owner);//恢复锁的位图
}
return ret;
......
......@@ -57,28 +57,27 @@ extern "C" {
注意事项
静态内存池区域,如果是通过动态内存分配方式获得的,在不需要静态内存池时,
需要释放该段内存,避免发生内存泄露。
静态内存不常用,因为需要使用者去确保不会超出使用范围
******************************************************************************/
#ifdef LOSCFG_AARCH64
#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5
#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 //魔法数字,@note_good 点赞,设计的很精巧,node内容从下一个节点地址变成魔法数字
#else
#define OS_MEMBOX_MAGIC 0xa55a5aa5
#define OS_MEMBOX_MAGIC 0xa55a5aa5
#endif
#define OS_MEMBOX_SET_MAGIC(addr) \
((LOS_MEMBOX_NODE *)(addr))->pstNext = (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC
((LOS_MEMBOX_NODE *)(addr))->pstNext = (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC //设置魔法数字
#define OS_MEMBOX_CHECK_MAGIC(addr) \
((((LOS_MEMBOX_NODE *)(addr))->pstNext == (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK)
#define OS_MEMBOX_USER_ADDR(addr) \
((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE))
((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE)) //@note_good 使用之前要去掉节点信息,太赞了! 很艺术化!!
#define OS_MEMBOX_NODE_ADDR(addr) \
((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE))
((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) //释放之前要加上节点信息
/* spinlock for mem module, only available on SMP mode */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memboxSpin);
#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state))
#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state))
//检查静态内存块
STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node)
{
UINT32 offset;
......@@ -96,12 +95,12 @@ STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *n
return LOS_NOK;
}
return OS_MEMBOX_CHECK_MAGIC(node);
return OS_MEMBOX_CHECK_MAGIC(node);//检查魔法数字是否被修改过了
}
//初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;//在内存起始处放置控制头
LOS_MEMBOX_NODE *node = NULL;
UINT32 index;
UINT32 intSave;
......@@ -124,29 +123,29 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32
MEMBOX_UNLOCK(intSave);
return LOS_NOK;
}
boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize;
boxInfo->uwBlkCnt = 0;
if (boxInfo->uwBlkNum == 0) {
boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize;//分块
boxInfo->uwBlkCnt = 0; //已分配的数量
if (boxInfo->uwBlkNum == 0) {//只有0块的情况
MEMBOX_UNLOCK(intSave);
return LOS_NOK;
}
node = (LOS_MEMBOX_NODE *)(boxInfo + 1);
node = (LOS_MEMBOX_NODE *)(boxInfo + 1);//去除控制头,找到第一个节点
boxInfo->stFreeList.pstNext = node;
boxInfo->stFreeList.pstNext = node;//头结点指向boxInfo长度尾部位置
for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) {
node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize);
node = node->pstNext;
node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize);//按块大小切割好,统一由pstNext指向
node = node->pstNext;//node存储了下一个节点的地址信息
}
node->pstNext = NULL;
node->pstNext = NULL;//最后一个为null
MEMBOX_UNLOCK(intSave);
return LOS_OK;
}
//从指定的静态内存池中申请一块静态内存块
//从指定的静态内存池中申请一块静态内存块,整个内核源码只有 OsSwtmrScan中用到了静态内存.
LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
......@@ -159,16 +158,16 @@ LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool)
}
MEMBOX_LOCK(intSave);
node = &(boxInfo->stFreeList);
if (node->pstNext != NULL) {
nodeTmp = node->pstNext;
node->pstNext = nodeTmp->pstNext;
OS_MEMBOX_SET_MAGIC(nodeTmp);
boxInfo->uwBlkCnt++;
node = &(boxInfo->stFreeList);//拿到空闲单链表
if (node->pstNext != NULL) {//不需要遍历链表,因为这是空闲链表
nodeTmp = node->pstNext;//先记录要使用的节点
node->pstNext = nodeTmp->pstNext;//不再空闲了,把节点摘出去了.
OS_MEMBOX_SET_MAGIC(nodeTmp);//设置节点魔法数字
boxInfo->uwBlkCnt++;//已使用块数增加
}
MEMBOX_UNLOCK(intSave);
return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp);
return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp);//返回可用的内存地址
}
//释放指定的一块静态内存块
LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box)
......@@ -183,16 +182,16 @@ LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box)
MEMBOX_LOCK(intSave);
do {
LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);
LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);//归还静态内存
if (OsCheckBoxMem(boxInfo, node) != LOS_OK) {
break;
}
node->pstNext = boxInfo->stFreeList.pstNext;
node->pstNext = boxInfo->stFreeList.pstNext;//将节点挂入单向链表
boxInfo->stFreeList.pstNext = node;
boxInfo->uwBlkCnt--;
boxInfo->uwBlkCnt--;//已经使用的内存块减一
ret = LOS_OK;
} while (0);
} while (0);//将被编译时优化
MEMBOX_UNLOCK(intSave);
return ret;
......@@ -205,7 +204,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box)
if ((pool == NULL) || (box == NULL)) {
return;
}
//将魔法数字一并清除了.
(VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0,
(boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE));
}
......
/*
* 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.
*/
/**
* @defgroup los_membox Static memory
* @ingroup kernel
*/
#ifndef _LOS_MEMBOX_H
#define _LOS_MEMBOX_H
#include "los_config.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_MEMBOX_NEXT(addr, blkSize) (LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) + (blkSize))
#define OS_MEMBOX_NODE_HEAD_SIZE sizeof(LOS_MEMBOX_NODE)
/**
* @ingroup los_membox
* Structure of a free node in a memory pool
*/
typedef struct tagMEMBOX_NODE {
struct tagMEMBOX_NODE *pstNext; /**< Free node's pointer to the next node in a memory pool */
} LOS_MEMBOX_NODE;
/**
* @ingroup los_membox
* Memory pool information structure
*/
typedef struct {
UINT32 uwBlkSize; /**< Block size */
UINT32 uwBlkNum; /**< Block number */
UINT32 uwBlkCnt; /**< The number of allocated blocks */
LOS_MEMBOX_NODE stFreeList; /**< Free list */
} LOS_MEMBOX_INFO;
typedef LOS_MEMBOX_INFO OS_MEMBOX_S;
/**
* @ingroup los_membox
* Memory pool alignment
*/
#define LOS_MEMBOX_ALLIGNED(memAddr) (((UINTPTR)(memAddr) + sizeof(UINTPTR) - 1) & (~(sizeof(UINTPTR) - 1)))
/**
* @ingroup los_membox
* Memory pool size
*/
#define LOS_MEMBOX_SIZE(blkSize, blkNum) \
(sizeof(LOS_MEMBOX_INFO) + (LOS_MEMBOX_ALLIGNED((blkSize) + OS_MEMBOX_NODE_HEAD_SIZE) * (blkNum)))
/**
* @ingroup los_membox
* @brief Initialize a memory pool.
*
* @par Description:
* <ul>
* <li>This API is used to initialize a memory pool.</li>
* </ul>
* @attention
* <ul>
* <li>The poolSize parameter value should match the following two conditions :
* 1) Be less than or equal to the Memory pool size;
* 2) Be greater than the size of LOS_MEMBOX_INFO.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
* @param poolSize [IN] Memory pool size.
* @param blkSize [IN] Memory block size.
*
* @retval #LOS_NOK The memory pool fails to be initialized.
* @retval #LOS_OK The memory pool is successfully initialized.
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see None.
*/
extern UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize);
/**
* @ingroup los_membox
* @brief Request a memory block.
*
* @par Description:
* <ul>
* <li>This API is used to request a memory block.</li>
* </ul>
* @attention
* <ul>
* <li>The input pool parameter must be initialized via func LOS_MemboxInit.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
*
* @retval #VOID* The request is accepted, and return a memory block address.
* @retval #NULL The request fails.
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see LOS_MemboxFree
*/
extern VOID *LOS_MemboxAlloc(VOID *pool);
/**
* @ingroup los_membox
* @brief Free a memory block.
*
* @par Description:
* <ul>
* <li>This API is used to free a memory block.</li>
* </ul>
* @attention
* <ul>
* <li>The input pool parameter must be initialized via func LOS_MemboxInit.</li>
* <li>The input box parameter must be allocated by LOS_MemboxAlloc.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
* @param box [IN] Memory block address.
*
* @retval #LOS_NOK This memory block fails to be freed.
* @retval #LOS_OK This memory block is successfully freed.
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see LOS_MemboxAlloc
*/
extern UINT32 LOS_MemboxFree(VOID *pool, VOID *box);
/**
* @ingroup los_membox
* @brief Clear a memory block.
*
* @par Description:
* <ul>
* <li>This API is used to set the memory block value to be 0.</li>
* </ul>
* @attention
* <ul>
* <li>The input pool parameter must be initialized via func LOS_MemboxInit.</li>
* <li>The input box parameter must be allocated by LOS_MemboxAlloc.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
* @param box [IN] Memory block address.
*
* @retval VOID
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see None.
*/
extern VOID LOS_MemboxClr(VOID *pool, VOID *box);
/**
* @ingroup los_membox
* @brief show membox info.
*
* @par Description:
* <ul>
* <li>This API is used to show the memory pool info.</li>
* </ul>
* @attention
* <ul>
* <li>The input pool parameter must be initialized via func LOS_MemboxInit.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
*
* @retval VOID
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see None.
*/
extern VOID LOS_ShowBox(VOID *pool);
/**
* @ingroup los_membox
* @brief calculate membox information.
*
* @par Description:
* <ul>
* <li>This API is used to calculate membox information.</li>
* </ul>
* @attention
* <ul>
* <li>One parameter of this interface is a pointer, it should be a correct value, otherwise, the system may
* be abnormal.</li>
* </ul>
*
* @param boxMem [IN] Type #VOID* Pointer to the calculate membox.
* @param maxBlk [OUT] Type #UINT32* Record membox max block.
* @param blkCnt [OUT] Type #UINT32* Record membox block count alreay allocated.
* @param blkSize [OUT] Type #UINT32* Record membox block size.
*
* @retval #LOS_OK The heap status calculate success.
* @retval #LOS_NOK The membox status calculate with some error.
* @par Dependency:
* <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
* @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemFree
*/
extern UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, UINT32 *blkCnt, UINT32 *blkSize);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_MEMBOX_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.
*/
/**
* @defgroup los_membox Static memory
* @ingroup kernel
*/
#ifndef _LOS_MEMBOX_H
#define _LOS_MEMBOX_H
#include "los_config.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_MEMBOX_NEXT(addr, blkSize) (LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) + (blkSize))
#define OS_MEMBOX_NODE_HEAD_SIZE sizeof(LOS_MEMBOX_NODE)
/**
* @ingroup los_membox
* Structure of a free node in a memory pool
*/
typedef struct tagMEMBOX_NODE { //内存池中空闲节点的结构,是个单向的链表
struct tagMEMBOX_NODE *pstNext; /**< Free node's pointer to the next node in a memory pool *///指向内存池中下一个空闲节点的指针
} LOS_MEMBOX_NODE;
/**
* @ingroup los_membox
* Memory pool information structure
*/
typedef struct {//静态内存池信息结构体
UINT32 uwBlkSize; /**< Block size */ //块大小
UINT32 uwBlkNum; /**< Block number */ //块数量
UINT32 uwBlkCnt; /**< The number of allocated blocks */ //已经被分配的块数量
LOS_MEMBOX_NODE stFreeList; /**< Free list */ //空闲链表
} LOS_MEMBOX_INFO;
typedef LOS_MEMBOX_INFO OS_MEMBOX_S;
/**
* @ingroup los_membox
* Memory pool alignment
*/
#define LOS_MEMBOX_ALLIGNED(memAddr) (((UINTPTR)(memAddr) + sizeof(UINTPTR) - 1) & (~(sizeof(UINTPTR) - 1)))
/**
* @ingroup los_membox
* Memory pool size
*/
#define LOS_MEMBOX_SIZE(blkSize, blkNum) \
(sizeof(LOS_MEMBOX_INFO) + (LOS_MEMBOX_ALLIGNED((blkSize) + OS_MEMBOX_NODE_HEAD_SIZE) * (blkNum)))
/**
* @ingroup los_membox
* @brief Initialize a memory pool.
*
* @par Description:
* <ul>
* <li>This API is used to initialize a memory pool.</li>
* </ul>
* @attention
* <ul>
* <li>The poolSize parameter value should match the following two conditions :
* 1) Be less than or equal to the Memory pool size;
* 2) Be greater than the size of LOS_MEMBOX_INFO.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
* @param poolSize [IN] Memory pool size.
* @param blkSize [IN] Memory block size.
*
* @retval #LOS_NOK The memory pool fails to be initialized.
* @retval #LOS_OK The memory pool is successfully initialized.
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see None.
*/
extern UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize);
/**
* @ingroup los_membox
* @brief Request a memory block.
*
* @par Description:
* <ul>
* <li>This API is used to request a memory block.</li>
* </ul>
* @attention
* <ul>
* <li>The input pool parameter must be initialized via func LOS_MemboxInit.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
*
* @retval #VOID* The request is accepted, and return a memory block address.
* @retval #NULL The request fails.
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see LOS_MemboxFree
*/
extern VOID *LOS_MemboxAlloc(VOID *pool);
/**
* @ingroup los_membox
* @brief Free a memory block.
*
* @par Description:
* <ul>
* <li>This API is used to free a memory block.</li>
* </ul>
* @attention
* <ul>
* <li>The input pool parameter must be initialized via func LOS_MemboxInit.</li>
* <li>The input box parameter must be allocated by LOS_MemboxAlloc.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
* @param box [IN] Memory block address.
*
* @retval #LOS_NOK This memory block fails to be freed.
* @retval #LOS_OK This memory block is successfully freed.
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see LOS_MemboxAlloc
*/
extern UINT32 LOS_MemboxFree(VOID *pool, VOID *box);
/**
* @ingroup los_membox
* @brief Clear a memory block.
*
* @par Description:
* <ul>
* <li>This API is used to set the memory block value to be 0.</li>
* </ul>
* @attention
* <ul>
* <li>The input pool parameter must be initialized via func LOS_MemboxInit.</li>
* <li>The input box parameter must be allocated by LOS_MemboxAlloc.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
* @param box [IN] Memory block address.
*
* @retval VOID
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see None.
*/
extern VOID LOS_MemboxClr(VOID *pool, VOID *box);
/**
* @ingroup los_membox
* @brief show membox info.
*
* @par Description:
* <ul>
* <li>This API is used to show the memory pool info.</li>
* </ul>
* @attention
* <ul>
* <li>The input pool parameter must be initialized via func LOS_MemboxInit.</li>
* </ul>
*
* @param pool [IN] Memory pool address.
*
* @retval VOID
* @par Dependency:
* <ul>
* <li>los_membox.h: the header file that contains the API declaration.</li>
* </ul>
* @see None.
*/
extern VOID LOS_ShowBox(VOID *pool);
/**
* @ingroup los_membox
* @brief calculate membox information.
*
* @par Description:
* <ul>
* <li>This API is used to calculate membox information.</li>
* </ul>
* @attention
* <ul>
* <li>One parameter of this interface is a pointer, it should be a correct value, otherwise, the system may
* be abnormal.</li>
* </ul>
*
* @param boxMem [IN] Type #VOID* Pointer to the calculate membox.
* @param maxBlk [OUT] Type #UINT32* Record membox max block.
* @param blkCnt [OUT] Type #UINT32* Record membox block count alreay allocated.
* @param blkSize [OUT] Type #UINT32* Record membox block size.
*
* @retval #LOS_OK The heap status calculate success.
* @retval #LOS_NOK The membox status calculate with some error.
* @par Dependency:
* <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
* @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemFree
*/
extern UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, UINT32 *blkCnt, UINT32 *blkSize);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_MEMBOX_H */
此差异已折叠。
git add -A
git commit -m '中断是如何管理的? CPU之间又是如何通讯的?
git commit -m '静态内存管理中节点处的实现很巧妙,点赞!
搜索 @note_pic 方便理解画的字符图
搜索 @note_why 尚未看明白的地方,如果您看明白了,请告知完善
搜索 @note_thinking 一点思考和吐槽的地方
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册