diff --git a/doc/cache/~$$进程控制顺序图.~vsdx b/doc/cache/~$$进程控制顺序图.~vsdx new file mode 100644 index 00000000..f3ad3b1e Binary files /dev/null and b/doc/cache/~$$进程控制顺序图.~vsdx differ diff --git a/doc/cache/进程控制顺序图.vsdx b/doc/cache/进程控制顺序图.vsdx new file mode 100644 index 00000000..9d0a1f31 Binary files /dev/null and b/doc/cache/进程控制顺序图.vsdx differ diff --git a/doc/~$泛读报告.docx b/doc/~$泛读报告.docx new file mode 100644 index 00000000..4ad6b906 Binary files /dev/null and b/doc/~$泛读报告.docx differ diff --git a/doc/泛读报告.docx b/doc/泛读报告.docx index c47306b3..56a3ce5f 100644 Binary files a/doc/泛读报告.docx and b/doc/泛读报告.docx differ 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; } - -