From 2409606bd2cfbf6fbfbc5fca38eccd01e3db92f0 Mon Sep 17 00:00:00 2001 From: eee <719747958@qq.com> Date: Fri, 19 Jan 2024 09:32:36 +0800 Subject: [PATCH] some changes happens --- doc/cache/~$$进程控制顺序图.~vsdx | Bin 0 -> 4096 bytes doc/cache/进程控制顺序图.vsdx | Bin 0 -> 31931 bytes doc/~$泛读报告.docx | Bin 0 -> 162 bytes doc/泛读报告.docx | Bin 145761 -> 156143 bytes .../kernel/base/mem/common/los_memstat.c | 18 +- .../kernel/base/mem/membox/los_membox.c | 223 -------- .../kernel/base/mem/tlsf/los_memory.c | 482 ++++++++---------- 7 files changed, 233 insertions(+), 490 deletions(-) create mode 100644 doc/cache/~$$进程控制顺序图.~vsdx create mode 100644 doc/cache/进程控制顺序图.vsdx create mode 100644 doc/~$泛读报告.docx diff --git a/doc/cache/~$$进程控制顺序图.~vsdx b/doc/cache/~$$进程控制顺序图.~vsdx new file mode 100644 index 0000000000000000000000000000000000000000..f3ad3b1e37f91454d0e3400f09144749627f80d1 GIT binary patch literal 4096 zcmeHJF;2rk5F95!0Hp{G1)|6YC?X+QX%LMID0u-0kVruyK>+a_p1@0>rhgm=w)gh-W-fcXUcbI|(WXkwCXV9m2f)EjQx0amHYHc8V|<|Z$y zwNxkqpWLg?ua^HAffJ1Q8>5Q^Lq2cts8Tk|Hs1n%@WSzQ-kV?iK@P;jnD+jJXaPk@}AMlFng<+mv~QBVCda9>}Xb z?BR~u0Ozz_&|;Ha@{3n^R(|cbox%U`+xYTc?TlZ&*vhY1xxTJ767Aph0@Y{T6TZW; z^tWrAG2^e8_o{;M8tAg}{2=A?vuLc+U(Y6{`HQ^EZLI%bej&R0FGsh{hW>vWs@-c5 yepl=M)5ojz<&Hp-B=$rr@J#sKxClbr>&N>AxK>k)9{PweFUD`*EY^Kg)$a?@s!^2y literal 0 HcmV?d00001 diff --git a/doc/cache/进程控制顺序图.vsdx b/doc/cache/进程控制顺序图.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..9d0a1f31d626d1d4fe390f2b7c1a9a4a9e86b801 GIT binary patch literal 31931 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 BL4W`N literal 0 HcmV?d00001 diff --git a/doc/~$泛读报告.docx b/doc/~$泛读报告.docx new file mode 100644 index 0000000000000000000000000000000000000000..4ad6b906510457f5e1251738e0b3478879968b88 GIT binary patch literal 162 zcmZRpP;gGn%wZr6urX9HC@?rPBr;?&fb>>8J0rq(oPj|)i3!CZ7!M|HC2{wEnb$4G c8IK_9k01YKUk>C;L3J&w*Aw_xk75J^0DVLjmjD0& literal 0 HcmV?d00001 diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index c47306b3f016d12a21464a13ce181140ab32fc1d..56a3ce5f5a8f79cdd32c1a7cb67d7058ff546cd1 100644 GIT binary patch delta 35113 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 BKe+$^ delta 24701 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 V{y@$MVgvyML?BRy5N28n`afcd9yI^} diff --git a/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c index 03815a3f..91164b4c 100644 --- a/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c +++ b/src/kernel_liteos_a/kernel/base/mem/common/los_memstat.c @@ -32,9 +32,9 @@ #include "los_memstat_pri.h" #include "los_task_pri.h" -/// 记录每个任务对内存的使用情况 + LITE_OS_SEC_BSS_MINOR STATIC TskMemUsedInfo g_tskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; -/// 计算指定任务对内存使用增加量 + LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -43,9 +43,9 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) if (OS_INT_ACTIVE) { return; } - g_tskMemUsedInfo[taskID].memUsed += usedSize; ///< 叠加 + g_tskMemUsedInfo[taskID].memUsed += usedSize; } -/// 计算指定任务对内存使用减少量 + LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -59,9 +59,9 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) OsCurrTaskGet()->taskName, g_tskMemUsedInfo[taskID].memUsed, usedSize); return; } - g_tskMemUsedInfo[taskID].memUsed -= usedSize; ///< 递减 + g_tskMemUsedInfo[taskID].memUsed -= usedSize; } -/// 获取指定任务对内存的使用情况 + LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -70,7 +70,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID) return g_tskMemUsedInfo[taskID].memUsed; } -/// 清空任务内存使用记录 + LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) { if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { @@ -82,8 +82,8 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) } g_tskMemUsedInfo[taskID].memUsed = 0; } -// Slab是一种内存分配器,通过将内存划分不同大小的空间分配给对象使用来进行缓存管理,应用于内核对象的缓存。 -#ifdef LOS_MEM_SLAB // + +#ifdef LOS_MEM_SLAB LITE_OS_SEC_BSS_MINOR STATIC TskSlabUsedInfo g_tskSlabUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; LITE_OS_SEC_TEXT_MINOR VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID) diff --git a/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c index 4180d3bd..7a4b66de 100644 --- a/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c +++ b/src/kernel_liteos_a/kernel/base/mem/membox/los_membox.c @@ -1,22 +1,4 @@ /* - * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020-2021 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 CON/* * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * @@ -51,211 +33,6 @@ #include "los_hwi.h" #include "los_spinlock.h" -#ifdef LOSCFG_AARCH64 -#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 -#else -#define OS_MEMBOX_MAGIC 0xa55a5aa5 -#endif -#define OS_MEMBOX_SET_MAGIC(addr) \ - ((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)) -#define OS_MEMBOX_NODE_ADDR(addr) \ - ((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) //节块 = (节头 + 节体) addr = 节体 -/* 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; - - if (boxInfo->uwBlkSize == 0) { - return LOS_NOK; - } - - offset = (UINT32)((UINTPTR)node - (UINTPTR)(boxInfo + 1)); - if ((offset % boxInfo->uwBlkSize) != 0) { - return LOS_NOK; - } - - if ((offset / boxInfo->uwBlkSize) >= boxInfo->uwBlkNum) { - return LOS_NOK; - } - - 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_NODE *node = NULL; - UINT32 index; - UINT32 intSave; - - if (pool == NULL) { - return LOS_NOK; - } - - if (blkSize == 0) { - return LOS_NOK; - } - - if (poolSize < sizeof(LOS_MEMBOX_INFO)) { - return LOS_NOK; - } - - MEMBOX_LOCK(intSave); - boxInfo->uwBlkSize = LOS_MEMBOX_ALIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE); //节块总大小(节头+节体) - 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);//去除池头,找到第一个节块位置 - - boxInfo->stFreeList.pstNext = node;//池头空闲链表指向第一个节块 - - for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) {//切割节块,挂入空闲链表 - node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize);//按块大小切割好,统一由pstNext指向 - node = node->pstNext;//node存储了下一个节点的地址信息 - } - - 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; - LOS_MEMBOX_NODE *node = NULL; - LOS_MEMBOX_NODE *nodeTmp = NULL; - UINT32 intSave; - - if (pool == NULL) { - return NULL; - } - - MEMBOX_LOCK(intSave); - 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);//返回可用的虚拟地址 -} -/// 释放指定的一块静态内存块 -LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box) -{ - LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; - UINT32 ret = LOS_NOK; - UINT32 intSave; - - if ((pool == NULL) || (box == NULL)) { - return LOS_NOK; - } - - MEMBOX_LOCK(intSave); - do { - LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);//通过节体获取节块首地址 - if (OsCheckBoxMem(boxInfo, node) != LOS_OK) { - break; - } - - node->pstNext = boxInfo->stFreeList.pstNext;//节块指向空闲链表表头 - boxInfo->stFreeList.pstNext = node;//空闲链表表头反指向它,意味节块排到第一,下次申请将首个分配它 - boxInfo->uwBlkCnt--;//已经使用的内存块减一 - ret = LOS_OK; - } while (0);//将被编译时优化 - MEMBOX_UNLOCK(intSave); - - return ret; -} -/// 清零指定静态内存块的内容 -LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box) -{ - LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; - - 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)); -} -/// 打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、 -/// 内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址 -LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool) -{ - UINT32 index; - UINT32 intSave; - LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; - LOS_MEMBOX_NODE *node = NULL; - - if (pool == NULL) { - return; - } - MEMBOX_LOCK(intSave); - PRINT_INFO("membox(%p,0x%x,0x%x):\r\n", pool, boxInfo->uwBlkSize, boxInfo->uwBlkNum); - PRINT_INFO("free node list:\r\n"); - - for (node = boxInfo->stFreeList.pstNext, index = 0; node != NULL; - node = node->pstNext, ++index) { - PRINT_INFO("(%u,%p)\r\n", index, node); - } - - PRINT_INFO("all node list:\r\n"); - node = (LOS_MEMBOX_NODE *)(boxInfo + 1); - for (index = 0; index < boxInfo->uwBlkNum; ++index, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) { - PRINT_INFO("(%u,%p,%p)\r\n", index, node, node->pstNext); - } - MEMBOX_UNLOCK(intSave); -} -/// 获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小 -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, - UINT32 *blkCnt, UINT32 *blkSize) -{ - if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) { - return LOS_NOK; - } - - *maxBlk = ((OS_MEMBOX_S *)boxMem)->uwBlkNum; - *blkCnt = ((OS_MEMBOX_S *)boxMem)->uwBlkCnt; - *blkSize = ((OS_MEMBOX_S *)boxMem)->uwBlkSize; - - return LOS_OK; -} - -TRIBUTORS - * "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. - */ - -#include "los_membox.h" -#include "los_hwi.h" -#include "los_spinlock.h" - #ifdef LOSCFG_AARCH64 #define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 diff --git a/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c index 5086ca7b..3441b613 100644 --- a/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c +++ b/src/kernel_liteos_a/kernel/base/mem/tlsf/los_memory.c @@ -43,7 +43,7 @@ #include "los_lms_pri.h" #endif -/* Used to cut non-essential functions. | 用于削减非必要功能 */ +/* Used to cut non-essential functions. */ #define OS_MEM_FREE_BY_TASKID 0 #ifdef LOSCFG_KERNEL_VM #define OS_MEM_EXPAND_ENABLE 1 @@ -56,32 +56,32 @@ /* column num of the output info of mem node */ #define OS_MEM_COLUMN_NUM 8 -UINT8 *m_aucSysMem0 = NULL; ///< 异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。 -UINT8 *m_aucSysMem1 = NULL; ///< (内核态)系统动态内存池地址的起始地址 +UINT8 *m_aucSysMem0 = NULL; +UINT8 *m_aucSysMem1 = NULL; #ifdef LOSCFG_MEM_MUL_POOL -VOID *g_poolHead = NULL; ///内存池头,由它牵引多个内存池 +VOID *g_poolHead = NULL; #endif /* The following is the macro definition and interface implementation related to the TLSF. */ /* Supposing a Second Level Index: SLI = 3. */ -#define OS_MEM_SLI 3 ///< 二级小区间级数, +#define OS_MEM_SLI 3 /* Giving 1 free list for each small bucket: 4, 8, 12, up to 124. */ -#define OS_MEM_SMALL_BUCKET_COUNT 31 ///< 小桶的偏移单位 从 4 ~ 124 ,共32级 -#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 ///< 小桶的最大数量 -/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ -#define OS_MEM_LARGE_BUCKET_COUNT 24 /// 为每个大存储桶空闲列表数量 大桶范围: [2^7, 2^31] ,每个小区间有分为 2^3个小区间 -#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) ///< 2^3 = 8 个,即大桶的每个区间又分为8个小区间 +#define OS_MEM_SMALL_BUCKET_COUNT 31 +#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 +/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ +#define OS_MEM_LARGE_BUCKET_COUNT 24 +#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) /* OS_MEM_SMALL_BUCKET_MAX_SIZE to the power of 2 is 7. */ -#define OS_MEM_LARGE_START_BUCKET 7 /// 大桶的开始下标 +#define OS_MEM_LARGE_START_BUCKET 7 /* The count of free list. */ -#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI)) ///< 总链表的数量 32 + 24 * 8 = 224 +#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI)) /* The bitmap is used to indicate whether the free list is empty, 1: not empty, 0: empty. */ -#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1) ///< 224 >> 5 + 1 = 7 ,为什么要右移 5 因为 2^5 = 32 是一个32位整型的大小 - ///< 而 32 * 7 = 224 ,也就是说用 int[7]当位图就能表示完 224个链表 ,此处,一定要理解好,因为这是理解 TLSF 算法的关键. -#define OS_MEM_BITMAP_MASK 0x1FU ///< 因为一个int型为 32位, 2^5 = 32,所以此处 0x1FU = 5个1 足以. +#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1) + +#define OS_MEM_BITMAP_MASK 0x1FU /* Used to find the first bit of 1 in bitmap. */ STATIC INLINE UINT16 OsMemFFS(UINT32 bitmap) @@ -101,7 +101,7 @@ STATIC INLINE UINT32 OsMemLog2(UINT32 size) return OsMemFLS(size); } -/* Get the first level: f = log2(size). | 获取第一级*/ +/* Get the first level: f = log2(size). */ STATIC INLINE UINT32 OsMemFlGet(UINT32 size) { if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { @@ -110,56 +110,56 @@ STATIC INLINE UINT32 OsMemFlGet(UINT32 size) return OsMemLog2(size); } -/* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. | 获取第二级 */ +/* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. */ STATIC INLINE UINT32 OsMemSlGet(UINT32 size, UINT32 fl) { return (((size << OS_MEM_SLI) >> fl) - OS_MEM_FREE_LIST_NUM); } /* The following is the memory algorithm related macro definition and interface implementation. */ -/// 内存池节点 + struct OsMemNodeHead { - UINT32 magic; ///< 魔法数字 0xABCDDCBA - union {//注意这里的前后指向的是连续的地址节点,用于分割和合并 - struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node | prev 用于当前节点指向前一个节点*/ - struct OsMemNodeHead *next; /* The next is used for last node points to the expand node | next 用于最后一个节点指向展开节点*/ + UINT32 magic; + union { + struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node */ + struct OsMemNodeHead *next; /* The next is used for last node points to the expand node */ } ptr; -#ifdef LOSCFG_MEM_LEAKCHECK //内存泄漏检测 - UINTPTR linkReg[LOS_RECORD_LR_CNT];///< 存放左右节点地址,用于检测 +#ifdef LOSCFG_MEM_LEAKCHECK + UINTPTR linkReg[LOS_RECORD_LR_CNT]; #endif - UINT32 sizeAndFlag; ///< 节点总大小+标签 + UINT32 sizeAndFlag; }; -/// 已使用内存池节点 + struct OsMemUsedNodeHead { - struct OsMemNodeHead header;///< 已被使用节点 + struct OsMemNodeHead header; #if OS_MEM_FREE_BY_TASKID - UINT32 taskID; ///< 使用节点的任务ID + UINT32 taskID; #endif }; -/// 内存池空闲节点 + struct OsMemFreeNodeHead { - struct OsMemNodeHead header; ///< 内存池节点 - struct OsMemFreeNodeHead *prev; ///< 前一个空闲前驱节点 - struct OsMemFreeNodeHead *next; ///< 后一个空闲后继节点 + struct OsMemNodeHead header; + struct OsMemFreeNodeHead *prev; + struct OsMemFreeNodeHead *next; }; -/// 内存池信息 + struct OsMemPoolInfo { - VOID *pool; ///< 指向内存块基地址,仅做记录而已,真正的分配内存跟它没啥关系 - UINT32 totalSize; ///< 总大小,确定了内存池的边界 - UINT32 attr; ///< 属性 default attr: lock, not expand. + VOID *pool; + UINT32 totalSize; + UINT32 attr; #ifdef LOSCFG_MEM_WATERLINE - UINT32 waterLine; /* Maximum usage size in a memory pool | 内存吃水线*/ - UINT32 curUsedSize; /* Current usage size in a memory pool | 当前已使用大小*/ + UINT32 waterLine; /* Maximum usage size in a memory pool */ + UINT32 curUsedSize; /* Current usage size in a memory pool */ #endif }; -/// 内存池头信息 + struct OsMemPoolHead { - struct OsMemPoolInfo info; ///< 记录内存池的信息 - UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; ///< 空闲位图 int[7] = 32 * 7 = 224 > 223 - struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT];///< 空闲节点链表 32 + 24 * 8 = 224 - SPIN_LOCK_S spinlock; ///< 操作本池的自旋锁,涉及CPU多核竞争,所以必须得是自旋锁 + struct OsMemPoolInfo info; + UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; + struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT]; + SPIN_LOCK_S spinlock; #ifdef LOSCFG_MEM_MUL_POOL - VOID *nextPool; ///< 指向下一个内存池 OsMemPoolHead 类型 + VOID *nextPool; #endif }; @@ -168,16 +168,16 @@ struct OsMemPoolHead { #define MEM_UNLOCK(pool, state) LOS_SpinUnlockRestore(&(pool)->spinlock, (state)) /* The memory pool support expand. */ -#define OS_MEM_POOL_EXPAND_ENABLE 0x01 ///< 支持扩展 +#define OS_MEM_POOL_EXPAND_ENABLE 0x01 /* The memory pool support no lock. */ -#define OS_MEM_POOL_LOCK_ENABLE 0x02 ///< 加锁 - -#define OS_MEM_NODE_MAGIC 0xABCDDCBA ///< 内存节点的魔法数字 -#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) //最小分配空间 -// 必须给指向空闲块的指针留位置 -#define OS_MEM_NODE_USED_FLAG 0x80000000U ///< 已使用标签 -#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U ///< 对齐标签 -#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node | 哨兵节点标签*/ +#define OS_MEM_POOL_LOCK_ENABLE 0x02 + +#define OS_MEM_NODE_MAGIC 0xABCDDCBA +#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) + +#define OS_MEM_NODE_USED_FLAG 0x80000000U +#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U +#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node */ #define OS_MEM_NODE_ALIGNED_AND_USED_FLAG (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LAST_FLAG) #define OS_MEM_NODE_GET_ALIGNED_FLAG(sizeAndFlag) \ @@ -226,33 +226,32 @@ STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) #if OS_MEM_FREE_BY_TASKID STATIC INLINE VOID OsMemNodeSetTaskID(struct OsMemUsedNodeHead *node) { - node->taskID = LOS_CurTaskIDGet();//将当前任务ID绑定到内存池节点上 + node->taskID = LOS_CurTaskIDGet(); } #endif #ifdef LOSCFG_MEM_WATERLINE STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) { - pool->info.curUsedSize += size; //延长可使用空间 + pool->info.curUsedSize += size; if (pool->info.curUsedSize > pool->info.waterLine) { - pool->info.waterLine = pool->info.curUsedSize; //警戒线加高 + pool->info.waterLine = pool->info.curUsedSize; } } #else STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) { - (VOID)pool; - (VOID)size; + (VOID)pool; + (VOID)size; } #endif #if OS_MEM_EXPAND_ENABLE -/// 更新哨兵节点内容 STATIC INLINE struct OsMemNodeHead *OsMemLastSentinelNodeGet(const struct OsMemNodeHead *sentinelNode) { struct OsMemNodeHead *node = NULL; - VOID *ptr = sentinelNode->ptr.next;//返回不连续的内存块 - UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); // 获取大小 + VOID *ptr = sentinelNode->ptr.next; + UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); while ((ptr != NULL) && (size != 0)) { node = OS_MEM_END_NODE(ptr, size); @@ -262,7 +261,7 @@ STATIC INLINE struct OsMemNodeHead *OsMemLastSentinelNodeGet(const struct OsMemN return node; } -/// 检查哨兵节点 + STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode) { if (!OS_MEM_NODE_GET_USED_FLAG(sentinelNode->sizeAndFlag)) { @@ -275,7 +274,7 @@ STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode) return TRUE; } -/// 是否为最后一个哨兵节点 + STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode) { if (OsMemSentinelNodeCheck(sentinelNode) == FALSE) { @@ -290,11 +289,11 @@ STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode) return FALSE; } -/// 设置哨兵节点内容 + STATIC INLINE VOID OsMemSentinelNodeSet(struct OsMemNodeHead *sentinelNode, VOID *newNode, UINT32 size) { - if (sentinelNode->ptr.next != NULL) { //哨兵节点有 逻辑地址不连续的衔接内存块 - sentinelNode = OsMemLastSentinelNodeGet(sentinelNode);//更新哨兵节点内容 + if (sentinelNode->ptr.next != NULL) { + sentinelNode = OsMemLastSentinelNodeGet(sentinelNode); } sentinelNode->sizeAndFlag = size; @@ -330,14 +329,14 @@ STATIC INLINE struct OsMemNodeHead *PreSentinelNodeGet(const VOID *pool, const s return NULL; } -/// 大内存释放 + UINT32 OsMemLargeNodeFree(const VOID *ptr) { - LosVmPage *page = OsVmVaddrToPage((VOID *)ptr);//获取物理页 + LosVmPage *page = OsVmVaddrToPage((VOID *)ptr); if ((page == NULL) || (page->nPages == 0)) { return LOS_NOK; } - LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages);//释放连续的几个物理页 + LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages); return LOS_OK; } @@ -376,7 +375,7 @@ STATIC INLINE BOOL TryShrinkPool(const VOID *pool, const struct OsMemNodeHead *n #endif return TRUE; } -/// 内存池扩展实现 + STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave) { UINT32 tryCount = MAX_SHRINK_PAGECACHE_TRY; @@ -384,11 +383,11 @@ STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave) struct OsMemNodeHead *newNode = NULL; struct OsMemNodeHead *endNode = NULL; - size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE);//圆整 - endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize);//获取哨兵节点 + size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE); + endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize); RETRY: - newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT);//申请新的内存池 | 物理内存 + newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT); if (newNode == NULL) { if (tryCount > 0) { tryCount--; @@ -412,26 +411,26 @@ RETRY: size = (resize == 0) ? size : resize; } #endif - newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE);//设置新节点大小 - newNode->ptr.prev = OS_MEM_END_NODE(newNode, size);//新节点的前节点指向新节点的哨兵节点 - OsMemSentinelNodeSet(endNode, newNode, size);//设置老内存池的哨兵节点信息,其实就是指向新内存块 - OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//将新节点加入空闲链表 + newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE); + newNode->ptr.prev = OS_MEM_END_NODE(newNode, size); + OsMemSentinelNodeSet(endNode, newNode, size); + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); - endNode = OS_MEM_END_NODE(newNode, size);//获取新节点的哨兵节点 - (VOID)memset(endNode, 0, sizeof(*endNode));//清空内存 - endNode->ptr.next = NULL;//新哨兵节点没有后续指向,因为它已成为最后 - endNode->magic = OS_MEM_NODE_MAGIC;//设置新哨兵节的魔法数字 - OsMemSentinelNodeSet(endNode, NULL, 0); //设置新哨兵节点内容 - OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE);//更新内存池警戒线 + endNode = OS_MEM_END_NODE(newNode, size); + (VOID)memset(endNode, 0, sizeof(*endNode)); + endNode->ptr.next = NULL; + endNode->magic = OS_MEM_NODE_MAGIC; + OsMemSentinelNodeSet(endNode, NULL, 0); + OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE); return 0; } -/// 扩展内存池 + STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave) { - UINT32 expandDefault = MEM_EXPAND_SIZE(LOS_MemPoolSizeGet(pool));//至少要扩展现有内存池的 1/8 大小 + UINT32 expandDefault = MEM_EXPAND_SIZE(LOS_MemPoolSizeGet(pool)); UINT32 expandSize = MAX(expandDefault, allocSize); - UINT32 tryCount = 1;//尝试次数 + UINT32 tryCount = 1; UINT32 ret; do { @@ -448,7 +447,7 @@ STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave return -1; } -///< 允许指定内存池扩展 + VOID LOS_MemExpandEnable(VOID *pool) { if (pool == NULL) { @@ -487,7 +486,7 @@ STATIC INLINE VOID OsLmsAllocAlignMark(VOID *ptr, VOID *alignedPtr, UINT32 size) g_lms->simpleMark((UINTPTR)ptr + sizeof(UINT32), (UINTPTR)alignedPtr, LMS_SHADOW_REDZONE_U8); } - /* mark remining as redzone */ + /* mark remaining as redzone */ g_lms->simpleMark(LMS_ADDR_ALIGN((UINTPTR)alignedPtr + size), (UINTPTR)OS_MEM_NEXT_NODE(allocNode), LMS_SHADOW_REDZONE_U8); } @@ -523,7 +522,8 @@ STATIC INLINE VOID OsLmsReallocResizeMark(struct OsMemNodeHead *node, UINT32 res g_lms->simpleMark((UINTPTR)node + resize, (UINTPTR)OS_MEM_NEXT_NODE(node), LMS_SHADOW_REDZONE_U8); } #endif -#ifdef LOSCFG_MEM_LEAKCHECK //内存泄漏检查 + +#ifdef LOSCFG_MEM_LEAKCHECK STATIC INLINE VOID OsMemLinkRegisterRecord(struct OsMemNodeHead *node) { LOS_RecordLR(node->linkReg, LOS_RECORD_LR_CNT, LOS_RECORD_LR_CNT, LOS_OMIT_LR_CNT); @@ -549,7 +549,7 @@ STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node) PRINTK("\n"); } } -/// 打印已使用的节点 + VOID OsMemUsedNodeShow(VOID *pool) { if (pool == NULL) { @@ -626,17 +626,17 @@ STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, STATIC INLINE UINT32 OsMemFreeListIndexGet(UINT32 size) { - UINT32 fl = OsMemFlGet(size);//获取一级位图 + UINT32 fl = OsMemFlGet(size); if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { return fl; } - UINT32 sl = OsMemSlGet(size, fl);//获取二级位图 + UINT32 sl = OsMemSlGet(size, fl); return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl); } STATIC INLINE struct OsMemFreeNodeHead *OsMemFindCurSuitableBlock(struct OsMemPoolHead *poolHead, - UINT32 index, UINT32 size) + UINT32 index, UINT32 size) { struct OsMemFreeNodeHead *node = NULL; @@ -663,7 +663,7 @@ STATIC INLINE UINT32 OsMemNotEmptyIndexGet(struct OsMemPoolHead *poolHead, UINT3 return OS_MEM_FREE_LIST_COUNT; } -/// 找到下一个合适的块 + STATIC INLINE struct OsMemFreeNodeHead *OsMemFindNextSuitableBlock(VOID *pool, UINT32 size, UINT32 *outIndex) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -730,13 +730,13 @@ STATIC INLINE VOID OsMemListAdd(struct OsMemPoolHead *pool, UINT32 listIndex, st OsMemSetFreeListBit(pool, listIndex); node->header.magic = OS_MEM_NODE_MAGIC; } -/// 从空闲链表中删除 + STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node) { if (node == pool->freeList[listIndex]) { pool->freeList[listIndex] = node->next; - if (node->next == NULL) {//如果链表空了 - OsMemClearFreeListBit(pool, listIndex);//将位图位 置为 0 + if (node->next == NULL) { + OsMemClearFreeListBit(pool, listIndex); } else { node->next->prev = NULL; } @@ -748,27 +748,27 @@ STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, } node->header.magic = OS_MEM_NODE_MAGIC; } -/// 添加一个空闲节点 + STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node) { - UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位 + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); if (index >= OS_MEM_FREE_LIST_COUNT) { LOS_Panic("The index of free lists is error, index = %u\n", index); return; } - OsMemListAdd(pool, index, node);//挂入链表 + OsMemListAdd(pool, index, node); } -/// 从空闲链表上摘除节点 + STATIC INLINE VOID OsMemFreeNodeDelete(VOID *pool, struct OsMemFreeNodeHead *node) { - UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位 + UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag); if (index >= OS_MEM_FREE_LIST_COUNT) { LOS_Panic("The index of free lists is error, index = %u\n", index); return; } OsMemListDelete(pool, index, node); } -//获取一个空闲的节点 + STATIC INLINE struct OsMemNodeHead *OsMemFreeNodeGet(VOID *pool, UINT32 size) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -782,67 +782,56 @@ STATIC INLINE struct OsMemNodeHead *OsMemFreeNodeGet(VOID *pool, UINT32 size) return &firstNode->header; } -/// 合并节点,和前面的节点合并 node 消失 + STATIC INLINE VOID OsMemMergeNode(struct OsMemNodeHead *node) { struct OsMemNodeHead *nextNode = NULL; - node->ptr.prev->sizeAndFlag += node->sizeAndFlag; //前节点长度变长 - nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); // 下一个节点位置 - if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//不是哨兵节点 - nextNode->ptr.prev = node->ptr.prev;//后一个节点的前节点变成前前节点 + node->ptr.prev->sizeAndFlag += node->sizeAndFlag; + nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { + nextNode->ptr.prev = node->ptr.prev; } } -/// 切割节点 + STATIC INLINE VOID OsMemSplitNode(VOID *pool, struct OsMemNodeHead *allocNode, UINT32 allocSize) { struct OsMemFreeNodeHead *newFreeNode = NULL; struct OsMemNodeHead *nextNode = NULL; - newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize);//切割后出现的新空闲节点,在分配节点的右侧 - newFreeNode->header.ptr.prev = allocNode;//新节点指向前节点,说明是从左到右切割 - newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize;//新空闲节点大小 - allocNode->sizeAndFlag = allocSize;//分配节点大小 - nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header);//获取新节点的下一个节点 - if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点不是哨兵节点(末尾节点) - nextNode->ptr.prev = &newFreeNode->header;//下一个节点的前节点为新空闲节点 - if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点也是空闲的 - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除下一个节点信息 - OsMemMergeNode(nextNode);//下一个节点和新空闲节点 合并成一个新节点 + newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize); + newFreeNode->header.ptr.prev = allocNode; + newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize; + allocNode->sizeAndFlag = allocSize; + nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header); + if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { + nextNode->ptr.prev = &newFreeNode->header; + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); + OsMemMergeNode(nextNode); } } - OsMemFreeNodeAdd(pool, newFreeNode);//挂入空闲链表 + OsMemFreeNodeAdd(pool, newFreeNode); } -// + STATIC INLINE VOID *OsMemCreateUsedNode(VOID *addr) { - struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr;//直接将地址转成使用节点,说明节点信息也存在内存池中 - //这种用法是非常巧妙的 + struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr; + #if OS_MEM_FREE_BY_TASKID - OsMemNodeSetTaskID(node);//设置使用内存节点的任务 + OsMemNodeSetTaskID(node); #endif -#ifdef LOSCFG_KERNEL_LMS //检测内存泄漏 +#ifdef LOSCFG_KERNEL_LMS struct OsMemNodeHead *newNode = (struct OsMemNodeHead *)node; if (g_lms != NULL) { g_lms->mallocMark(newNode, OS_MEM_NEXT_NODE(newNode), OS_MEM_NODE_HEAD_SIZE); } #endif - return node + 1; //@note_good 这个地方挺有意思的,只是将结构体扩展下,留一个 int 位 ,变成了已使用节点,返回的地址正是要分配给应用的地址 + return node + 1; } -/*! - * @brief OsMemPoolInit 内存池初始化 - * 内存池节点部分包含3种类型节点:未使用空闲内存节点(OsMemFreeNodeHead),已使用内存节点(OsMemUsedNodeHead) 和 尾节点(OsMemNodeHead)。 - * \n 每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。 - * \n 空闲内存节点和已使用内存节点后面的内存区域是数据域 - * @param pool - * @param size - * @return - * - * @see - */ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) { struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; @@ -864,32 +853,30 @@ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) #endif LOS_SpinInit(&poolHead->spinlock); - poolHead->info.pool = pool; //内存池的起始地址,但注意真正的内存并不是从此处分配,它只是用来记录这个内存块的开始位置而已. - poolHead->info.totalSize = size;//内存池总大小 - poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. | 默认是上锁,不支持扩展,需扩展得另外设置*/ + poolHead->info.pool = pool; + poolHead->info.totalSize = size; + poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. */ - newNode = OS_MEM_FIRST_NODE(pool);//跳到第一个节点位置,即跳过结构体本身位置,真正的分配内存是从newNode开始的. - newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE);//这才是可供分配给外界使用的总内存块大小,即数据域 - //OS_MEM_NODE_HEAD_SIZE 叫当前使用节点,即指 newNode占用的空间 - newNode->ptr.prev = NULL;//开始是空指向 - newNode->magic = OS_MEM_NODE_MAGIC;//魔法数字 用于标识这是一个 OsMemNodeHead 节点, 魔法数字不能被覆盖, - OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//添加一个空闲节点,由此有了首个可供分配的空闲节点 + newNode = OS_MEM_FIRST_NODE(pool); + newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE); + newNode->ptr.prev = NULL; + newNode->magic = OS_MEM_NODE_MAGIC; + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); /* The last mem node */ - endNode = OS_MEM_END_NODE(pool, size);//确定尾节点位置,尾节点没有数据域 - endNode->magic = OS_MEM_NODE_MAGIC; //填入尾节点的魔法数字 -#if OS_MEM_EXPAND_ENABLE //支持扩展 - endNode->ptr.next = NULL;//尾节点没有后继节点 - OsMemSentinelNodeSet(endNode, NULL, 0);//将尾节点设置为哨兵节点 + endNode = OS_MEM_END_NODE(pool, size); + endNode->magic = OS_MEM_NODE_MAGIC; +#if OS_MEM_EXPAND_ENABLE + endNode->ptr.next = NULL; + OsMemSentinelNodeSet(endNode, NULL, 0); #else - endNode->sizeAndFlag = 0;//0代表没有数据域 - endNode->ptr.prev = newNode;//前驱指针指向第一个节点 + endNode->sizeAndFlag = 0; + endNode->ptr.prev = newNode; OS_MEM_NODE_SET_USED_FLAG(endNode->sizeAndFlag); #endif -#ifdef LOSCFG_MEM_WATERLINE //吃水线开关 - poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE;//内存池已使用了这么多空间,这些都是存内存池自身数据的空间, - //但此处是否还要算是 endNode ? @note_thinking - poolHead->info.waterLine = poolHead->info.curUsedSize; //设置吃水线 +#ifdef LOSCFG_MEM_WATERLINE + poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE; + poolHead->info.waterLine = poolHead->info.curUsedSize; #endif #ifdef LOSCFG_KERNEL_LMS if (resize != 0) { @@ -909,13 +896,13 @@ STATIC VOID OsMemPoolDeinit(const VOID *pool, UINT32 size) #endif (VOID)memset_s(pool, size, 0, sizeof(struct OsMemPoolHead)); } -/// 新增内存池 + STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) { VOID *nextPool = g_poolHead; VOID *curPool = g_poolHead; UINTPTR poolEnd; - while (nextPool != NULL) {//单链表遍历方式 + while (nextPool != NULL) { poolEnd = (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool); if (((pool <= nextPool) && (((UINTPTR)pool + size) > (UINTPTR)nextPool)) || (((UINTPTR)pool < poolEnd) && (((UINTPTR)pool + size) >= poolEnd))) { @@ -929,15 +916,15 @@ STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) } if (g_poolHead == NULL) { - g_poolHead = pool; //首个内存池 + g_poolHead = pool; } else { - ((struct OsMemPoolHead *)curPool)->nextPool = pool; //两池扯上关系 + ((struct OsMemPoolHead *)curPool)->nextPool = pool; } - ((struct OsMemPoolHead *)pool)->nextPool = NULL; //新池下一个无所指 + ((struct OsMemPoolHead *)pool)->nextPool = NULL; return LOS_OK; } -/// 删除内存池 + STATIC UINT32 OsMemPoolDelete(const VOID *pool) { UINT32 ret = LOS_NOK; @@ -968,39 +955,29 @@ STATIC UINT32 OsMemPoolDelete(const VOID *pool) } #endif -/*! - * @brief LOS_MemInit 初始化一块指定的动态内存池,大小为size - * 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。 - * @param pool - * @param size - * @return - * @attention EndNode作为内存池末尾的节点,size为0。 - * @see - */ UINT32 LOS_MemInit(VOID *pool, UINT32 size) { if ((pool == NULL) || (size <= OS_MEM_MIN_POOL_SIZE)) { return OS_ERROR; } - size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE);//4个字节对齐 + size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE); if (OsMemPoolInit(pool, size)) { return OS_ERROR; } -#ifdef LOSCFG_MEM_MUL_POOL //多内存池开关 +#ifdef LOSCFG_MEM_MUL_POOL if (OsMemPoolAdd(pool, size)) { (VOID)OsMemPoolDeInit(pool, size); return OS_ERROR; } #endif - OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size);//打印日志 + OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size); return LOS_OK; } #ifdef LOSCFG_MEM_MUL_POOL -/// 删除指定内存池 UINT32 LOS_MemDeInit(VOID *pool) { struct OsMemPoolHead *tmpPool = (struct OsMemPoolHead *)pool; @@ -1020,7 +997,7 @@ UINT32 LOS_MemDeInit(VOID *pool) OsHookCall(LOS_HOOK_TYPE_MEM_DEINIT, tmpPool); return LOS_OK; } -/// 打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。 + UINT32 LOS_MemPoolList(VOID) { VOID *nextPool = g_poolHead; @@ -1034,7 +1011,7 @@ UINT32 LOS_MemPoolList(VOID) return index; } #endif -/// 从指定动态内存池中申请size长度的内存 + STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave) { struct OsMemNodeHead *allocNode = NULL; @@ -1047,15 +1024,15 @@ STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 i UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); #if OS_MEM_EXPAND_ENABLE -retry: //这种写法也挺赞的 @note_good +retry: #endif - allocNode = OsMemFreeNodeGet(pool, allocSize);//获取空闲节点 - if (allocNode == NULL) {//没有内存了,怎搞? + allocNode = OsMemFreeNodeGet(pool, allocSize); + if (allocNode == NULL) { #if OS_MEM_EXPAND_ENABLE if (pool->info.attr & OS_MEM_POOL_EXPAND_ENABLE) { - INT32 ret = OsMemPoolExpand(pool, allocSize, intSave);//扩展内存池 + INT32 ret = OsMemPoolExpand(pool, allocSize, intSave); if (ret == 0) { - goto retry;//再来一遍 + goto retry; } } #endif @@ -1070,22 +1047,22 @@ retry: //这种写法也挺赞的 @note_good return NULL; } - if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) {//所需小于内存池可供分配量 - OsMemSplitNode(pool, allocNode, allocSize);//劈开内存池 + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) { + OsMemSplitNode(pool, allocNode, allocSize); } - OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag);//给节点贴上已使用的标签 - OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag));//更新吃水线 + OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag); + OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag)); -#ifdef LOSCFG_MEM_LEAKCHECK //检测内存泄漏开关 +#ifdef LOSCFG_MEM_LEAKCHECK OsMemLinkRegisterRecord(allocNode); #endif - return OsMemCreateUsedNode((VOID *)allocNode);//创建已使用节点 + return OsMemCreateUsedNode((VOID *)allocNode); } -/// 从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存 + VOID *LOS_MemAlloc(VOID *pool, UINT32 size) { - if ((pool == NULL) || (size == 0)) {//没提供内存池时 + if ((pool == NULL) || (size == 0)) { return (size > 0) ? OsVmBootMemAlloc(size) : NULL; } @@ -1102,14 +1079,14 @@ VOID *LOS_MemAlloc(VOID *pool, UINT32 size) break; } MEM_LOCK(poolHead, intSave); - ptr = OsMemAlloc(poolHead, size, intSave);//真正的分配内存函数,详细查看 鸿蒙内核源码分析(内存池篇) + ptr = OsMemAlloc(poolHead, size, intSave); MEM_UNLOCK(poolHead, intSave); } while (0); - OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size);//打印日志,到此一游 + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size); return ptr; } -/// 从指定内存池中申请size长度的内存且地址按boundary字节对齐的内存 + VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { UINT32 gapSize; @@ -1166,10 +1143,10 @@ VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) ptr = alignedPtr; } while (0); - OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary);//打印对齐日志,表示程序曾临幸过此处 + OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary); return ptr; } -/// 内存池有效性检查 + STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const VOID *addr) { UINT32 size; @@ -1183,7 +1160,7 @@ STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const V if (OS_MEM_MIDDLE_ADDR_OPEN_END(pool + 1, addr, (UINTPTR)pool + size)) { return TRUE; } -#if OS_MEM_EXPAND_ENABLE //如果支持可扩展 +#if OS_MEM_EXPAND_ENABLE struct OsMemNodeHead *node = NULL; struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, size); while (OsMemIsLastSentinelNode(sentinel) == FALSE) { @@ -1273,7 +1250,7 @@ STATIC UINT32 OsMemCheckUsedNode(const struct OsMemPoolHead *pool, const struct return LOS_OK; } -/// 释放内存 + STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node) { UINT32 ret = OsMemCheckUsedNode(pool, node); @@ -1283,10 +1260,10 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead } #ifdef LOSCFG_MEM_WATERLINE - pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//降低水位线 + pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); #endif - node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//获取大小和标记 + node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); #ifdef LOSCFG_MEM_LEAKCHECK OsMemLinkRegisterRecord(node); #endif @@ -1297,17 +1274,17 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead g_lms->check((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, TRUE); } #endif - struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode | 合并前一个节点*/ + struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode */ if ((preNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode);//删除前节点的信息 - OsMemMergeNode(node);//向前合并 + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode); + OsMemMergeNode(node); node = preNode; } - struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode | 计算后一个节点位置*/ + struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode */ if ((nextNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { - OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除后节点信息 - OsMemMergeNode(nextNode);//合并节点 + OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); + OsMemMergeNode(nextNode); } #if OS_MEM_EXPAND_ENABLE @@ -1328,7 +1305,7 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead #endif return ret; } -/// 释放从指定动态内存中申请的内存 + UINT32 LOS_MemFree(VOID *pool, VOID *ptr) { UINT32 intSave; @@ -1344,13 +1321,13 @@ UINT32 LOS_MemFree(VOID *pool, VOID *ptr) struct OsMemNodeHead *node = NULL; do { - UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32));//获取节点大小和标签 即: sizeAndFlag + UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32)); if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); break; } - node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE);//定位到节点开始位置 + node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); @@ -1438,7 +1415,7 @@ STATIC INLINE VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) } STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, - struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) + struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) { struct OsMemNodeHead *nextNode = NULL; UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); @@ -1469,7 +1446,7 @@ STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, } return tmpPtr; } -/// 按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块 + VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) { if ((pool == NULL) || OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { @@ -1562,7 +1539,7 @@ UINT32 LOS_MemFreeByTaskID(VOID *pool, UINT32 taskID) return LOS_OK; } #endif -/// 获取指定动态内存池的总大小 + UINT32 LOS_MemPoolSizeGet(const VOID *pool) { UINT32 count = 0; @@ -1571,23 +1548,23 @@ UINT32 LOS_MemPoolSizeGet(const VOID *pool) return LOS_NOK; } - count += ((struct OsMemPoolHead *)pool)->info.totalSize; // 这里的 += 好像没必要吧?, = 就可以了, @note_thinking + count += ((struct OsMemPoolHead *)pool)->info.totalSize; -#if OS_MEM_EXPAND_ENABLE //支持扩展 +#if OS_MEM_EXPAND_ENABLE UINT32 size; struct OsMemNodeHead *node = NULL; - struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count);//获取哨兵节点 + struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count); - while (OsMemIsLastSentinelNode(sentinel) == FALSE) {//不是最后一个节点 - size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag);//数据域大小 - node = OsMemSentinelNodeGet(sentinel);//再获取哨兵节点 - sentinel = OS_MEM_END_NODE(node, size);//获取尾节点 - count += size; //内存池大小变大 + while (OsMemIsLastSentinelNode(sentinel) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag); + node = OsMemSentinelNodeGet(sentinel); + sentinel = OS_MEM_END_NODE(node, size); + count += size; } #endif return count; } -/// 获取指定动态内存池的总使用量大小 + UINT32 LOS_MemTotalUsedGet(VOID *pool) { struct OsMemNodeHead *tmpNode = NULL; @@ -1660,7 +1637,7 @@ STATIC UINT32 OsMemAddrValidCheckPrint(const VOID *pool, struct OsMemFreeNodeHea } STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID *pool, - const struct OsMemNodeHead *endNode) + const struct OsMemNodeHead *endNode) { if (!OS_MEM_MAGIC_VALID(*tmpNode)) { OsMemMagicCheckPrint(tmpNode); @@ -1676,7 +1653,7 @@ STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID } STATIC UINT32 OsMemFreeListNodeCheck(const struct OsMemPoolHead *pool, - const struct OsMemFreeNodeHead *node) + const struct OsMemFreeNodeHead *node) { if (!OsMemAddrValidCheck(pool, node) || !OsMemAddrValidCheck(pool, node->prev) || @@ -1737,9 +1714,9 @@ OUT: #endif } } -//对指定内存池做完整性检查, + STATIC UINT32 OsMemIntegrityCheck(const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, - struct OsMemNodeHead **preNode) + struct OsMemNodeHead **preNode) { struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); @@ -1862,7 +1839,7 @@ STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) return LOS_OK; } #endif -/// 对指定内存池做完整性检查 + UINT32 LOS_MemIntegrityCheck(const VOID *pool) { if (pool == NULL) { @@ -1887,7 +1864,7 @@ ERROR_OUT: } STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNodeHead *node, - LOS_MEM_POOL_STATUS *poolStatus) + LOS_MEM_POOL_STATUS *poolStatus) { UINT32 totalUsedSize = 0; UINT32 totalFreeSize = 0; @@ -1916,17 +1893,8 @@ STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNode poolStatus->freeNodeNum += freeNodeNum; } -/*! - * @brief LOS_MemInfoGet - * 获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小 - * @param pool - * @param poolStatus - * @return - * - * @see - */ UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) -{//内存碎片率计算:同样调用LOS_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 +{ struct OsMemPoolHead *poolInfo = pool; if (poolStatus == NULL) { @@ -2007,7 +1975,7 @@ STATIC VOID OsMemInfoPrint(VOID *pool) status.freeNodeNum); #endif } -/// 打印指定内存池的空闲内存块的大小及数量 + UINT32 LOS_MemFreeNodeShow(VOID *pool) { struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; @@ -2054,7 +2022,7 @@ UINT32 LOS_MemFreeNodeShow(VOID *pool) return LOS_OK; } -///内核空间动态内存(堆内存)初始化 , 争取系统动态内存池 + STATUS_T OsKHeapInit(size_t size) { STATUS_T ret; @@ -2073,38 +2041,38 @@ STATUS_T OsKHeapInit(size_t size) return -1; } - m_aucSysMem0 = m_aucSysMem1 = ptr;// 指定内核内存池的位置 - ret = LOS_MemInit(m_aucSysMem0, size); //初始化内存池,供内核分配动态内存 + m_aucSysMem0 = m_aucSysMem1 = ptr; + ret = LOS_MemInit(m_aucSysMem0, size); if (ret != LOS_OK) { PRINT_ERR("vmm_kheap_init LOS_MemInit failed!\n"); g_vmBootMemBase -= size; return ret; } #if OS_MEM_EXPAND_ENABLE - LOS_MemExpandEnable(OS_SYS_MEM_ADDR);//支持扩展系统动态内存 + LOS_MemExpandEnable(OS_SYS_MEM_ADDR); #endif return LOS_OK; } -///< 判断地址是否在堆区 + BOOL OsMemIsHeapNode(const VOID *ptr) { - struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1;//内核堆区开始地址 - struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool);//获取内存池首个节点 - struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize);//获取内存池的尾节点 + struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1; + struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool); + struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); - if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//如果在首尾范围内 + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { return TRUE; } -#if OS_MEM_EXPAND_ENABLE//内存池经过扩展后,新旧块的虚拟地址是不连续的,所以需要跳块判断 - UINT32 intSave; - UINT32 size;//详细查看百篇博客系列篇之 鸿蒙内核源码分析(内存池篇) - MEM_LOCK(pool, intSave); //获取自旋锁 - while (OsMemIsLastSentinelNode(endNode) == FALSE) { //哨兵节点是内存池结束的标记 - size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag);//获取节点大小 - firstNode = OsMemSentinelNodeGet(endNode);//获取下一块的开始地址 - endNode = OS_MEM_END_NODE(firstNode, size);//获取下一块的尾节点 - if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//判断地址是否在该块中 +#if OS_MEM_EXPAND_ENABLE + UINT32 intSave; + UINT32 size; + MEM_LOCK(pool, intSave); + while (OsMemIsLastSentinelNode(endNode) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); + firstNode = OsMemSentinelNodeGet(endNode); + endNode = OS_MEM_END_NODE(firstNode, size); + if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) { MEM_UNLOCK(pool, intSave); return TRUE; } @@ -2113,5 +2081,3 @@ BOOL OsMemIsHeapNode(const VOID *ptr) #endif return FALSE; } - - -- 2.34.1