diff --git a/doc/何佳聪 泛读报告.docx b/doc/何佳聪 泛读报告.docx new file mode 100644 index 0000000..b8c9677 Binary files /dev/null and b/doc/何佳聪 泛读报告.docx differ diff --git a/doc/蔡伦_LiteOS阅读泛读报告.docx b/doc/蔡伦_LiteOS阅读泛读报告.docx deleted file mode 100644 index e69de29..0000000 diff --git a/hjc/hjc.txt b/hjc/hjc.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/kernel/base/mem/bestfit/los_memory.c b/src/kernel/base/mem/bestfit/los_memory.c index e2f1856..eaa5b45 100644 --- a/src/kernel/base/mem/bestfit/los_memory.c +++ b/src/kernel/base/mem/bestfit/los_memory.c @@ -62,8 +62,13 @@ extern "C" { return; \ } \ } while (0) +//这个宏的作用是确保在参数为NULL时能够快速地进行错误处理, +//避免在每个需要检查空指针的地方都重复编写相似的代码。 +//这样可以提高代码的可读性和可维护性。 -/* spinlock for mem module, only available on SMP mode */ + + +/*对内存模块的自旋锁进行定义的注释。它表明这个自旋锁只在SMP(对称多处理)模式下可用。 */ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memSpin); UINT8 *m_aucSysMem0 = NULL; @@ -90,7 +95,18 @@ STATIC VOID OsMemNodeSave(LosMemDynNode *node); #endif STATIC VOID *OsMemAllocWithCheck(LosMemPoolInfo *pool, UINT32 size); - +/* +LITE_OS_SEC_BSS 表示将 g_memSpin 这个自旋锁变量放在安全的BSS段中,以保护其不受外部干扰。 +SPIN_LOCK_INIT(g_memSpin) 初始化自旋锁 g_memSpin,将其设置为空闲状态。 +m_aucSysMem0 和 m_aucSysMem1 均为指向 UINT8 类型的指针,初始值均为 NULL。这些指针可能是用于指向系统内存的起始地址。 +g_MALLOC_HOOK 是一个函数指针,用于挂接动态内存分配的钩子函数,可以在内存分配、释放等操作前后执行一些自定义处理。 +g_sys_mem_addr_end 是一个 UINTPTR 类型的变量,可能表示系统内存的结束地址。 +g_excInteractMemSize 是一个 UINTPTR 类型的变量,在 LOSCFG_EXC_INTERACTION 宏开启时会被定义,可能表示异常交互模块的内存大小。 +g_memCheckLevel 是一个 UINT8 类型的变量,在 LOSCFG_BASE_MEM_NODE_SIZE_CHECK 宏开启时会被定义,可能表示内存节点大小检查级别。 +g_moduleMemUsedSize 是一个 UINT32 类型的数组,在 LOSCFG_MEM_MUL_MODULE 宏开启时会被定义,可能表示多模块内存使用情况。 +OsMemNodeSave 是一个静态函数,可能用于备份内存节点的头部信息。 +OsMemAllocWithCheck 是一个静态函数,可能用于带检查的内存分配操作。 +*/ STATIC INLINE VOID OS_MEM_TASKID_SET(LosMemDynNode *node, UINT32 taskId) { node->selfNode.taskId = taskId; @@ -122,7 +138,12 @@ STATIC INLINE UINT32 OS_MEM_MODID_GET(const LosMemDynNode *node) } #endif - +/*OS_MEM_TASKID_SET 函数用于将给定的任务ID(task ID)设置到指定的内存节点 node 中。 +OS_MEM_TASKID_GET 函数用于从给定的内存节点 node 中获取任务ID(task ID)。 +如果宏 LOSCFG_MEM_MUL_MODULE 被定义,则还有以下两个函数: +OS_MEM_MODID_SET 函数用于将给定的模块ID(module ID)设置到指定的内存节点 node 中。 +OS_MEM_MODID_GET 函数用于从给定的内存节点 node 中获取模块ID(module ID)。 +在设置任务ID或模块ID后,如果宏 LOSCFG_MEM_HEAD_BACKUP 被定义,则会调用 OsMemNodeSave 函数备份内存节点的头部信息。*/ /* * Description : set magic & taskid * Input : node -- the node which will be set magic & taskid @@ -139,6 +160,8 @@ STATIC INLINE VOID OsMemSetMagicNumAndTaskID(LosMemDynNode *node) * or in interrupt, make the value of taskid of node to (TASK_NUM - 1) which is * the id of the extra task. We can record those memory use with that. */ + //这段注释是在说明一种情况,即如果在任务初始化之前(即任务的 runTask 还没有被赋值)或在中断中进行操作,将节点的 taskid 值设置为 (TASK_NUM - 1), +//其中 TASK_NUM 是额外任务的 ID。这样可以记录那些在任务初始化之前或在中断中使用的内存。 if ((runTask != NULL) && OS_INT_INACTIVE) { OS_MEM_TASKID_SET(node, runTask->taskId); } else { @@ -147,7 +170,10 @@ STATIC INLINE VOID OsMemSetMagicNumAndTaskID(LosMemDynNode *node) } #endif } - +//如果宏 LOSCFG_MEM_HEAD_BACKUP 被定义,那么会定义一个名为 CHECKSUM_MAGICNUM 的常量, +//用于计算内存控制节点的校验和。 +OS_MEM_NODE_CHECKSUM_CALCULATE 宏用于计算给定内存控制节点的校验和值。 +OsMemDispCtlNode 函数用于打印给定内存控制节点的相关信息。 #ifdef LOSCFG_BASE_MEM_NODE_SIZE_CHECK const VOID *OsMemFindNodeCtrl(const VOID *pool, const VOID *ptr); #endif @@ -180,6 +206,8 @@ STATIC INLINE VOID OsMemDispCtlNode(const LosMemCtlNode *ctlNode) } STATIC INLINE VOID OsMemDispMoreDetails(const LosMemDynNode *node) +//用于打印关于动态内存节点的更多详细信息。它接受一个 LosMemDynNode 结构体指针作为参数, +//并根据节点的状态打印不同的信息,例如节点是否被使用、分配该节点的任务信息等。 { UINT32 taskId; LosTaskCB *taskCB = NULL; @@ -223,6 +251,7 @@ STATIC INLINE VOID OsMemDispMoreDetails(const LosMemDynNode *node) STATIC INLINE VOID OsMemDispWildPointerMsg(const LosMemDynNode *node, const VOID *ptr) { + //用于在发现野指针时打印相关信息。它接受一个 LosMemDynNode 结构体指针和一个野指针作为参数,并打印出野指针的详细信息,以及可能的原因。 PRINT_ERR("*****************************************************\n"); PRINT_ERR("find an control block at: %p, gap size: 0x%x, sizeof(LosMemDynNode): 0x%x\n", node, node->selfNode.gapSize, sizeof(LosMemDynNode)); @@ -234,17 +263,17 @@ STATIC INLINE VOID OsMemDispWildPointerMsg(const LosMemDynNode *node, const VOID PRINT_ERR("*****************************************************\n\n"); } -STATIC INLINE VOID OsMemChecksumSet(LosMemCtlNode *ctlNode) +STATIC INLINE VOID OsMemChecksumSet(LosMemCtlNode *ctlNode)//用于为控制节点计算并设置校验和。 { ctlNode->checksum = OS_MEM_NODE_CHECKSUM_CALCULATE(ctlNode); } -STATIC INLINE BOOL OsMemChecksumVerify(const LosMemCtlNode *ctlNode) +STATIC INLINE BOOL OsMemChecksumVerify(const LosMemCtlNode *ctlNode)//验证控制节点的校验和是否正确。 { return ctlNode->checksum == OS_MEM_NODE_CHECKSUM_CALCULATE(ctlNode); } -STATIC INLINE VOID OsMemBackupSetup(const LosMemDynNode *node) +STATIC INLINE VOID OsMemBackupSetup(const LosMemDynNode *node)//为当前节点的前一个节点设置备份信息 { LosMemDynNode *nodePre = node->selfNode.preNode; if (nodePre != NULL) { @@ -257,7 +286,7 @@ STATIC INLINE VOID OsMemBackupSetup(const LosMemDynNode *node) } } -LosMemDynNode *OsMemNodeNextGet(const VOID *pool, const LosMemDynNode *node) +LosMemDynNode *OsMemNodeNextGet(const VOID *pool, const LosMemDynNode *node)//获取指定节点的下一个节点 { const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool; @@ -269,6 +298,7 @@ LosMemDynNode *OsMemNodeNextGet(const VOID *pool, const LosMemDynNode *node) } STATIC INLINE UINT32 OsMemBackupSetup4Next(const VOID *pool, LosMemDynNode *node) +//为下一个节点设置备份信息,并检查下一个节点的校验和是否正确。 { LosMemDynNode *nodeNext = OsMemNodeNextGet(pool, node); @@ -294,6 +324,8 @@ STATIC INLINE UINT32 OsMemBackupSetup4Next(const VOID *pool, LosMemDynNode *node UINT32 OsMemBackupDoRestore(VOID *pool, const LosMemDynNode *nodePre, LosMemDynNode *node) { + //从备份中恢复节点。它首先打印出备份信息和原节点信息,然后将备份信息中记录的值恢复到节点中, + //并调用 OsMemBackupSetup4Next 重新设置下一个节点的备份信息。 if (node == NULL) { PRINT_ERR("the node is NULL.\n"); return LOS_NOK; @@ -315,6 +347,7 @@ UINT32 OsMemBackupDoRestore(VOID *pool, const LosMemDynNode *nodePre, LosMemDynN } STATIC LosMemDynNode *OsMemFirstNodePrevGet(const LosMemPoolInfo *poolInfo) +//获取内存池中第一个节点的前一个节点。 { LosMemDynNode *nodePre = NULL; @@ -335,6 +368,7 @@ STATIC LosMemDynNode *OsMemFirstNodePrevGet(const LosMemPoolInfo *poolInfo) } LosMemDynNode *OsMemNodePrevGet(VOID *pool, const LosMemDynNode *node) +//在内存池中查找给定节点的前一个节点。 { LosMemDynNode *nodeCur = NULL; LosMemDynNode *nodePre = NULL; @@ -393,7 +427,7 @@ LosMemDynNode *OsMemNodePrevGet(VOID *pool, const LosMemDynNode *node) } LosMemDynNode *OsMemNodePrevTryGet(VOID *pool, LosMemDynNode **node, const VOID *ptr) -{ +{//在内存池中尝试获取指向给定地址的节点的前一个节点。 UINTPTR nodeShouldBe; LosMemDynNode *nodeCur = NULL; LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; @@ -447,7 +481,7 @@ LosMemDynNode *OsMemNodePrevTryGet(VOID *pool, LosMemDynNode **node, const VOID } STATIC INLINE UINT32 OsMemBackupTryRestore(VOID *pool, LosMemDynNode **node, const VOID *ptr) -{ +{//尝试恢复节点的备份状态。 LosMemDynNode *nodeHead = NULL; LosMemDynNode *nodePre = OsMemNodePrevTryGet(pool, &nodeHead, ptr); if (nodePre == NULL) { @@ -459,7 +493,7 @@ STATIC INLINE UINT32 OsMemBackupTryRestore(VOID *pool, LosMemDynNode **node, con } STATIC INLINE UINT32 OsMemBackupRestore(VOID *pool, LosMemDynNode *node) -{ +{//恢复节点的备份状态 LosMemDynNode *nodePre = OsMemNodePrevGet(pool, node); if (nodePre == NULL) { return LOS_NOK; @@ -469,7 +503,7 @@ STATIC INLINE UINT32 OsMemBackupRestore(VOID *pool, LosMemDynNode *node) } STATIC INLINE UINT32 OsMemBackupCheckAndRetore(VOID *pool, const VOID *ptr, LosMemDynNode *node) -{ +{//检查并恢复节点的备份状态。 LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; LosMemDynNode *startNode = OS_MEM_FIRST_NODE(pool); LosMemDynNode *endNode = OS_MEM_END_NODE(pool, poolInfo->poolSize); @@ -485,26 +519,26 @@ STATIC INLINE UINT32 OsMemBackupCheckAndRetore(VOID *pool, const VOID *ptr, LosM } STATIC INLINE VOID OsMemSetGapSize(LosMemCtlNode *ctlNode, UINT32 gapSize) -{ +{//设置节点的间隙大小。 ctlNode->gapSize = gapSize; } STATIC VOID OsMemNodeSave(LosMemDynNode *node) -{ +{//保存节点的状态信息 OsMemSetGapSize(&(node->selfNode), 0); OsMemChecksumSet(&(node->selfNode)); OsMemBackupSetup(node); } STATIC VOID OsMemNodeSaveWithGapSize(LosMemDynNode *node, UINT32 gapSize) -{ +{//保存节点的状态信息,并设置间隙大小。 OsMemSetGapSize(&(node->selfNode), gapSize); OsMemChecksumSet(&(node->selfNode)); OsMemBackupSetup(node); } STATIC VOID OsMemListDelete(LOS_DL_LIST *node, const VOID *firstNode) -{ +{//从链表中删除节点 LosMemDynNode *dynNode = NULL; node->pstNext->pstPrev = node->pstPrev; @@ -528,7 +562,7 @@ STATIC VOID OsMemListDelete(LOS_DL_LIST *node, const VOID *firstNode) } STATIC VOID OsMemListAdd(LOS_DL_LIST *listNode, LOS_DL_LIST *node, const VOID *firstNode) -{ +{//将节点添加到链表中 LosMemDynNode *dynNode = NULL; node->pstNext = listNode->pstNext; @@ -547,6 +581,7 @@ STATIC VOID OsMemListAdd(LOS_DL_LIST *listNode, LOS_DL_LIST *node, const VOID *f } VOID LOS_MemBadNodeShow(VOID *pool) +//遍历给定内存池中的内存动态节点,检查节点的校验和,然后打印出错的节点以及其前一个节点的信息。 { LosMemDynNode *nodePre = NULL; LosMemDynNode *tmpNode = NULL; @@ -584,7 +619,7 @@ VOID LOS_MemBadNodeShow(VOID *pool) #else /* without LOSCFG_MEM_HEAD_BACKUP */ STATIC VOID OsMemListDelete(LOS_DL_LIST *node, const VOID *firstNode) -{ +{//从双向链表中删除指定的节点 (VOID)firstNode; node->pstNext->pstPrev = node->pstPrev; node->pstPrev->pstNext = node->pstNext; @@ -593,7 +628,7 @@ STATIC VOID OsMemListDelete(LOS_DL_LIST *node, const VOID *firstNode) } STATIC VOID OsMemListAdd(LOS_DL_LIST *listNode, LOS_DL_LIST *node, const VOID *firstNode) -{ +{//将节点添加到双向链表中 (VOID)firstNode; node->pstNext = listNode->pstNext; node->pstPrev = listNode; @@ -604,6 +639,9 @@ STATIC VOID OsMemListAdd(LOS_DL_LIST *listNode, LOS_DL_LIST *node, const VOID *f #endif #ifdef LOSCFG_MEM_LEAKCHECK +//用于注册内存动态节点并记录它的链路寄存器信息。具体来说, +//该函数会将当前节点的 linkReg 数组清零,并调用 ArchGetFp 函数获取当前栈帧指针, +//然后调用 ArchBackTraceGet 函数获取从当前栈帧开始的函数调用链信息并保存在 linkReg 数组中。 __attribute__((always_inline)) inline VOID OsMemLinkRegisterRecord(LosMemDynNode *node) { UINTPTR framePtr; @@ -616,6 +654,9 @@ __attribute__((always_inline)) inline VOID OsMemLinkRegisterRecord(LosMemDynNode } #ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK +//只有在开启了内存节点完整性检查、并且发现了内存节点错误时才会被调用。 +//该函数用于打印出错节点和前一个节点的链路寄存器信息,以帮助进行故障排查和修复。 +//如果定义了 LOSCFG_SHELL_EXCINFO_DUMP 宏,则还会将信息输出到异常信息缓冲区中。 STATIC VOID OsMemNodeBacktraceInfo(const LosMemDynNode *tmpNode, const LosMemDynNode *preNode) { INT32 i; @@ -642,6 +683,8 @@ STATIC VOID OsMemNodeBacktraceInfo(const LosMemDynNode *tmpNode, const LosMemDyn #endif LITE_OS_SEC_TEXT_MINOR VOID OsMemUsedNodeShow(VOID *pool) +//打印出使用的内存节点和相关的链接寄存器。 +//它接受一个指向内存池的指针作为参数,并遍历内存池中的节点来打印信息。 { LosMemDynNode *tmpNode = NULL; LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; @@ -697,6 +740,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsMemUsedNodeShow(VOID *pool) #ifdef LOSCFG_KERNEL_MEM_SLAB_EXTENTION STATIC VOID *OsMemReallocSlab(VOID *pool, VOID *ptr, BOOL *isSlabMem, UINT32 size) { + //在扩展内核内存时重新分配用于内存池的内存块。它接受一个指向内存池的指针、一个指向原始内存块的指针以及一个布尔值的指针作为参数,返回重新分配后的内存块指针。 errno_t rc; UINT32 blkSz; VOID *newPtr = NULL; @@ -736,12 +780,15 @@ STATIC VOID *OsMemReallocSlab(VOID *pool, VOID *ptr, BOOL *isSlabMem, UINT32 siz } VOID *OsMemAlloc(VOID *pool, UINT32 size) +//分配指定大小的内存块。它接受一个指向内存池的指针和一个大小参数,并返回分配的内存块指针。 + + { return OsMemAllocWithCheck(pool, size); } #else - +//与上述函数相同,但只在支持内存泄漏检测的情况下启用。(条件编译) STATIC VOID *OsMemReallocSlab(VOID *pool, const VOID *ptr, BOOL *isSlabMem, UINT32 size) { *isSlabMem = FALSE; @@ -752,6 +799,7 @@ STATIC VOID *OsMemReallocSlab(VOID *pool, const VOID *ptr, BOOL *isSlabMem, UINT #ifdef LOSCFG_EXC_INTERACTION LITE_OS_SEC_TEXT_INIT UINT32 OsMemExcInteractionInit(UINTPTR memStart) +//初始化用于异常交互的内存。它接受一个起始内存地址参数,并返回初始化结果。 { UINT32 ret; m_aucSysMem0 = (UINT8 *)memStart; @@ -763,6 +811,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMemExcInteractionInit(UINTPTR memStart) #endif LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(UINTPTR memStart) +//初始化系统堆内存。它接受一个起始内存地址参数,并返回初始化结果。 { UINT32 ret; UINT32 poolSize; @@ -785,7 +834,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(UINTPTR memStart) * tmpNode --- pointer a suitable free block */ STATIC INLINE LosMemDynNode *OsMemFindSuitableFreeBlock(VOID *pool, UINT32 allocSize) -{ +{//在内存池中查找合适的空闲块以供分配使用的功能 LOS_DL_LIST *listNodeHead = NULL; LosMemDynNode *tmpNode = NULL; @@ -825,20 +874,17 @@ STATIC INLINE LosMemDynNode *OsMemFindSuitableFreeBlock(VOID *pool, UINT32 alloc return NULL; } -/* - * Description : clear a mem node, set every member to NULL - * Input : node --- Pointer to the mem node which will be cleared up - */ -STATIC INLINE VOID OsMemClearNode(LosMemDynNode *node) + +STATIC INLINE VOID OsMemClearNode(LosMemDynNode *node)//将 LosMemDynNode 结构体清零。 + + { (VOID)memset_s((VOID *)node, sizeof(LosMemDynNode), 0, sizeof(LosMemDynNode)); } -/* - * Description : merge this node and pre node, then clear this node info - * Input : node --- Pointer to node which will be merged - */ -STATIC INLINE VOID OsMemMergeNode(LosMemDynNode *node) + +STATIC INLINE VOID OsMemMergeNode(LosMemDynNode *node)//合并两个相邻的空闲节点。具体实现是将当前节点和后继节点合并成一个大的空闲节点,然后将当前节点清零。 + LosMemDynNode *newFreeNode = NULL; { LosMemDynNode *nextNode = NULL; @@ -852,18 +898,13 @@ STATIC INLINE VOID OsMemMergeNode(LosMemDynNode *node) OsMemClearNode(node); } -/* - * Description : split new node from allocNode, and merge remainder mem if necessary - * Input : pool -- Pointer to memory pool - * allocNode -- the source node which the new node will split from it. - * After pick up it's node info, change to point to the new node - * allocSize -- the size of new node - * Output : allocNode -- save new node addr - */ STATIC INLINE VOID OsMemSplitNode(VOID *pool, LosMemDynNode *allocNode, UINT32 allocSize) -{ - LosMemDynNode *newFreeNode = NULL; +{//将一个空闲节点分割成两个,并将其中一个分配给需要的内存块。 +//具体实现是在当前空闲节点上创建一个新的空闲节点,并将原有空闲节点的部分内存分配给新节点, +//再将新节点添加到对应链表中。 + + LosMemDynNode *nextNode = NULL; LOS_DL_LIST *listNodeHead = NULL; const VOID *firstNode = (const VOID *)((UINT8 *)OS_MEM_HEAD_ADDR(pool) + OS_DLNK_HEAD_SIZE); @@ -899,7 +940,7 @@ STATIC INLINE VOID OsMemSplitNode(VOID *pool, * pool -- Pointer to memory pool */ STATIC INLINE VOID OsMemFreeNode(LosMemDynNode *node, LosMemPoolInfo *pool) -{ +{//释放内存节点的,它包括了一些内存合并和链表操作 LosMemDynNode *nextNode = NULL; LOS_DL_LIST *listNodeHead = NULL; const VOID *firstNode = (const VOID *)((UINT8 *)OS_MEM_HEAD_ADDR(pool) + OS_DLNK_HEAD_SIZE); @@ -942,12 +983,7 @@ STATIC INLINE VOID OsMemFreeNode(LosMemDynNode *node, LosMemPoolInfo *pool) } #ifdef LOSCFG_MEM_DEBUG -/* - * Description : check the result if pointer memory node belongs to pointer memory pool - * Input : pool -- Pointer to memory pool - * node -- the node which need be checked - * Return : LOS_OK or LOS_NOK - */ +//OsMemIsNodeValid 和 OsMemCheckUsedNode 则是用来检查内存节点的有效性的函数 STATIC INLINE BOOL OsMemIsNodeValid(const LosMemDynNode *node, const LosMemDynNode *startNode, const LosMemDynNode *endNode, const UINT8 *startPool, const UINT8 *endPool) @@ -1003,7 +1039,7 @@ STATIC INLINE VOID OsMemCheckUsedNode(const VOID *pool, const LosMemDynNode *nod #ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT32 OsMemPoolDlinkcheck(const LosMemPoolInfo *pool, LOS_DL_LIST listHead) -{ +{//OsMemPoolDlinkcheck 则是用来检查内存池的双向链表的函数 if (((UINTPTR)listHead.pstPrev < (UINTPTR)(pool + 1)) || ((UINTPTR)listHead.pstPrev >= ((UINTPTR)pool + pool->poolSize)) || ((UINTPTR)listHead.pstNext < (UINTPTR)(pool + 1)) || @@ -1021,7 +1057,7 @@ LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT32 OsMemPoolDlinkcheck(const LosMemPool * Input : pool --Pointer to memory pool */ LITE_OS_SEC_TEXT_MINOR VOID OsMemPoolHeadInfoPrint(const VOID *pool) -{ +{//打印内存池头部信息(poolAddr, poolSize等),以及检查内存池的双向链表是否异常(如果异常,则打印链表头的前后指针) const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool; UINT32 dlinkNum; UINT32 flag = 0; @@ -1065,7 +1101,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsMemPoolHeadInfoPrint(const VOID *pool) } STATIC UINT32 OsMemIntegrityCheck(const VOID *pool, LosMemDynNode **tmpNode, LosMemDynNode **preNode) -{ +{//检查整个内存池的完整性,并输出相关信息。具体实现是从第一个节点开始遍历,逐一检查节点的合法性。如果检测到错误,会触发系统崩溃 const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool; const UINT8 *endPool = (const UINT8 *)pool + poolInfo->poolSize; @@ -1118,7 +1154,7 @@ STATIC UINT32 OsMemIntegrityCheck(const VOID *pool, LosMemDynNode **tmpNode, Los STATIC VOID OsMemNodeInfo(const LosMemDynNode *tmpNode, const LosMemDynNode *preNode) -{ +{//这个函数的作用是输出节点信息,包括节点前后指针、节点大小、堆栈信息等。同时还会输出相关的内存数据,方便调试。 if (tmpNode == preNode) { PRINTK("\n the broken node is the first node\n"); #ifdef LOSCFG_SHELL_EXCINFO_DUMP @@ -1158,7 +1194,8 @@ STATIC VOID OsMemNodeInfo(const LosMemDynNode *tmpNode, STATIC VOID OsMemIntegrityCheckError(const LosMemDynNode *tmpNode, const LosMemDynNode *preNode) -{ +{//当检测到内存池的完整性出现问题时,输出相关信息,并触发系统崩溃。 +//同时,该函数会输出当前节点和前一个节点的信息,以及前一个节点的所属任务的相关信息。 LosTaskCB *taskCB = NULL; UINT32 taskId; @@ -1197,7 +1234,9 @@ STATIC VOID OsMemIntegrityCheckError(const LosMemDynNode *tmpNode, * Return : LOS_OK --memory pool integrate or LOS_NOK--memory pool impaired */ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool) -{ +{//用于检查指定内存池的完整性。它首先对传入的参数进行空指针判断, +//然后获取互斥锁,调用OsMemIntegrityCheck函数来检查内存池的完整性。 +//如果检查失败,则调用OsMemIntegrityCheckError函数进行错误处理,并释放互斥锁 LosMemDynNode *tmpNode = NULL; LosMemDynNode *preNode = NULL; UINT32 intSave; @@ -1219,7 +1258,7 @@ ERROR_OUT: return LOS_NOK; } -VOID OsMemIntegrityMultiCheck(VOID) +VOID OsMemIntegrityMultiCheck(VOID)//进行多个内存池的完整性检查 { if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) { PRINTK("system memcheck over, all passed!\n"); @@ -1237,6 +1276,7 @@ VOID OsMemIntegrityMultiCheck(VOID) #endif } #else +//如果定义了宏LOSCFG_EXC_INTERACTION,则调用LOS_MemIntegrityCheck函数来检查异常交互内存池m_aucSysMem0的完整性,并输出检查结果。 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool) { return LOS_OK; @@ -1248,7 +1288,7 @@ VOID OsMemIntegrityMultiCheck(VOID) #endif STATIC INLINE VOID OsMemNodeDebugOperate(VOID *pool, LosMemDynNode *allocNode, UINT32 size) -{ +{//用于内存节点的调试操作 #ifdef LOSCFG_MEM_HEAD_BACKUP OsMemNodeSave(allocNode); #endif @@ -1259,7 +1299,8 @@ STATIC INLINE VOID OsMemNodeDebugOperate(VOID *pool, LosMemDynNode *allocNode, U } STATIC UINT32 OsMemInfoGet(const VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) -{ +{//获取指定内存池的信息。它首先对传入的参数进行类型转换和有效性检查, +//然后遍历内存池中的节点,统计已使用和空闲节点的数量、总大小等信息。 LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; LosMemDynNode *tmpNode = NULL; UINT32 totalUsedSize = 0; @@ -1302,7 +1343,7 @@ STATIC UINT32 OsMemInfoGet(const VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) } VOID OsMemInfoPrint(const VOID *pool) -{ +{//打印内存池的信息 LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; LOS_MEM_POOL_STATUS status = {0}; @@ -1351,7 +1392,8 @@ STATIC INLINE VOID OsMemInfoAlert(const VOID *pool, UINT32 allocSize) * Return : Pointer to allocated memory */ STATIC VOID *OsMemAllocWithCheck(LosMemPoolInfo *pool, UINT32 size) -{ +{//分配内存的函数,它首先对要分配的内存大小进行一些处理,然后查找合适大小的空闲块, +//如果找到则进行分割和设置标记等操作,最后返回分配的内存块。 LosMemDynNode *allocNode = NULL; UINT32 allocSize; @@ -1392,16 +1434,9 @@ STATIC VOID *OsMemAllocWithCheck(LosMemPoolInfo *pool, UINT32 size) return (allocNode + 1); } -/* - * Description : reAlloc a smaller memory node - * Input : pool --- Pointer to memory pool - * allocSize --- the size of new node which will be alloced - * node --- the node which will be realloced - * nodeSize --- the size of old node - * Output : node --- pointer to the new node after realloc - */ + STATIC INLINE VOID OsMemReAllocSmaller(LosMemPoolInfo *pool, UINT32 allocSize, LosMemDynNode *node, UINT32 nodeSize) -{ +{//重新分配较小内存块的函数,它会判断是否可以将原有内存块进行分割,如果可以则进行相应的操作。 if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= nodeSize) { node->selfNode.sizeAndFlag = nodeSize; OsMemSplitNode(pool, node, allocSize); @@ -1417,18 +1452,10 @@ STATIC INLINE VOID OsMemReAllocSmaller(LosMemPoolInfo *pool, UINT32 allocSize, L #endif } -/* - * Description : reAlloc a Bigger memory node after merge node and nextNode - * Input : pool --- Pointer to memory pool - * allocSize --- the size of new node which will be alloced - * node --- the node which will be realloced - * nodeSize --- the size of old node - * nextNode --- pointer next node which will be merged - * Output : node --- pointer to the new node after realloc - */ + STATIC INLINE VOID OsMemMergeNodeForReAllocBigger(LosMemPoolInfo *pool, UINT32 allocSize, LosMemDynNode *node, UINT32 nodeSize, LosMemDynNode *nextNode) -{ +{//重新分配较大内存块的函数,它会判断是否需要合并相邻的内存块,并进行相应的操作。 const VOID *firstNode = (const VOID *)((UINT8 *)OS_MEM_HEAD_ADDR(pool) + OS_DLNK_HEAD_SIZE); node->selfNode.sizeAndFlag = nodeSize; @@ -1450,7 +1477,7 @@ STATIC INLINE VOID OsMemMergeNodeForReAllocBigger(LosMemPoolInfo *pool, UINT32 a } STATIC UINT32 OsMemInit(VOID *pool, UINT32 size) -{ +{//初始化内存池的函数,它会对内存池进行一些必要的初始化工作,包括设置头结点、尾结点,以及初始化统计信息等。 LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; LosMemDynNode *newNode = NULL; LosMemDynNode *endNode = NULL; @@ -1500,7 +1527,7 @@ STATIC UINT32 OsMemInit(VOID *pool, UINT32 size) } LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pool, UINT32 size) -{ +{//初始化内存池,其中包括对内存池的大小、对齐等进行检查,并调用相应的内部函数进行内存池的初始化工作。 UINT32 intSave; if ((pool == NULL) || (size < OS_MEM_MIN_POOL_SIZE)) { @@ -1533,7 +1560,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pool, UINT32 size) } LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size) -{ +{//从内存池中分配指定大小的内存块, +//其中包括调用 OsSlabMemAlloc 和 OsMemAllocWithCheck 等函数来实现内存的分配。 VOID *ptr = NULL; UINT32 intSave; @@ -1564,7 +1592,7 @@ LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size) } LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) -{ +{//按照指定的对齐边界来分配内存,其中包括对边界对齐和内存分配的相关处理。 UINT32 useSize; UINT32 gapSize; VOID *ptr = NULL; @@ -1622,7 +1650,7 @@ LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundar } LITE_OS_SEC_TEXT STATIC INLINE VOID OsDoMemFree(VOID *pool, const VOID *ptr, LosMemDynNode *node) -{ +{//释放内存,其中包括内存检查和内存释放等操作。 OsMemCheckUsedNode(pool, node); OsMemFreeNode(node, pool); @@ -1634,7 +1662,7 @@ LITE_OS_SEC_TEXT STATIC INLINE VOID OsDoMemFree(VOID *pool, const VOID *ptr, Los } UINT32 OsMemFree(VOID *pool, const VOID *ptr) -{ +{//释放内存,其中包括内存检查和内存释放等操作。 UINT32 ret = LOS_OK; UINT32 gapSize; LosMemDynNode *node = NULL; @@ -1673,7 +1701,7 @@ OUT: } LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pool, VOID *ptr) -{ +{//判断了传入参数的有效性,然后调用OsSlabMemFree和OsMemFree进行内存的释放操作,并最终返回相应的状态码 UINT32 ret; UINT32 intSave; @@ -1698,7 +1726,8 @@ OUT: } STATIC VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) -{ +{//根据传入的指针获取真正的内存地址,这个地址是动态内存块的起始地址。在获取真实地址之前, +//需要判断相邻内存块的标志位和大小是否正确,以保证获取到的内存地址是正确的。 VOID *realPtr = ptr; UINT32 gapSize = *((UINT32 *)((UINTPTR)ptr - sizeof(UINT32))); @@ -1719,7 +1748,10 @@ STATIC VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) } STATIC VOID *OsMemRealloc(VOID *pool, VOID *ptr, UINT32 size) -{ +{//实现内存重新分配的功能。首先,它会根据传入的指针获取真正的内存地址, +//并对节点信息进行一系列的检查。如果需要重新分配的内存大小小于原有内存块的大小 +//则直接将原有内存块作为新的内存块返回。 +//否则,需要进行内存的合并或者申请新的内存块等操作。 LosMemDynNode *node = NULL; LosMemDynNode *nextNode = NULL; VOID *tmpPtr = NULL; @@ -1761,7 +1793,8 @@ STATIC VOID *OsMemRealloc(VOID *pool, VOID *ptr, UINT32 size) } LITE_OS_SEC_TEXT_MINOR VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) -{ +{//对OsMemRealloc和OsMemReallocSlab函数的封装。如果传入的内存池是Slab内存池, +//则调用OsMemReallocSlab函数进行处理;否则,则调用OsMemRealloc函数进行处理。 UINT32 intSave; VOID *newPtr = NULL; BOOL isSlabMem = FALSE; @@ -1798,7 +1831,10 @@ OUT: } LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool) -{ +{//获取指定内存池已使用的总字节数。它通过遍历内存池中的动态内存节点,判断节点是否被使用, +//并累计已使用的字节数。 + + LosMemDynNode *tmpNode = NULL; LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; UINT32 memUsed = 0; @@ -1823,7 +1859,8 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool) } LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemUsedBlksGet(VOID *pool) -{ +{//获取指定内存池已使用的内存块数量。 +//它通过遍历内存池中的动态内存节点,判断节点是否被使用,并累计已使用的内存块数量。 LosMemDynNode *tmpNode = NULL; LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; UINT32 blkNums = 0; @@ -1848,7 +1885,8 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemUsedBlksGet(VOID *pool) } LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTaskIdGet(const VOID *ptr) -{ +{//根据指针获取其所在的任务ID。它首先判断指针是否在系统内存范围内, +//然后遍历内存池中的动态内存节点,找到指针所在的内存块,再获取该内存块所属的任务ID。 LosMemDynNode *tmpNode = NULL; LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)(VOID *)m_aucSysMem1; UINT32 intSave; @@ -1887,7 +1925,8 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTaskIdGet(const VOID *ptr) } LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemFreeBlksGet(VOID *pool) -{ +{//获取指定内存池中空闲的内存块数量。 +//它通过遍历内存池中的动态内存节点,判断节点是否空闲,并累计空闲的内存块数量。 LosMemDynNode *tmpNode = NULL; LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; UINT32 blkNums = 0; @@ -1912,7 +1951,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemFreeBlksGet(VOID *pool) } LITE_OS_SEC_TEXT_MINOR UINTPTR LOS_MemLastUsedGet(VOID *pool) -{ +{//获取指定内存池最后一个使用的内存块的地址 LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; LosMemDynNode *node = NULL; @@ -1936,7 +1975,8 @@ LITE_OS_SEC_TEXT_MINOR UINTPTR LOS_MemLastUsedGet(VOID *pool) * Return : the number of free node */ LITE_OS_SEC_TEXT_MINOR VOID OsMemResetEndNode(VOID *pool, UINTPTR preAddr) -{ +{//重置内存池的末尾节点。它将末尾节点的大小和标志设置为头节点的大小,并根据 preAddr 的值设置前一个节点的指针。 +//然后,它将该节点标记为已使用,并设置魔术数和任务ID。 LosMemDynNode *endNode = (LosMemDynNode *)OS_MEM_END_NODE(pool, ((LosMemPoolInfo *)pool)->poolSize); endNode->selfNode.sizeAndFlag = OS_MEM_NODE_HEAD_SIZE; if (preAddr != 0) { @@ -1950,7 +1990,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsMemResetEndNode(VOID *pool, UINTPTR preAddr) #endif } -UINT32 LOS_MemPoolSizeGet(const VOID *pool) +UINT32 LOS_MemPoolSizeGet(const VOID *pool)//获取内存池的大小。如果传入的内存池为空,则返回错误。 { if (pool == NULL) { return LOS_NOK; @@ -1959,7 +1999,9 @@ UINT32 LOS_MemPoolSizeGet(const VOID *pool) } LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) -{ +{//获取内存池的信息。它接受一个内存池指针和一个指向内存池状态结构体的指针作为参数。 +//首先,它检查传入的指针是否为空,如果为空则返回错误。 +//然后,它获取内存池的信息,并在获取完成后释放内存池的锁。 LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; UINT32 ret; UINT32 intSave; @@ -1982,7 +2024,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *po } STATIC INLINE VOID OsShowFreeNode(UINT32 index, UINT32 length, const UINT32 *countNum) -{ +{//显示空闲节点的信息。它打印出每个块大小对应的节点数量。 UINT32 count = 0; PRINTK("\n block size: "); while (count < length) { @@ -1998,7 +2040,8 @@ STATIC INLINE VOID OsShowFreeNode(UINT32 index, UINT32 length, const UINT32 *cou } LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemFreeNodeShow(VOID *pool) -{ +{//显示剩余的空闲节点数量。它遍历多重双向链表, +//统计每个链表头节点后面的节点数量,并调用 OsShowFreeNode 函数打印出结果。 LOS_DL_LIST *listNodeHead = NULL; LosMultipleDlinkHead *headAddr = (LosMultipleDlinkHead *)((UINTPTR)pool + sizeof(LosMemPoolInfo)); LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; @@ -2043,7 +2086,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemFreeNodeShow(VOID *pool) #ifdef LOSCFG_BASE_MEM_NODE_SIZE_CHECK LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemNodeSizeCheck(VOID *pool, VOID *ptr, UINT32 *totalSize, UINT32 *availSize) -{ +{//进行内存节点大小检查的函数 const VOID *head = NULL; LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; UINT8 *endPool = NULL; @@ -2096,7 +2139,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemNodeSizeCheck(VOID *pool, VOID *ptr, UINT32 * attention : this func couldn't ensure the return memCtrl belongs to ptr it just find forward the most nearly one */ LITE_OS_SEC_TEXT_MINOR const VOID *OsMemFindNodeCtrl(const VOID *pool, const VOID *ptr) -{ +{//查找内存池中指针所指的动态内存节点控制块,并返回其地址 const VOID *head = ptr; if (ptr == NULL) { @@ -2114,7 +2157,7 @@ LITE_OS_SEC_TEXT_MINOR const VOID *OsMemFindNodeCtrl(const VOID *pool, const VOI } LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemCheckLevelSet(UINT8 checkLevel) -{ +{//用于设置内存检查级别,接受一个参数 checkLevel,可以是 LOS_MEM_CHECK_LEVEL_LOW、LOS_MEM_CHECK_LEVEL_HIGH 或 LOS_MEM_CHECK_LEVEL_DISABLE if (checkLevel == LOS_MEM_CHECK_LEVEL_LOW) { PRINTK("%s: LOS_MEM_CHECK_LEVEL_LOW \n", __FUNCTION__); } else if (checkLevel == LOS_MEM_CHECK_LEVEL_HIGH) { @@ -2130,13 +2173,13 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemCheckLevelSet(UINT8 checkLevel) } LITE_OS_SEC_TEXT_MINOR UINT8 LOS_MemCheckLevelGet(VOID) -{ +{//获取当前的内存检查级别,直接返回全局变量 g_memCheckLevel 的值。 return g_memCheckLevel; } UINT32 OsMemSysNodeCheck(VOID *dstAddr, VOID *srcAddr, UINT32 nodeLength, UINT8 pos) -{ +{//检查动态节点控制块的可用大小是否足够,以保证进行 memcpy 或 memset 操作时不会越界 UINT32 ret; UINT32 totalSize = 0; UINT32 availSize = 0; @@ -2180,7 +2223,7 @@ UINT32 OsMemSysNodeCheck(VOID *dstAddr, VOID *srcAddr, UINT32 nodeLength, UINT8 #ifdef LOSCFG_MEM_MUL_MODULE STATIC INLINE UINT32 OsMemModCheck(UINT32 moduleId) -{ +{//检查输入的模块 ID 是否有效 if (moduleId > MEM_MODULE_MAX) { PRINT_ERR("error module ID input!\n"); return LOS_NOK; @@ -2189,7 +2232,7 @@ STATIC INLINE UINT32 OsMemModCheck(UINT32 moduleId) } STATIC INLINE VOID *OsMemPtrToNode(VOID *ptr) -{ +{//将指针转换为动态节点控制块的地址 UINT32 gapSize; if ((UINTPTR)ptr & (OS_MEM_ALIGN_SIZE - 1)) { @@ -2216,7 +2259,7 @@ STATIC INLINE VOID *OsMemPtrToNode(VOID *ptr) } STATIC INLINE UINT32 OsMemNodeSizeGet(VOID *ptr) -{ +{//获取动态节点控制块中记录的节点大小 LosMemDynNode *node = (LosMemDynNode *)OsMemPtrToNode(ptr); if (node == NULL) { return 0; @@ -2226,7 +2269,7 @@ STATIC INLINE UINT32 OsMemNodeSizeGet(VOID *ptr) } VOID *LOS_MemMalloc(VOID *pool, UINT32 size, UINT32 moduleId) -{ +{//在内存池中分配指定大小的内存,并进行模块 ID 的标记 UINT32 intSave; VOID *ptr = NULL; VOID *node = NULL; @@ -2247,7 +2290,8 @@ VOID *LOS_MemMalloc(VOID *pool, UINT32 size, UINT32 moduleId) } VOID *LOS_MemMallocAlign(VOID *pool, UINT32 size, UINT32 boundary, UINT32 moduleId) -{ +{//与 LOS_MemMalloc 函数类似,区别在于它支持按照指定对齐边界分配内存。 +//调用 LOS_MemAllocAlign 分配对齐内存,并执行与 LOS_MemMalloc 相同的操作 UINT32 intSave; VOID *ptr = NULL; VOID *node = NULL; @@ -2268,7 +2312,7 @@ VOID *LOS_MemMallocAlign(VOID *pool, UINT32 size, UINT32 boundary, UINT32 module } UINT32 LOS_MemMfree(VOID *pool, VOID *ptr, UINT32 moduleId) -{ +{//用于释放指定的内存块 UINT32 intSave; UINT32 ret; UINT32 size; @@ -2301,7 +2345,15 @@ UINT32 LOS_MemMfree(VOID *pool, VOID *ptr, UINT32 moduleId) } VOID *LOS_MemMrealloc(VOID *pool, VOID *ptr, UINT32 size, UINT32 moduleId) -{ +{//重新分配指定大小的内存块 +//首先检查模块 ID 和内存池是否有效,如果无效则返回空指针。 +//然后判断传入的指针是否为空,如果为空则调用 LOS_MemMalloc 分配新的内存块。 +//接着将指针转换为动态节点控制块的地址,并判断节点的模块 ID 是否与传入的模块 ID 匹配, +//如果不匹配则打印错误信息并使用节点中记录的模块 ID 进行重新分配操作。如果新的大小为 0, +//则调用 LOS_MemMfree 释放原来的内存块并返回空指针。 +//最后调用 LOS_MemRealloc 进行内存块的重新分配,并更新模块使用的内存大小。 + + VOID *newPtr = NULL; UINT32 oldNodeSize; UINT32 intSave; @@ -2346,7 +2398,7 @@ VOID *LOS_MemMrealloc(VOID *pool, VOID *ptr, UINT32 size, UINT32 moduleId) } UINT32 LOS_MemMusedGet(UINT32 moduleId) -{ +{//获取指定模块使用的内存大小 if (OsMemModCheck(moduleId) == LOS_NOK) { return OS_NULL_INT; }