diff --git a/README.md b/README.md index 40a902d6276fae8c71f63eee74c60e494f607afd..b5d4e953a12218a87d31442e09a09c2864c21e64 100644 --- a/README.md +++ b/README.md @@ -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)** diff --git a/arch/arm/arm/src/los_exc.c b/arch/arm/arm/src/los_exc.c index 54b8f3af09a2f44feae75cbea6573a9fffd66d63..210d3c575900ed87ad7cfe4241b8b0b1e8278f1d 100644 --- a/arch/arm/arm/src/los_exc.c +++ b/arch/arm/arm/src/los_exc.c @@ -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); diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index a9dfcf43097b56bf473e104b0c793ce97d109b16..1b4e64e594d320486c5f27756c95472aeb69a0e3 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -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; diff --git a/kernel/base/include/los_percpu_pri.h b/kernel/base/include/los_percpu_pri.h index ef190e3b5c8f2d468f85864f585be1e2a47c11b7..494db97a344f9fdef55f9c74fbb40ed390df737a 100644 --- a/kernel/base/include/los_percpu_pri.h +++ b/kernel/base/include/los_percpu_pri.h @@ -1,87 +1,87 @@ -/* - * 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 */ diff --git a/kernel/base/ipc/los_mux.c b/kernel/base/ipc/los_mux.c index d7ce9bec62d2ca12a285e3afa31d5add1eb79c83..cf1c31ef40548883d7c58c81dc563bf0ad92b9e5 100644 --- a/kernel/base/ipc/los_mux.c +++ b/kernel/base/ipc/los_mux.c @@ -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; diff --git a/kernel/base/mem/membox/los_membox.c b/kernel/base/mem/membox/los_membox.c index 174e78e92103b63739904b9f17a084d305521181..2d83b745c27c9c15760b5087f3d2f1bc471a5253 100644 --- a/kernel/base/mem/membox/los_membox.c +++ b/kernel/base/mem/membox/los_membox.c @@ -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)); } diff --git a/kernel/include/los_membox.h b/kernel/include/los_membox.h index 0e5f11b29226a94f7954082b9cdfe266f38e79a7..3f3fd69964904546391e989bd2499eb78b69ec62 100644 --- a/kernel/include/los_membox.h +++ b/kernel/include/los_membox.h @@ -1,250 +1,250 @@ -/* - * 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: - * - * @attention - * - * - * @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: - * - * @see None. - */ -extern UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize); - -/** - * @ingroup los_membox - * @brief Request a memory block. - * - * @par Description: - * - * @attention - * - * - * @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: - * - * @see LOS_MemboxFree - */ -extern VOID *LOS_MemboxAlloc(VOID *pool); - -/** - * @ingroup los_membox - * @brief Free a memory block. - * - * @par Description: - * - * @attention - * - * - * @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: - * - * @see LOS_MemboxAlloc - */ -extern UINT32 LOS_MemboxFree(VOID *pool, VOID *box); - -/** - * @ingroup los_membox - * @brief Clear a memory block. - * - * @par Description: - * - * @attention - * - * - * @param pool [IN] Memory pool address. - * @param box [IN] Memory block address. - * - * @retval VOID - * @par Dependency: - * - * @see None. - */ -extern VOID LOS_MemboxClr(VOID *pool, VOID *box); - -/** - * @ingroup los_membox - * @brief show membox info. - * - * @par Description: - * - * @attention - * - * - * @param pool [IN] Memory pool address. - * - * @retval VOID - * @par Dependency: - * - * @see None. - */ -extern VOID LOS_ShowBox(VOID *pool); - -/** - * @ingroup los_membox - * @brief calculate membox information. - * - * @par Description: - * - * @attention - * - * - * @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: - * - * @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: + * + * @attention + * + * + * @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: + * + * @see None. + */ +extern UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize); + +/** + * @ingroup los_membox + * @brief Request a memory block. + * + * @par Description: + * + * @attention + * + * + * @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: + * + * @see LOS_MemboxFree + */ +extern VOID *LOS_MemboxAlloc(VOID *pool); + +/** + * @ingroup los_membox + * @brief Free a memory block. + * + * @par Description: + * + * @attention + * + * + * @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: + * + * @see LOS_MemboxAlloc + */ +extern UINT32 LOS_MemboxFree(VOID *pool, VOID *box); + +/** + * @ingroup los_membox + * @brief Clear a memory block. + * + * @par Description: + * + * @attention + * + * + * @param pool [IN] Memory pool address. + * @param box [IN] Memory block address. + * + * @retval VOID + * @par Dependency: + * + * @see None. + */ +extern VOID LOS_MemboxClr(VOID *pool, VOID *box); + +/** + * @ingroup los_membox + * @brief show membox info. + * + * @par Description: + * + * @attention + * + * + * @param pool [IN] Memory pool address. + * + * @retval VOID + * @par Dependency: + * + * @see None. + */ +extern VOID LOS_ShowBox(VOID *pool); + +/** + * @ingroup los_membox + * @brief calculate membox information. + * + * @par Description: + * + * @attention + * + * + * @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: + * + * @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 */ diff --git a/kernel/include/los_mux.h b/kernel/include/los_mux.h index 44756d5dd5daf4d9bad66a9fcc75a12039d70599..3d29d782f98c89a2fde6e079cd0e8b3a9477b264 100644 --- a/kernel/include/los_mux.h +++ b/kernel/include/los_mux.h @@ -1,243 +1,243 @@ -/* - * 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_mux Mutex - * @ingroup kernel - */ - -#ifndef _LOS_MUX_H -#define _LOS_MUX_H - -#include "los_base.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -enum { - LOS_MUX_PRIO_NONE = 0, //线程的优先级和调度不会受到互斥锁影响,先来后到,普通排队. - LOS_MUX_PRIO_INHERIT = 1, //当高优先级的等待低优先级的线程释放锁时,低优先级的线程以高优先级线程的优先级运行。 - //当线程解锁互斥量时,线程的优先级自动被将到它原来的优先级 - LOS_MUX_PRIO_PROTECT = 2 //详见:OsMuxPendOp中的注解,详细说明了LOS_MUX_PRIO_PROTECT的含义 -}; - -enum { - LOS_MUX_NORMAL = 0, //非递归锁 只有[0.1]两个状态,不做任何特殊的错误检,不进行deadlock detection(死锁检测) - LOS_MUX_RECURSIVE = 1, //递归锁 允许同一线程在互斥量解锁前对该互斥量进行多次加锁。递归互斥量维护锁的计数,在解锁次数和加锁次数不相同的情况下,不会释放锁,别的线程就无法加锁此互斥量。 - LOS_MUX_ERRORCHECK = 2, //进行错误检查,如果一个线程企图对一个已经锁住的mutex进行relock或对未加锁的unlock,将返回一个错误。 - LOS_MUX_DEFAULT = LOS_MUX_RECURSIVE //鸿蒙系统默认使用递归锁 -}; - -typedef struct { //互斥锁的属性 - UINT8 protocol; //协议 - UINT8 prioceiling; //优先级上限 - UINT8 type; //类型属性 - UINT8 reserved; //保留字段 -} LosMuxAttr; - -/** - * @ingroup los_mux - * Mutex object. - */ -typedef struct OsMux { //互斥锁结构体 - UINT32 magic; /**< magic number */ //魔法数字 - LosMuxAttr attr; /**< Mutex attribute */ //互斥锁属性 - LOS_DL_LIST holdList; /**< The task holding the lock change */ //当有任务拿到本锁时,通过holdList节点把锁挂到该任务的锁链表上 - LOS_DL_LIST muxList; /**< Mutex linked list */ //等本锁的任务链表,上面挂的都是任务,注意和holdList的区别. - VOID *owner; /**< The current thread that is locking a mutex */ //当前拥有这把锁的任务 - UINT16 muxCount; /**< Times of locking a mutex */ //锁定互斥体的次数,递归锁允许多次 -} LosMux; - -extern UINT32 LOS_MuxAttrInit(LosMuxAttr *attr); -extern UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr); -extern UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outType); -extern UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type); -extern UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *protocol); -extern UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol); -extern UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32 *prioceiling); -extern UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioceiling); -extern UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling, INT32 *oldPrioceiling); -extern UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioceiling); -extern BOOL LOS_MuxIsValid(const LosMux *mutex); - -/** - * @ingroup los_mux - * @brief Init a mutex. - * - * @par Description: - * This API is used to Init a mutex. A mutex handle is assigned to muxHandle when the mutex is init successfully. - * Return LOS_OK on creating successful, return specific error code otherwise. - * @attention - * - * - * @param mutex [IN] Handle pointer of the successfully init mutex. - * @param attr [IN] The mutex attribute. - * - * @retval #LOS_EINVAL The mutex pointer is NULL. - * @retval #LOS_OK The mutex is successfully created. - * @par Dependency: - * - * @see LOS_MuxDestroy - */ -extern UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr); - -/** - * @ingroup los_mux - * @brief Destroy a mutex. - * - * @par Description: - * This API is used to delete a specified mutex. Return LOS_OK on deleting successfully, return specific error code - * otherwise. - * @attention - * - * - * @param mutex [IN] Handle of the mutex to be deleted. - * - * @retval #LOS_EINVAL The mutex pointer is NULL. - * @retval #LOS_EBUSY Tasks pended on this mutex. - * @retval #LOS_EBADF The lock has been destroyed or broken. - * @retval #LOS_OK The mutex is successfully deleted. - * @par Dependency: - * - * @see LOS_MuxInit - */ -extern UINT32 LOS_MuxDestroy(LosMux *mutex); - -/** - * @ingroup los_mux - * @brief Wait to lock a mutex. - * - * @par Description: - * This API is used to wait for a specified period of time to lock a mutex. - * @attention - * - * - * @param mutex [IN] Handle of the mutex to be waited on. - * @param timeout [IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick). - * - * @retval #LOS_EINVAL The mutex pointer is NULL, The timeout is zero or Lock status error. - * @retval #LOS_EINTR The mutex is being locked during an interrupt. - * @retval #LOS_EBUSY Tasks pended on this mutex. - * @retval #LOS_EBADF The lock has been destroyed or broken. - * @retval #LOS_EDEADLK Mutex error check failed or System locked task scheduling. - * @retval #LOS_ETIMEDOUT The mutex waiting times out. - * @retval #LOS_OK The mutex is successfully locked. - * @par Dependency: - * - * @see LOS_MuxInit | LOS_MuxUnlock - */ -extern UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout); - -/** - * @ingroup los_mux - * @brief Try wait to lock a mutex. - * - * @par Description: - * This API is used to wait for a specified period of time to lock a mutex. - * @attention - * - * - * @param mutex [IN] Handle of the mutex to be waited on. - * - * @retval #LOS_EINVAL The mutex pointer is NULL or Lock status error. - * @retval #LOS_EINTR The mutex is being locked during an interrupt. - * @retval #LOS_EBUSY Tasks pended on this mutex. - * @retval #LOS_EBADF The lock has been destroyed or broken. - * @retval #LOS_EDEADLK Mutex error check failed or System locked task scheduling. - * @retval #LOS_ETIMEDOUT The mutex waiting times out. - * @retval #LOS_OK The mutex is successfully locked. - * @par Dependency: - * - * @see LOS_MuxInit | LOS_MuxUnlock - */ -extern UINT32 LOS_MuxTrylock(LosMux *mutex); - -/** - * @ingroup los_mux - * @brief Release a mutex. - * - * @par Description: - * This API is used to release a specified mutex. - * @attention - * - * - * @param mutex [IN] Handle of the mutex to be released. - * - * @retval #LOS_EINVAL The mutex pointer is NULL, The timeout is zero or Lock status error. - * @retval #LOS_EINTR The mutex is being locked during an interrupt. - * @retval #LOS_EBUSY Tasks pended on this mutex. - * @retval #LOS_EBADF The lock has been destroyed or broken. - * @retval #LOS_EDEADLK Mutex error check failed or System locked task scheduling. - * @retval #LOS_ETIMEDOUT The mutex waiting times out. - * @retval #LOS_OK The mutex is successfully locked. - * @par Dependency: - * - * @see LOS_MuxInit | LOS_MuxLock - */ -extern UINT32 LOS_MuxUnlock(LosMux *mutex); - -#ifdef __cplusplus -#if __cplusplus -} -#endif -#endif /* __cplusplus */ - -#endif /* _LOS_MUX_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_mux Mutex + * @ingroup kernel + */ + +#ifndef _LOS_MUX_H +#define _LOS_MUX_H + +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +enum { + LOS_MUX_PRIO_NONE = 0, //线程的优先级和调度不会受到互斥锁影响,先来后到,普通排队. + LOS_MUX_PRIO_INHERIT = 1, //当高优先级的等待低优先级的线程释放锁时,低优先级的线程以高优先级线程的优先级运行。 + //当线程解锁互斥量时,线程的优先级自动被将到它原来的优先级 + LOS_MUX_PRIO_PROTECT = 2 //详见:OsMuxPendOp中的注解,详细说明了LOS_MUX_PRIO_PROTECT的含义 +}; + +enum { + LOS_MUX_NORMAL = 0, //非递归锁 只有[0.1]两个状态,不做任何特殊的错误检,不进行deadlock detection(死锁检测) + LOS_MUX_RECURSIVE = 1, //递归锁 允许同一线程在互斥量解锁前对该互斥量进行多次加锁。递归互斥量维护锁的计数,在解锁次数和加锁次数不相同的情况下,不会释放锁,别的线程就无法加锁此互斥量。 + LOS_MUX_ERRORCHECK = 2, //进行错误检查,如果一个线程企图对一个已经锁住的mutex进行relock或对未加锁的unlock,将返回一个错误。 + LOS_MUX_DEFAULT = LOS_MUX_RECURSIVE //鸿蒙系统默认使用递归锁 +}; + +typedef struct { //互斥锁的属性 + UINT8 protocol; //协议 + UINT8 prioceiling; //优先级上限 + UINT8 type; //类型属性 + UINT8 reserved; //保留字段 +} LosMuxAttr; + +/** + * @ingroup los_mux + * Mutex object. + */ +typedef struct OsMux { //互斥锁结构体 + UINT32 magic; /**< magic number */ //魔法数字 + LosMuxAttr attr; /**< Mutex attribute */ //互斥锁属性 + LOS_DL_LIST holdList; /**< The task holding the lock change */ //当有任务拿到本锁时,通过holdList节点把锁挂到该任务的锁链表上 + LOS_DL_LIST muxList; /**< Mutex linked list */ //等这个锁的任务链表,上面挂的都是任务,注意和holdList的区别. + VOID *owner; /**< The current thread that is locking a mutex */ //当前拥有这把锁的任务 + UINT16 muxCount; /**< Times of locking a mutex */ //锁定互斥体的次数,递归锁允许多次 +} LosMux; + +extern UINT32 LOS_MuxAttrInit(LosMuxAttr *attr); +extern UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr); +extern UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outType); +extern UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type); +extern UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *protocol); +extern UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol); +extern UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32 *prioceiling); +extern UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioceiling); +extern UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling, INT32 *oldPrioceiling); +extern UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioceiling); +extern BOOL LOS_MuxIsValid(const LosMux *mutex); + +/** + * @ingroup los_mux + * @brief Init a mutex. + * + * @par Description: + * This API is used to Init a mutex. A mutex handle is assigned to muxHandle when the mutex is init successfully. + * Return LOS_OK on creating successful, return specific error code otherwise. + * @attention + * + * + * @param mutex [IN] Handle pointer of the successfully init mutex. + * @param attr [IN] The mutex attribute. + * + * @retval #LOS_EINVAL The mutex pointer is NULL. + * @retval #LOS_OK The mutex is successfully created. + * @par Dependency: + * + * @see LOS_MuxDestroy + */ +extern UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr); + +/** + * @ingroup los_mux + * @brief Destroy a mutex. + * + * @par Description: + * This API is used to delete a specified mutex. Return LOS_OK on deleting successfully, return specific error code + * otherwise. + * @attention + * + * + * @param mutex [IN] Handle of the mutex to be deleted. + * + * @retval #LOS_EINVAL The mutex pointer is NULL. + * @retval #LOS_EBUSY Tasks pended on this mutex. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_OK The mutex is successfully deleted. + * @par Dependency: + * + * @see LOS_MuxInit + */ +extern UINT32 LOS_MuxDestroy(LosMux *mutex); + +/** + * @ingroup los_mux + * @brief Wait to lock a mutex. + * + * @par Description: + * This API is used to wait for a specified period of time to lock a mutex. + * @attention + * + * + * @param mutex [IN] Handle of the mutex to be waited on. + * @param timeout [IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_EINVAL The mutex pointer is NULL, The timeout is zero or Lock status error. + * @retval #LOS_EINTR The mutex is being locked during an interrupt. + * @retval #LOS_EBUSY Tasks pended on this mutex. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK Mutex error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The mutex waiting times out. + * @retval #LOS_OK The mutex is successfully locked. + * @par Dependency: + * + * @see LOS_MuxInit | LOS_MuxUnlock + */ +extern UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout); + +/** + * @ingroup los_mux + * @brief Try wait to lock a mutex. + * + * @par Description: + * This API is used to wait for a specified period of time to lock a mutex. + * @attention + * + * + * @param mutex [IN] Handle of the mutex to be waited on. + * + * @retval #LOS_EINVAL The mutex pointer is NULL or Lock status error. + * @retval #LOS_EINTR The mutex is being locked during an interrupt. + * @retval #LOS_EBUSY Tasks pended on this mutex. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK Mutex error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The mutex waiting times out. + * @retval #LOS_OK The mutex is successfully locked. + * @par Dependency: + * + * @see LOS_MuxInit | LOS_MuxUnlock + */ +extern UINT32 LOS_MuxTrylock(LosMux *mutex); + +/** + * @ingroup los_mux + * @brief Release a mutex. + * + * @par Description: + * This API is used to release a specified mutex. + * @attention + * + * + * @param mutex [IN] Handle of the mutex to be released. + * + * @retval #LOS_EINVAL The mutex pointer is NULL, The timeout is zero or Lock status error. + * @retval #LOS_EINTR The mutex is being locked during an interrupt. + * @retval #LOS_EBUSY Tasks pended on this mutex. + * @retval #LOS_EBADF The lock has been destroyed or broken. + * @retval #LOS_EDEADLK Mutex error check failed or System locked task scheduling. + * @retval #LOS_ETIMEDOUT The mutex waiting times out. + * @retval #LOS_OK The mutex is successfully locked. + * @par Dependency: + * + * @see LOS_MuxInit | LOS_MuxLock + */ +extern UINT32 LOS_MuxUnlock(LosMux *mutex); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* _LOS_MUX_H */ diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 6a11338468e3399f35ccc309870bc7b05d968b3d..f105a8f7d99c66306bbd22ed7a9b246778a65582 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,5 +1,5 @@ git add -A -git commit -m '中断是如何管理的? CPU之间又是如何通讯的? +git commit -m '静态内存管理中节点处的实现很巧妙,点赞! 搜索 @note_pic 方便理解画的字符图 搜索 @note_why 尚未看明白的地方,如果您看明白了,请告知完善 搜索 @note_thinking 一点思考和吐槽的地方