更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_memory.c 文件参考

http://www.gii.upv.es/tlsf/files/ecrts04_tlsf.pdf 更多...

浏览源代码.

结构体

struct  OsMemNodeHead
 内存池节点 更多...
 
struct  OsMemUsedNodeHead
 已使用内存池节点 更多...
 
struct  OsMemFreeNodeHead
 内存池空闲节点 更多...
 
struct  OsMemPoolInfo
 内存池信息 更多...
 
struct  OsMemPoolHead
 内存池头信息 更多...
 

函数

STATIC INLINE UINT16 OsMemFFS (UINT32 bitmap)
 
STATIC INLINE UINT16 OsMemFLS (UINT32 bitmap)
 
STATIC INLINE UINT32 OsMemLog2 (UINT32 size)
 
STATIC INLINE UINT32 OsMemFlGet (UINT32 size)
 
STATIC INLINE UINT32 OsMemSlGet (UINT32 size, UINT32 fl)
 
STATIC INLINE VOID OsMemFreeNodeAdd (VOID *pool, struct OsMemFreeNodeHead *node)
 添加一个空闲节点 更多...
 
STATIC INLINE UINT32 OsMemFree (struct OsMemPoolHead *pool, struct OsMemNodeHead *node)
 释放内存 更多...
 
STATIC VOID OsMemInfoPrint (VOID *pool)
 
STATIC INLINE UINT32 OsMemAllocCheck (struct OsMemPoolHead *pool, UINT32 intSave)
 
STATIC INLINE VOID OsMemNodeSetTaskID (struct OsMemUsedNodeHead *node)
 
STATIC INLINE VOID OsMemWaterUsedRecord (struct OsMemPoolHead *pool, UINT32 size)
 
STATIC INLINE struct OsMemNodeHeadOsMemLastSentinelNodeGet (const struct OsMemNodeHead *sentinelNode)
 更新哨兵节点内容 更多...
 
STATIC INLINE BOOL OsMemSentinelNodeCheck (struct OsMemNodeHead *sentinelNode)
 检查哨兵节点 更多...
 
STATIC INLINE BOOL OsMemIsLastSentinelNode (struct OsMemNodeHead *sentinelNode)
 是否为最后一个哨兵节点 更多...
 
STATIC INLINE VOID OsMemSentinelNodeSet (struct OsMemNodeHead *sentinelNode, VOID *newNode, UINT32 size)
 设置哨兵节点内容 更多...
 
STATIC INLINE VOID * OsMemSentinelNodeGet (struct OsMemNodeHead *node)
 
STATIC INLINE struct OsMemNodeHeadPreSentinelNodeGet (const VOID *pool, const struct OsMemNodeHead *node)
 
UINT32 OsMemLargeNodeFree (const VOID *ptr)
 大内存释放 更多...
 
STATIC INLINE BOOL TryShrinkPool (const VOID *pool, const struct OsMemNodeHead *node)
 
STATIC INLINE INT32 OsMemPoolExpandSub (VOID *pool, UINT32 size, UINT32 intSave)
 内存池扩展实现 更多...
 
STATIC INLINE INT32 OsMemPoolExpand (VOID *pool, UINT32 allocSize, UINT32 intSave)
 扩展内存池 更多...
 
VOID LOS_MemExpandEnable (VOID *pool)
 Enable memory pool to support dynamic expansion. 更多...
 
STATIC INLINE VOID OsLmsFirstNodeMark (VOID *pool, struct OsMemNodeHead *node)
 
STATIC INLINE VOID OsLmsAllocAlignMark (VOID *ptr, VOID *alignedPtr, UINT32 size)
 
STATIC INLINE VOID OsLmsReallocMergeNodeMark (struct OsMemNodeHead *node)
 
STATIC INLINE VOID OsLmsReallocSplitNodeMark (struct OsMemNodeHead *node)
 
STATIC INLINE VOID OsLmsReallocResizeMark (struct OsMemNodeHead *node, UINT32 resize)
 
STATIC INLINE VOID OsMemLinkRegisterRecord (struct OsMemNodeHead *node)
 
STATIC INLINE VOID OsMemUsedNodePrint (struct OsMemNodeHead *node)
 
VOID OsMemUsedNodeShow (VOID *pool)
 打印已使用的节点 更多...
 
STATIC VOID OsMemNodeBacktraceInfo (const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode)
 
STATIC INLINE UINT32 OsMemFreeListIndexGet (UINT32 size)
 
STATIC INLINE struct OsMemFreeNodeHeadOsMemFindCurSuitableBlock (struct OsMemPoolHead *poolHead, UINT32 index, UINT32 size)
 
STATIC INLINE UINT32 OsMemNotEmptyIndexGet (struct OsMemPoolHead *poolHead, UINT32 index)
 
STATIC INLINE struct OsMemFreeNodeHeadOsMemFindNextSuitableBlock (VOID *pool, UINT32 size, UINT32 *outIndex)
 找到下一个合适的块 更多...
 
STATIC INLINE VOID OsMemSetFreeListBit (struct OsMemPoolHead *head, UINT32 index)
 
STATIC INLINE VOID OsMemClearFreeListBit (struct OsMemPoolHead *head, UINT32 index)
 
STATIC INLINE VOID OsMemListAdd (struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node)
 
STATIC INLINE VOID OsMemListDelete (struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node)
 从空闲链表中删除 更多...
 
STATIC INLINE VOID OsMemFreeNodeDelete (VOID *pool, struct OsMemFreeNodeHead *node)
 从空闲链表上摘除节点 更多...
 
STATIC INLINE struct OsMemNodeHeadOsMemFreeNodeGet (VOID *pool, UINT32 size)
 
STATIC INLINE VOID OsMemMergeNode (struct OsMemNodeHead *node)
 合并节点,和前面的节点合并 node 消失 更多...
 
STATIC INLINE VOID OsMemSplitNode (VOID *pool, struct OsMemNodeHead *allocNode, UINT32 allocSize)
 切割节点 更多...
 
STATIC INLINE VOID * OsMemCreateUsedNode (VOID *addr)
 
STATIC UINT32 OsMemPoolInit (VOID *pool, UINT32 size)
 OsMemPoolInit 内存池初始化 内存池节点部分包含3种类型节点:未使用空闲内存节点(OsMemFreeNodeHead),已使用内存节点(OsMemUsedNodeHead) 和 尾节点(OsMemNodeHead)。
每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。
空闲内存节点和已使用内存节点后面的内存区域是数据域 更多...
 
STATIC VOID OsMemPoolDeinit (VOID *pool)
 
STATIC UINT32 OsMemPoolAdd (VOID *pool, UINT32 size)
 新增内存池 更多...
 
STATIC UINT32 OsMemPoolDelete (VOID *pool)
 删除内存池 更多...
 
UINT32 LOS_MemInit (VOID *pool, UINT32 size)
 LOS_MemInit 初始化一块指定的动态内存池,大小为size 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。 更多...
 
UINT32 LOS_MemDeInit (VOID *pool)
 删除指定内存池 更多...
 
UINT32 LOS_MemPoolList (VOID)
 打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。 更多...
 
STATIC INLINE VOID * OsMemAlloc (struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave)
 从指定动态内存池中申请size长度的内存 更多...
 
VOID * LOS_MemAlloc (VOID *pool, UINT32 size)
 从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存 更多...
 
VOID * LOS_MemAllocAlign (VOID *pool, UINT32 size, UINT32 boundary)
 从指定内存池中申请size长度的内存且地址按boundary字节对齐的内存 更多...
 
STATIC INLINE BOOL OsMemAddrValidCheck (const struct OsMemPoolHead *pool, const VOID *addr)
 内存池有效性检查 更多...
 
STATIC INLINE BOOL OsMemIsNodeValid (const struct OsMemNodeHead *node, const struct OsMemNodeHead *startNode, const struct OsMemNodeHead *endNode, const struct OsMemPoolHead *poolInfo)
 
STATIC BOOL MemCheckUsedNode (const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node, const struct OsMemNodeHead *startNode, const struct OsMemNodeHead *endNode)
 
STATIC UINT32 OsMemCheckUsedNode (const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node)
 
UINT32 LOS_MemFree (VOID *pool, VOID *ptr)
 释放从指定动态内存中申请的内存 更多...
 
STATIC INLINE VOID OsMemReAllocSmaller (VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize)
 
STATIC INLINE VOID OsMemMergeNodeForReAllocBigger (VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize, struct OsMemNodeHead *nextNode)
 
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)
 
VOID * LOS_MemRealloc (VOID *pool, VOID *ptr, UINT32 size)
 按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块 更多...
 
UINT32 LOS_MemFreeByTaskID (VOID *pool, UINT32 taskID)
 
UINT32 LOS_MemPoolSizeGet (const VOID *pool)
 获取指定动态内存池的总大小 更多...
 
UINT32 LOS_MemTotalUsedGet (VOID *pool)
 获取指定动态内存池的总使用量大小 更多...
 
STATIC INLINE VOID OsMemMagicCheckPrint (struct OsMemNodeHead **tmpNode)
 
STATIC UINT32 OsMemAddrValidCheckPrint (const VOID *pool, struct OsMemFreeNodeHead **tmpNode)
 
STATIC UINT32 OsMemIntegrityCheckSub (struct OsMemNodeHead **tmpNode, const VOID *pool, const struct OsMemNodeHead *endNode)
 
STATIC UINT32 OsMemFreeListNodeCheck (const struct OsMemPoolHead *pool, const struct OsMemFreeNodeHead *node)
 
STATIC VOID OsMemPoolHeadCheck (const struct OsMemPoolHead *pool)
 
STATIC UINT32 OsMemIntegrityCheck (const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, struct OsMemNodeHead **preNode)
 
STATIC VOID OsMemNodeInfo (const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode)
 
STATIC VOID OsMemIntegrityCheckError (struct OsMemPoolHead *pool, const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode, UINT32 intSave)
 
UINT32 LOS_MemIntegrityCheck (const VOID *pool)
 对指定内存池做完整性检查 更多...
 
STATIC INLINE VOID OsMemInfoGet (struct OsMemPoolHead *poolInfo, struct OsMemNodeHead *node, LOS_MEM_POOL_STATUS *poolStatus)
 
UINT32 LOS_MemInfoGet (VOID *pool, LOS_MEM_POOL_STATUS *poolStatus)
 LOS_MemInfoGet
获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小 更多...
 
UINT32 LOS_MemFreeNodeShow (VOID *pool)
 打印指定内存池的空闲内存块的大小及数量 更多...
 
STATUS_T OsKHeapInit (size_t size)
 内核空间动态内存(堆内存)初始化 , 争取系统动态内存池 更多...
 
BOOL OsMemIsHeapNode (const VOID *ptr)
 

变量

UINT8m_aucSysMem0 = NULL
 异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。 更多...
 
UINT8m_aucSysMem1 = NULL
 系统动态内存池地址的起始地址 @note_thinking 能否不要用 0,1来命名核心变量 ??? 更多...
 
VOID * g_poolHead = NULL
 

详细描述

http://www.gii.upv.es/tlsf/files/ecrts04_tlsf.pdf

https://www.codenong.com/cs106845116/ TLSF算法(一)分配中的位图计算
基本概念
    内存管理模块管理系统的内存资源,它是操作系统的核心模块之一,主要包括内存的初始化、分配以及释放。
    OpenHarmony LiteOS-A的堆内存管理提供内存初始化、分配、释放等功能。在系统运行过程中,堆内存管理
    模块通过对内存的申请/释放来管理用户和OS对内存的使用,使内存的利用率和使用效率达到最优,同时最大限度地解决系统的内存碎片问题。

运行机制
    堆内存管理,即在内存资源充足的情况下,根据用户需求,从系统配置的一块比较大的连续内存
    (内存池,也是堆内存)中分配任意大小的内存块。当用户不需要该内存块时,又可以释放回系统供下一次使用。
    与静态内存相比,动态内存管理的优点是按需分配,缺点是内存池中容易出现碎片。
    OpenHarmony LiteOS-A堆内存在TLSF算法的基础上,对区间的划分进行了优化,获得更优的性能,降低了碎片率。
    动态内存核心算法框图如下:
 根据空闲内存块的大小,使用多个空闲链表来管理。根据内存空闲块大小分为两个部分:[4, 127]和[27, 231],如上图size class所示:

 1. 对[4,127]区间的内存进行等分,如上图下半部分所示,分为31个小区间,每个小区间对应内存块大小为4字节的倍数。
    每个小区间对应一个空闲内存链表和用于标记对应空闲内存链表是否为空的一个比特位,值为1时,空闲链表非空。
    [4,127]区间的31个小区间内存对应31个比特位进行标记链表是否为空。
 2. 大于127字节的空闲内存块,按照2的次幂区间大小进行空闲链表管理。总共分为24个小区间,每个小区间又等分为8个二级小区间,
    见上图上半部分的Size Class和Size SubClass部分。每个二级小区间对应一个空闲链表和用于标记对应空闲内存链表是否为空的一个比特位。
    总共24*8=192个二级小区间,对应192个空闲链表和192个比特位进行标记链表是否为空。
 例如,当有40字节的空闲内存需要插入空闲链表时,对应小区间[40,43],第10个空闲链表,位图标记的第10比特位。
 把40字节的空闲内存挂载第10个空闲链表上,并判断是否需要更新位图标记。当需要申请40字节的内存时,
 根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,
 进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。当有580字节的空闲内存需要插入空闲链表时,对应二级小区间[29,29+2^6],
 第31+2*8=47个空闲链表,并使用位图的第47个比特位来标记链表是否为空。把580字节的空闲内存挂载第47个空闲链表上,并判断是否需要更新位图标记。
 当需要申请580字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。
 如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。如果对应的空闲链表为空,
 则向更大的内存区间去查询是否有满足条件的空闲链表,实际计算时,会一次性查找到满足申请大小的空闲链表。
 
 内存信息包括内存池大小、内存使用量、剩余内存大小、最大空闲内存、内存水线、内存节点数统计、碎片率等。
 内存水线:即内存池的最大使用量,每次申请和释放时,都会更新水线值,实际业务可根据该值,优化内存池大小;
 碎片率:衡量内存池的碎片化程度,碎片率高表现为内存池剩余内存很多,但是最大空闲内存块很小,可以用公式(fragment=100-最大空闲内存块大小/剩余内存大小)来度量;

 内存管理结构如下图所示:
版本
作者
weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
日期
2021-11-19

在文件 los_memory.c 中定义.

函数说明

◆ LOS_MemFreeByTaskID()

UINT32 LOS_MemFreeByTaskID ( VOID *  pool,
UINT32  taskID 
)

在文件 los_memory.c1554 行定义.

1555{
1556 if (pool == NULL) {
1557 return OS_ERROR;
1558 }
1559
1560 if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
1561 return OS_ERROR;
1562 }
1563
1564 struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool;
1565 struct OsMemNodeHead *tmpNode = NULL;
1566 struct OsMemUsedNodeHead *node = NULL;
1567 struct OsMemNodeHead *endNode = NULL;
1568 UINT32 size;
1569 UINT32 intSave;
1570
1571 MEM_LOCK(poolHead, intSave);
1572 endNode = OS_MEM_END_NODE(pool, poolHead->info.totalSize);
1573 for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode;) {
1574 if (tmpNode == endNode) {
1575 if (OsMemIsLastSentinelNode(endNode) == FALSE) {
1576 size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag);
1577 tmpNode = OsMemSentinelNodeGet(endNode);
1578 endNode = OS_MEM_END_NODE(tmpNode, size);
1579 continue;
1580 } else {
1581 break;
1582 }
1583 } else {
1584 if (!OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) {
1585 tmpNode = OS_MEM_NEXT_NODE(tmpNode);
1586 continue;
1587 }
1588
1589 node = (struct OsMemUsedNodeHead *)tmpNode;
1590 tmpNode = OS_MEM_NEXT_NODE(tmpNode);
1591
1592 if (node->taskID == taskID) {
1593 OsMemFree(poolHead, &node->header);
1594 }
1595 }
1596 }
1597 MEM_UNLOCK(poolHead, intSave);
1598
1599 return LOS_OK;
1600}
STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node)
释放内存
Definition: los_memory.c:1314
STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode)
是否为最后一个哨兵节点
Definition: los_memory.c:327
STATIC INLINE VOID * OsMemSentinelNodeGet(struct OsMemNodeHead *node)
Definition: los_memory.c:354
unsigned int UINT32
Definition: los_typedef.h:57
内存池节点
Definition: los_memory.c:169
UINT32 sizeAndFlag
节点总大小+标签
Definition: los_memory.c:178
内存池头信息
Definition: los_memory.c:204
struct OsMemPoolInfo info
记录内存池的信息
Definition: los_memory.c:205
UINT32 totalSize
总大小,确定了内存池的边界
Definition: los_memory.c:196
已使用内存池节点
Definition: los_memory.c:181
struct OsMemNodeHead header
已被使用节点
Definition: los_memory.c:182
UINT32 taskID
使用节点的任务ID
Definition: los_memory.c:184
函数调用图:

◆ MemCheckUsedNode()

STATIC BOOL MemCheckUsedNode ( const struct OsMemPoolHead pool,
const struct OsMemNodeHead node,
const struct OsMemNodeHead startNode,
const struct OsMemNodeHead endNode 
)

在文件 los_memory.c1260 行定义.

1262{
1263 if (!OsMemIsNodeValid(node, startNode, endNode, pool)) {
1264 return FALSE;
1265 }
1266
1267 if (!OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) {
1268 return FALSE;
1269 }
1270
1271 const struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node);
1272 if (!OsMemIsNodeValid(nextNode, startNode, endNode, pool)) {
1273 return FALSE;
1274 }
1275
1276 if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {
1277 if (nextNode->ptr.prev != node) {
1278 return FALSE;
1279 }
1280 }
1281
1282 if ((node != startNode) &&
1283 ((!OsMemIsNodeValid(node->ptr.prev, startNode, endNode, pool)) ||
1284 (OS_MEM_NEXT_NODE(node->ptr.prev) != node))) {
1285 return FALSE;
1286 }
1287
1288 return TRUE;
1289}
STATIC INLINE BOOL OsMemIsNodeValid(const struct OsMemNodeHead *node, const struct OsMemNodeHead *startNode, const struct OsMemNodeHead *endNode, const struct OsMemPoolHead *poolInfo)
Definition: los_memory.c:1238
struct OsMemNodeHead * prev
Definition: los_memory.c:172
union OsMemNodeHead::@5 ptr
函数调用图:
这是这个函数的调用关系图:

◆ OsGetRealPtr()

STATIC INLINE VOID * OsGetRealPtr ( const VOID *  pool,
VOID *  ptr 
)

在文件 los_memory.c1456 行定义.

1457{
1458 VOID *realPtr = ptr;
1459 UINT32 gapSize = *((UINT32 *)((UINTPTR)ptr - sizeof(UINT32)));
1460
1461 if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) {
1462 PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize);
1463 return NULL;
1464 }
1465 if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) {
1466 gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize);
1467 if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) ||
1468 (gapSize > ((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE - (UINTPTR)pool))) {
1469 PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize);
1470 return NULL;
1471 }
1472 realPtr = (VOID *)((UINTPTR)ptr - (UINTPTR)gapSize);
1473 }
1474 return realPtr;
1475}
unsigned long UINTPTR
Definition: los_typedef.h:68
这是这个函数的调用关系图:

◆ OsKHeapInit()

STATUS_T OsKHeapInit ( size_t  size)

内核空间动态内存(堆内存)初始化 , 争取系统动态内存池

判断地址是否在堆区

在文件 los_memory.c2095 行定义.

函数调用图:
这是这个函数的调用关系图:

◆ OsLmsAllocAlignMark()

STATIC INLINE VOID OsLmsAllocAlignMark ( VOID *  ptr,
VOID *  alignedPtr,
UINT32  size 
)

在文件 los_memory.c525 行定义.

526{
527 struct OsMemNodeHead *allocNode = NULL;
528
529 if ((g_lms == NULL) || (ptr == NULL)) {
530 return;
531 }
532 allocNode = (struct OsMemNodeHead *)((struct OsMemUsedNodeHead *)ptr - 1);
533 if (ptr != alignedPtr) {
534 g_lms->simpleMark((UINTPTR)ptr, (UINTPTR)ptr + sizeof(UINT32), LMS_SHADOW_PAINT_U8);
535 g_lms->simpleMark((UINTPTR)ptr + sizeof(UINT32), (UINTPTR)alignedPtr, LMS_SHADOW_REDZONE_U8);
536 }
537
538 /* mark remining as redzone */
539 g_lms->simpleMark(LMS_ADDR_ALIGN((UINTPTR)alignedPtr + size), (UINTPTR)OS_MEM_NEXT_NODE(allocNode),
540 LMS_SHADOW_REDZONE_U8);
541}
LmsHook * g_lms
Definition: los_lms.c:68
VOID(* simpleMark)(UINTPTR startAddr, UINTPTR endAddr, UINT32 value)
Definition: los_lms_pri.h:100
这是这个函数的调用关系图:

◆ OsLmsFirstNodeMark()

STATIC INLINE VOID OsLmsFirstNodeMark ( VOID *  pool,
struct OsMemNodeHead node 
)

在文件 los_memory.c511 行定义.

512{
513 if (g_lms == NULL) {
514 return;
515 }
516
517 g_lms->simpleMark((UINTPTR)pool, (UINTPTR)node, LMS_SHADOW_PAINT_U8);
518 g_lms->simpleMark((UINTPTR)node, (UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, LMS_SHADOW_REDZONE_U8);
519 g_lms->simpleMark((UINTPTR)OS_MEM_NEXT_NODE(node), (UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE,
520 LMS_SHADOW_REDZONE_U8);
521 g_lms->simpleMark((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, (UINTPTR)OS_MEM_NEXT_NODE(node),
522 LMS_SHADOW_AFTERFREE_U8);
523}
这是这个函数的调用关系图:

◆ OsLmsReallocMergeNodeMark()

STATIC INLINE VOID OsLmsReallocMergeNodeMark ( struct OsMemNodeHead node)

在文件 los_memory.c543 行定义.

544{
545 if (g_lms == NULL) {
546 return;
547 }
548
549 g_lms->simpleMark((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, (UINTPTR)OS_MEM_NEXT_NODE(node),
550 LMS_SHADOW_ACCESSABLE_U8);
551}
这是这个函数的调用关系图:

◆ OsLmsReallocResizeMark()

STATIC INLINE VOID OsLmsReallocResizeMark ( struct OsMemNodeHead node,
UINT32  resize 
)

在文件 los_memory.c565 行定义.

566{
567 if (g_lms == NULL) {
568 return;
569 }
570 /* mark remaining as redzone */
571 g_lms->simpleMark((UINTPTR)node + resize, (UINTPTR)OS_MEM_NEXT_NODE(node), LMS_SHADOW_REDZONE_U8);
572}
这是这个函数的调用关系图:

◆ OsLmsReallocSplitNodeMark()

STATIC INLINE VOID OsLmsReallocSplitNodeMark ( struct OsMemNodeHead node)

在文件 los_memory.c553 行定义.

554{
555 if (g_lms == NULL) {
556 return;
557 }
558 /* mark next node */
559 g_lms->simpleMark((UINTPTR)OS_MEM_NEXT_NODE(node),
560 (UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE, LMS_SHADOW_REDZONE_U8);
561 g_lms->simpleMark((UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE,
562 (UINTPTR)OS_MEM_NEXT_NODE(OS_MEM_NEXT_NODE(node)), LMS_SHADOW_AFTERFREE_U8);
563}
这是这个函数的调用关系图:

◆ OsMemAddrValidCheck()

STATIC INLINE BOOL OsMemAddrValidCheck ( const struct OsMemPoolHead pool,
const VOID *  addr 
)

内存池有效性检查

在文件 los_memory.c1210 行定义.

1211{
1212 UINT32 size;
1213
1214 /* First node prev is NULL */
1215 if (addr == NULL) {
1216 return TRUE;
1217 }
1218
1219 size = pool->info.totalSize;
1220 if (OS_MEM_MIDDLE_ADDR_OPEN_END(pool + 1, addr, (UINTPTR)pool + size)) {
1221 return TRUE;
1222 }
1223#if OS_MEM_EXPAND_ENABLE //如果支持可扩展
1224 struct OsMemNodeHead *node = NULL;
1225 struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, size);
1226 while (OsMemIsLastSentinelNode(sentinel) == FALSE) {
1227 size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag);
1228 node = OsMemSentinelNodeGet(sentinel);
1229 sentinel = OS_MEM_END_NODE(node, size);
1230 if (OS_MEM_MIDDLE_ADDR_OPEN_END(node, addr, (UINTPTR)node + size)) {
1231 return TRUE;
1232 }
1233 }
1234#endif
1235 return FALSE;
1236}
函数调用图:
这是这个函数的调用关系图:

◆ OsMemAddrValidCheckPrint()

STATIC UINT32 OsMemAddrValidCheckPrint ( const VOID *  pool,
struct OsMemFreeNodeHead **  tmpNode 
)

在文件 los_memory.c1682 行定义.

1683{
1684 if (((*tmpNode)->prev != NULL) && !OsMemAddrValidCheck(pool, (*tmpNode)->prev)) {
1685 PRINT_ERR("[%s], %d, memory check error!\n"
1686 " freeNode.prev:%#x is out of legal mem range\n",
1687 __FUNCTION__, __LINE__, (*tmpNode)->prev);
1688 return LOS_NOK;
1689 }
1690 if (((*tmpNode)->next != NULL) && !OsMemAddrValidCheck(pool, (*tmpNode)->next)) {
1691 PRINT_ERR("[%s], %d, memory check error!\n"
1692 " freeNode.next:%#x is out of legal mem range\n",
1693 __FUNCTION__, __LINE__, (*tmpNode)->next);
1694 return LOS_NOK;
1695 }
1696 return LOS_OK;
1697}
STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const VOID *addr)
内存池有效性检查
Definition: los_memory.c:1210
函数调用图:
这是这个函数的调用关系图:

◆ OsMemAlloc()

STATIC INLINE VOID * OsMemAlloc ( struct OsMemPoolHead pool,
UINT32  size,
UINT32  intSave 
)

从指定动态内存池中申请size长度的内存

在文件 los_memory.c1075 行定义.

1076{
1077 struct OsMemNodeHead *allocNode = NULL;
1078
1079#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK
1080 if (OsMemAllocCheck(pool, intSave) == LOS_NOK) {
1081 return NULL;
1082 }
1083#endif
1084
1085 UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE);
1086#if OS_MEM_EXPAND_ENABLE
1087retry: //这种写法也挺赞的 @note_good
1088#endif
1089 allocNode = OsMemFreeNodeGet(pool, allocSize);//获取空闲节点
1090 if (allocNode == NULL) {//没有内存了,怎搞?
1091#if OS_MEM_EXPAND_ENABLE
1092 if (pool->info.attr & OS_MEM_POOL_EXPAND_ENABLE) {
1093 INT32 ret = OsMemPoolExpand(pool, allocSize, intSave);//扩展内存池
1094 if (ret == 0) {
1095 goto retry;//再来一遍
1096 }
1097 }
1098#endif
1099 MEM_UNLOCK(pool, intSave);
1100 PRINT_ERR("---------------------------------------------------"
1101 "--------------------------------------------------------\n");
1102 OsMemInfoPrint(pool);
1103 PRINT_ERR("[%s] No suitable free block, require free node size: 0x%x\n", __FUNCTION__, allocSize);
1104 PRINT_ERR("----------------------------------------------------"
1105 "-------------------------------------------------------\n");
1106 MEM_LOCK(pool, intSave);
1107 return NULL;
1108 }
1109
1110 if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) {//所需小于内存池可供分配量
1111 OsMemSplitNode(pool, allocNode, allocSize);//劈开内存池
1112 }
1113
1114 OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag);//给节点贴上已使用的标签
1115 OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag));//更新吃水线
1116
1117#ifdef LOSCFG_MEM_LEAKCHECK //检测内存泄漏开关
1118 OsMemLinkRegisterRecord(allocNode);
1119#endif
1120 return OsMemCreateUsedNode((VOID *)allocNode);//创建已使用节点
1121}
STATIC INLINE VOID OsMemLinkRegisterRecord(struct OsMemNodeHead *node)
Definition: los_memory.c:575
STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size)
Definition: los_memory.c:282
STATIC INLINE VOID OsMemSplitNode(VOID *pool, struct OsMemNodeHead *allocNode, UINT32 allocSize)
切割节点
Definition: los_memory.c:845
STATIC INLINE struct OsMemNodeHead * OsMemFreeNodeGet(VOID *pool, UINT32 size)
Definition: los_memory.c:820
STATIC INLINE VOID * OsMemCreateUsedNode(VOID *addr)
Definition: los_memory.c:866
STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave)
扩展内存池
Definition: los_memory.c:478
STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave)
Definition: los_memory.c:1890
STATIC VOID OsMemInfoPrint(VOID *pool)
Definition: los_memory.c:2018
signed int INT32
Definition: los_typedef.h:60
UINT32 attr
属性 default attr: lock, not expand.
Definition: los_memory.c:197
函数调用图:
这是这个函数的调用关系图:

◆ OsMemAllocCheck()

STATIC INLINE UINT32 OsMemAllocCheck ( struct OsMemPoolHead pool,
UINT32  intSave 
)

在文件 los_memory.c1890 行定义.

1891{
1892 struct OsMemNodeHead *tmpNode = NULL;
1893 struct OsMemNodeHead *preNode = NULL;
1894
1895 if (OsMemIntegrityCheck(pool, &tmpNode, &preNode)) {
1896 OsMemIntegrityCheckError(pool, tmpNode, preNode, intSave);
1897 return LOS_NOK;
1898 }
1899 return LOS_OK;
1900}
STATIC UINT32 OsMemIntegrityCheck(const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, struct OsMemNodeHead **preNode)
Definition: los_memory.c:1778
STATIC VOID OsMemIntegrityCheckError(struct OsMemPoolHead *pool, const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode, UINT32 intSave)
Definition: los_memory.c:1853
函数调用图:
这是这个函数的调用关系图:

◆ OsMemCheckUsedNode()

STATIC UINT32 OsMemCheckUsedNode ( const struct OsMemPoolHead pool,
const struct OsMemNodeHead node 
)

在文件 los_memory.c1291 行定义.

1292{
1293 struct OsMemNodeHead *startNode = (struct OsMemNodeHead *)OS_MEM_FIRST_NODE(pool);
1294 struct OsMemNodeHead *endNode = (struct OsMemNodeHead *)OS_MEM_END_NODE(pool, pool->info.totalSize);
1295 BOOL doneFlag = FALSE;
1296
1297 do {
1298 doneFlag = MemCheckUsedNode(pool, node, startNode, endNode);
1299 if (!doneFlag) {
1300#if OS_MEM_EXPAND_ENABLE
1301 if (OsMemIsLastSentinelNode(endNode) == FALSE) {
1302 startNode = OsMemSentinelNodeGet(endNode);
1303 endNode = OS_MEM_END_NODE(startNode, OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag));
1304 continue;
1305 }
1306#endif
1307 return LOS_NOK;
1308 }
1309 } while (!doneFlag);
1310
1311 return LOS_OK;
1312}
STATIC BOOL MemCheckUsedNode(const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node, const struct OsMemNodeHead *startNode, const struct OsMemNodeHead *endNode)
Definition: los_memory.c:1260
size_t BOOL
Definition: los_typedef.h:88
函数调用图:
这是这个函数的调用关系图:

◆ OsMemClearFreeListBit()

STATIC INLINE VOID OsMemClearFreeListBit ( struct OsMemPoolHead head,
UINT32  index 
)

在文件 los_memory.c764 行定义.

765{
766 head->freeListBitmap[BITMAP_INDEX(index)] &= ~(1U << (index & 0x1f));
767}
UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]
空闲位图 int[7] = 32 * 7 = 224 > 223
Definition: los_memory.c:206
这是这个函数的调用关系图:

◆ OsMemCreateUsedNode()

STATIC INLINE VOID * OsMemCreateUsedNode ( VOID *  addr)

在文件 los_memory.c866 行定义.

867{
868 struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr;//直接将地址转成使用节点,说明节点信息也存在内存池中
869 //这种用法是非常巧妙的
870#if OS_MEM_FREE_BY_TASKID
871 OsMemNodeSetTaskID(node);//设置使用内存节点的任务
872#endif
873
874#ifdef LOSCFG_KERNEL_LMS //检测内存泄漏
875 struct OsMemNodeHead *newNode = (struct OsMemNodeHead *)node;
876 if (g_lms != NULL) {
877 g_lms->mallocMark(newNode, OS_MEM_NEXT_NODE(newNode), OS_MEM_NODE_HEAD_SIZE);
878 }
879#endif
880 return node + 1; //@note_good 这个地方挺有意思的,只是将结构体扩展下,留一个 int 位 ,变成了已使用节点,返回的地址正是要分配给应用的地址
881}
STATIC INLINE VOID OsMemNodeSetTaskID(struct OsMemUsedNodeHead *node)
Definition: los_memory.c:275
VOID(* mallocMark)(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize)
Definition: los_lms_pri.h:98
函数调用图:
这是这个函数的调用关系图:

◆ OsMemFFS()

STATIC INLINE UINT16 OsMemFFS ( UINT32  bitmap)

在文件 los_memory.c135 行定义.

136{
137 bitmap &= ~bitmap + 1;
138 return (OS_MEM_BITMAP_MASK - CLZ(bitmap));
139}
这是这个函数的调用关系图:

◆ OsMemFindCurSuitableBlock()

STATIC INLINE struct OsMemFreeNodeHead * OsMemFindCurSuitableBlock ( struct OsMemPoolHead poolHead,
UINT32  index,
UINT32  size 
)

在文件 los_memory.c686 行定义.

688{
689 struct OsMemFreeNodeHead *node = NULL;
690
691 for (node = poolHead->freeList[index]; node != NULL; node = node->next) {
692 if (node->header.sizeAndFlag >= size) {
693 return node;
694 }
695 }
696
697 return NULL;
698}
内存池空闲节点
Definition: los_memory.c:188
struct OsMemFreeNodeHead * next
后一个空闲后继节点
Definition: los_memory.c:191
struct OsMemNodeHead header
内存池节点
Definition: los_memory.c:189
struct OsMemFreeNodeHead * freeList[OS_MEM_FREE_LIST_COUNT]
空闲节点链表 32 + 24 * 8 = 224
Definition: los_memory.c:207
这是这个函数的调用关系图:

◆ OsMemFindNextSuitableBlock()

STATIC INLINE struct OsMemFreeNodeHead * OsMemFindNextSuitableBlock ( VOID *  pool,
UINT32  size,
UINT32 outIndex 
)

找到下一个合适的块

在文件 los_memory.c715 行定义.

716{
717 struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool;
718 UINT32 fl = OsMemFlGet(size);
719 UINT32 sl;
720 UINT32 index, tmp;
721 UINT32 curIndex = OS_MEM_FREE_LIST_COUNT;
722 UINT32 mask;
723
724 do {
725 if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) {
726 index = fl;
727 } else {
728 sl = OsMemSlGet(size, fl);
729 curIndex = ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl + OS_MEM_SMALL_BUCKET_COUNT;
730 index = curIndex + 1;
731 }
732
733 tmp = OsMemNotEmptyIndexGet(poolHead, index);
734 if (tmp != OS_MEM_FREE_LIST_COUNT) {
735 index = tmp;
736 goto DONE;
737 }
738
739 for (index = LOS_Align(index + 1, 32); index < OS_MEM_FREE_LIST_COUNT; index += 32) { /* 32: align size */
740 mask = poolHead->freeListBitmap[BITMAP_INDEX(index)];
741 if (mask != 0) {
742 index = OsMemFFS(mask) + index;
743 goto DONE;
744 }
745 }
746 } while (0);
747
748 if (curIndex == OS_MEM_FREE_LIST_COUNT) {
749 return NULL;
750 }
751
752 *outIndex = curIndex;
753 return OsMemFindCurSuitableBlock(poolHead, curIndex, size);
754DONE:
755 *outIndex = index;
756 return poolHead->freeList[index];
757}
LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
Align the value (addr) by some bytes (boundary) you specify.
Definition: los_misc.c:35
STATIC INLINE struct OsMemFreeNodeHead * OsMemFindCurSuitableBlock(struct OsMemPoolHead *poolHead, UINT32 index, UINT32 size)
Definition: los_memory.c:686
STATIC INLINE UINT32 OsMemFlGet(UINT32 size)
Definition: los_memory.c:153
STATIC INLINE UINT16 OsMemFFS(UINT32 bitmap)
Definition: los_memory.c:135
STATIC INLINE UINT32 OsMemNotEmptyIndexGet(struct OsMemPoolHead *poolHead, UINT32 index)
Definition: los_memory.c:701
STATIC INLINE UINT32 OsMemSlGet(UINT32 size, UINT32 fl)
Definition: los_memory.c:162
函数调用图:
这是这个函数的调用关系图:

◆ OsMemFlGet()

STATIC INLINE UINT32 OsMemFlGet ( UINT32  size)

在文件 los_memory.c153 行定义.

154{
155 if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) {
156 return ((size >> 2) - 1); /* 2: The small bucket setup is 4. */
157 }
158 return OsMemLog2(size);
159}
STATIC INLINE UINT32 OsMemLog2(UINT32 size)
Definition: los_memory.c:147
函数调用图:
这是这个函数的调用关系图:

◆ OsMemFLS()

STATIC INLINE UINT16 OsMemFLS ( UINT32  bitmap)

在文件 los_memory.c142 行定义.

143{
144 return (OS_MEM_BITMAP_MASK - CLZ(bitmap));
145}
这是这个函数的调用关系图:

◆ OsMemFree()

STATIC INLINE UINT32 OsMemFree ( struct OsMemPoolHead pool,
struct OsMemNodeHead node 
)

释放内存

在文件 los_memory.c1314 行定义.

1315{
1316 UINT32 ret = OsMemCheckUsedNode(pool, node);
1317 if (ret != LOS_OK) {
1318 PRINT_ERR("OsMemFree check error!\n");
1319 return ret;
1320 }
1321
1322#ifdef LOSCFG_MEM_WATERLINE
1323 pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//降低水位线
1324#endif
1325
1326 node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);//获取大小和标记
1327#ifdef LOSCFG_MEM_LEAKCHECK
1329#endif
1330#ifdef LOSCFG_KERNEL_LMS
1331 struct OsMemNodeHead *nextNodeBackup = OS_MEM_NEXT_NODE(node);
1332 struct OsMemNodeHead *curNodeBackup = node;
1333 if (g_lms != NULL) {
1334 g_lms->check((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, TRUE);
1335 }
1336#endif
1337 struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode | 合并前一个节点*/
1338 if ((preNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) {
1339 OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode);//删除前节点的信息
1340 OsMemMergeNode(node);//向前合并
1341 node = preNode;
1342 }
1343
1344 struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node); /* merage nextNode | 计算后一个节点位置*/
1345 if ((nextNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) {
1346 OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除后节点信息
1347 OsMemMergeNode(nextNode);//合并节点
1348 }
1349
1350#if OS_MEM_EXPAND_ENABLE
1351 if (pool->info.attr & OS_MEM_POOL_EXPAND_ENABLE) {
1352 /* if this is a expand head node, and all unused, free it to pmm */
1353 if ((node->ptr.prev != NULL) && (node->ptr.prev > node)) {
1354 if (TryShrinkPool(pool, node)) {
1355 return LOS_OK;
1356 }
1357 }
1358 }
1359#endif
1360 OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)node);
1361#ifdef LOSCFG_KERNEL_LMS
1362 if (g_lms != NULL) {
1363 g_lms->freeMark(curNodeBackup, nextNodeBackup, OS_MEM_NODE_HEAD_SIZE);
1364 }
1365#endif
1366 return ret;
1367}
STATIC INLINE VOID OsMemMergeNode(struct OsMemNodeHead *node)
合并节点,和前面的节点合并 node 消失
Definition: los_memory.c:834
STATIC UINT32 OsMemCheckUsedNode(const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node)
Definition: los_memory.c:1291
STATIC INLINE BOOL TryShrinkPool(const VOID *pool, const struct OsMemNodeHead *node)
Definition: los_memory.c:393
STATIC INLINE VOID OsMemFreeNodeDelete(VOID *pool, struct OsMemFreeNodeHead *node)
从空闲链表上摘除节点
Definition: los_memory.c:810
STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node)
添加一个空闲节点
Definition: los_memory.c:800
VOID(* check)(UINTPTR checkAddr, BOOL isFreeCheck)
Definition: los_lms_pri.h:101
VOID(* freeMark)(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize)
Definition: los_lms_pri.h:99
UINT32 curUsedSize
Definition: los_memory.c:200
函数调用图:
这是这个函数的调用关系图:

◆ OsMemFreeListIndexGet()

STATIC INLINE UINT32 OsMemFreeListIndexGet ( UINT32  size)

在文件 los_memory.c675 行定义.

676{
677 UINT32 fl = OsMemFlGet(size);//获取一级位图
678 if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) {
679 return fl;
680 }
681
682 UINT32 sl = OsMemSlGet(size, fl);//获取二级位图
683 return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl);
684}
函数调用图:
这是这个函数的调用关系图:

◆ OsMemFreeListNodeCheck()

STATIC UINT32 OsMemFreeListNodeCheck ( const struct OsMemPoolHead pool,
const struct OsMemFreeNodeHead node 
)

在文件 los_memory.c1715 行定义.

1717{
1718 if (!OsMemAddrValidCheck(pool, node) ||
1719 !OsMemAddrValidCheck(pool, node->prev) ||
1720 !OsMemAddrValidCheck(pool, node->next) ||
1721 !OsMemAddrValidCheck(pool, node->header.ptr.prev)) {
1722 return LOS_NOK;
1723 }
1724
1725 if (!OS_MEM_IS_ALIGNED(node, sizeof(VOID *)) ||
1726 !OS_MEM_IS_ALIGNED(node->prev, sizeof(VOID *)) ||
1727 !OS_MEM_IS_ALIGNED(node->next, sizeof(VOID *)) ||
1728 !OS_MEM_IS_ALIGNED(node->header.ptr.prev, sizeof(VOID *))) {
1729 return LOS_NOK;
1730 }
1731
1732 return LOS_OK;
1733}
struct OsMemFreeNodeHead * prev
前一个空闲前驱节点
Definition: los_memory.c:190
函数调用图:
这是这个函数的调用关系图:

◆ OsMemFreeNodeAdd()

STATIC INLINE VOID OsMemFreeNodeAdd ( VOID *  pool,
struct OsMemFreeNodeHead node 
)

添加一个空闲节点

在文件 los_memory.c800 行定义.

801{
802 UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位
803 if (index >= OS_MEM_FREE_LIST_COUNT) {
804 LOS_Panic("The index of free lists is error, index = %u\n", index);
805 return;
806 }
807 OsMemListAdd(pool, index, node);//挂入链表
808}
NORETURN VOID LOS_Panic(const CHAR *fmt,...)
Kernel panic function.
STATIC INLINE UINT32 OsMemFreeListIndexGet(UINT32 size)
Definition: los_memory.c:675
STATIC INLINE VOID OsMemListAdd(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node)
Definition: los_memory.c:769
函数调用图:
这是这个函数的调用关系图:

◆ OsMemFreeNodeDelete()

STATIC INLINE VOID OsMemFreeNodeDelete ( VOID *  pool,
struct OsMemFreeNodeHead node 
)

从空闲链表上摘除节点

在文件 los_memory.c810 行定义.

811{
812 UINT32 index = OsMemFreeListIndexGet(node->header.sizeAndFlag);//根据大小定位索引位
813 if (index >= OS_MEM_FREE_LIST_COUNT) {
814 LOS_Panic("The index of free lists is error, index = %u\n", index);
815 return;
816 }
817 OsMemListDelete(pool, index, node);
818}
STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node)
从空闲链表中删除
Definition: los_memory.c:782
函数调用图:
这是这个函数的调用关系图:

◆ OsMemFreeNodeGet()

STATIC INLINE struct OsMemNodeHead * OsMemFreeNodeGet ( VOID *  pool,
UINT32  size 
)

在文件 los_memory.c820 行定义.

821{
822 struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool;
823 UINT32 index;
824 struct OsMemFreeNodeHead *firstNode = OsMemFindNextSuitableBlock(pool, size, &index);
825 if (firstNode == NULL) {
826 return NULL;
827 }
828
829 OsMemListDelete(poolHead, index, firstNode);
830
831 return &firstNode->header;
832}
STATIC INLINE struct OsMemFreeNodeHead * OsMemFindNextSuitableBlock(VOID *pool, UINT32 size, UINT32 *outIndex)
找到下一个合适的块
Definition: los_memory.c:715
函数调用图:
这是这个函数的调用关系图:

◆ OsMemInfoGet()

STATIC INLINE VOID OsMemInfoGet ( struct OsMemPoolHead poolInfo,
struct OsMemNodeHead node,
LOS_MEM_POOL_STATUS poolStatus 
)

在文件 los_memory.c1926 行定义.

1928{
1929 UINT32 totalUsedSize = 0;
1930 UINT32 totalFreeSize = 0;
1931 UINT32 usedNodeNum = 0;
1932 UINT32 freeNodeNum = 0;
1933 UINT32 maxFreeSize = 0;
1934 UINT32 size;
1935
1936 if (!OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) {
1937 size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);
1938 ++freeNodeNum;
1939 totalFreeSize += size;
1940 if (maxFreeSize < size) {
1941 maxFreeSize = size;
1942 }
1943 } else {
1944 size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);
1945 ++usedNodeNum;
1946 totalUsedSize += size;
1947 }
1948
1949 poolStatus->totalUsedSize += totalUsedSize;
1950 poolStatus->totalFreeSize += totalFreeSize;
1951 poolStatus->maxFreeNodeSize = MAX(poolStatus->maxFreeNodeSize, maxFreeSize);
1952 poolStatus->usedNodeNum += usedNodeNum;
1953 poolStatus->freeNodeNum += freeNodeNum;
1954}
这是这个函数的调用关系图:

◆ OsMemInfoPrint()

STATIC VOID OsMemInfoPrint ( VOID *  pool)

在文件 los_memory.c2018 行定义.

2019{
2020 struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool;
2021 LOS_MEM_POOL_STATUS status = {0};
2022
2023 if (LOS_MemInfoGet(pool, &status) == LOS_NOK) {
2024 return;
2025 }
2026
2027#ifdef LOSCFG_MEM_WATERLINE
2028 PRINTK("pool addr pool size used size free size "
2029 "max free node size used node num free node num UsageWaterLine\n");
2030 PRINTK("--------------- -------- ------- -------- "
2031 "-------------- ------------- ------------ ------------\n");
2032 PRINTK("%-16#x 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x 0x%-13x\n",
2033 poolInfo->info.pool, LOS_MemPoolSizeGet(pool), status.totalUsedSize,
2034 status.totalFreeSize, status.maxFreeNodeSize, status.usedNodeNum,
2035 status.freeNodeNum, status.usageWaterLine);
2036#else
2037 PRINTK("pool addr pool size used size free size "
2038 "max free node size used node num free node num\n");
2039 PRINTK("--------------- -------- ------- -------- "
2040 "-------------- ------------- ------------\n");
2041 PRINTK("%-16#x 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x\n",
2042 poolInfo->info.pool, LOS_MemPoolSizeGet(pool), status.totalUsedSize,
2043 status.totalFreeSize, status.maxFreeNodeSize, status.usedNodeNum,
2044 status.freeNodeNum);
2045#endif
2046}
UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus)
LOS_MemInfoGet 获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小
Definition: los_memory.c:1965
UINT32 LOS_MemPoolSizeGet(const VOID *pool)
获取指定动态内存池的总大小
Definition: los_memory.c:1603
VOID * pool
指向内存块基地址,仅做记录而已,真正的分配内存跟它没啥关系
Definition: los_memory.c:195
函数调用图:
这是这个函数的调用关系图:

◆ OsMemIntegrityCheck()

STATIC UINT32 OsMemIntegrityCheck ( const struct OsMemPoolHead pool,
struct OsMemNodeHead **  tmpNode,
struct OsMemNodeHead **  preNode 
)

在文件 los_memory.c1778 行定义.

1780{
1781 struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize);
1782
1783 OsMemPoolHeadCheck(pool);
1784
1785 *preNode = OS_MEM_FIRST_NODE(pool);
1786 do {
1787 for (*tmpNode = *preNode; *tmpNode < endNode; *tmpNode = OS_MEM_NEXT_NODE(*tmpNode)) {
1788 if (OsMemIntegrityCheckSub(tmpNode, pool, endNode) == LOS_NOK) {
1789 return LOS_NOK;
1790 }
1791 *preNode = *tmpNode;
1792 }
1793#if OS_MEM_EXPAND_ENABLE
1794 if (OsMemIsLastSentinelNode(*tmpNode) == FALSE) {
1795 *preNode = OsMemSentinelNodeGet(*tmpNode);
1796 endNode = OS_MEM_END_NODE(*preNode, OS_MEM_NODE_GET_SIZE((*tmpNode)->sizeAndFlag));
1797 } else
1798#endif
1799 {
1800 break;
1801 }
1802 } while (1);
1803 return LOS_OK;
1804}
STATIC VOID OsMemPoolHeadCheck(const struct OsMemPoolHead *pool)
Definition: los_memory.c:1735
STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID *pool, const struct OsMemNodeHead *endNode)
Definition: los_memory.c:1699
函数调用图:
这是这个函数的调用关系图:

◆ OsMemIntegrityCheckError()

STATIC VOID OsMemIntegrityCheckError ( struct OsMemPoolHead pool,
const struct OsMemNodeHead tmpNode,
const struct OsMemNodeHead preNode,
UINT32  intSave 
)

在文件 los_memory.c1853 行定义.

1857{
1858 OsMemNodeInfo(tmpNode, preNode);
1859
1860#if OS_MEM_FREE_BY_TASKID
1861 LosTaskCB *taskCB = NULL;
1862 if (OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) {
1863 struct OsMemUsedNodeHead *usedNode = (struct OsMemUsedNodeHead *)preNode;
1864 UINT32 taskID = usedNode->taskID;
1865 if (OS_TID_CHECK_INVALID(taskID)) {
1866 MEM_UNLOCK(pool, intSave);
1867 LOS_Panic("Task ID %u in pre node is invalid!\n", taskID);
1868 return;
1869 }
1870
1871 taskCB = OS_TCB_FROM_TID(taskID);
1872 if (OsTaskIsUnused(taskCB) || (taskCB->taskEntry == NULL)) {
1873 MEM_UNLOCK(pool, intSave);
1874 LOS_Panic("\r\nTask ID %u in pre node is not created!\n", taskID);
1875 return;
1876 }
1877 } else {
1878 PRINTK("The prev node is free\n");
1879 }
1880 MEM_UNLOCK(pool, intSave);
1881 LOS_Panic("cur node: %#x\npre node: %#x\npre node was allocated by task:%s\n",
1882 tmpNode, preNode, taskCB->taskName);
1883#else
1884 MEM_UNLOCK(pool, intSave);
1885 LOS_Panic("Memory integrity check error, cur node: %#x, pre node: %#x\n", tmpNode, preNode);
1886#endif
1887}
STATIC VOID OsMemNodeInfo(const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode)
Definition: los_memory.c:1806
STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
任务是否在使用
Definition: los_task_pri.h:255
TSK_ENTRY_FUNC taskEntry
CHAR taskName[OS_TCB_NAME_LEN]
函数调用图:
这是这个函数的调用关系图:

◆ OsMemIntegrityCheckSub()

STATIC UINT32 OsMemIntegrityCheckSub ( struct OsMemNodeHead **  tmpNode,
const VOID *  pool,
const struct OsMemNodeHead endNode 
)

在文件 los_memory.c1699 行定义.

1701{
1702 if (!OS_MEM_MAGIC_VALID(*tmpNode)) {
1703 OsMemMagicCheckPrint(tmpNode);
1704 return LOS_NOK;
1705 }
1706
1707 if (!OS_MEM_NODE_GET_USED_FLAG((*tmpNode)->sizeAndFlag)) { /* is free node, check free node range */
1708 if (OsMemAddrValidCheckPrint(pool, (struct OsMemFreeNodeHead **)tmpNode)) {
1709 return LOS_NOK;
1710 }
1711 }
1712 return LOS_OK;
1713}
STATIC UINT32 OsMemAddrValidCheckPrint(const VOID *pool, struct OsMemFreeNodeHead **tmpNode)
Definition: los_memory.c:1682
STATIC INLINE VOID OsMemMagicCheckPrint(struct OsMemNodeHead **tmpNode)
Definition: los_memory.c:1675
函数调用图:
这是这个函数的调用关系图:

◆ OsMemIsHeapNode()

BOOL OsMemIsHeapNode ( const VOID *  ptr)

在文件 los_memory.c2126 行定义.

2127{
2128 struct OsMemPoolHead *pool = (struct OsMemPoolHead *)m_aucSysMem1;//内核堆区开始地址
2129 struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool);//获取内存池首个节点
2130 struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize);//获取内存池的尾节点
2131
2132 if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//如果在首尾范围内
2133 return TRUE;
2134 }
2135
2136#if OS_MEM_EXPAND_ENABLE//内存池经过扩展后,新旧块的虚拟地址是不连续的,所以需要跳块判断
2137 UINT32 intSave;
2138 UINT32 size;//详细查看百篇博客系列篇之 鸿蒙内核源码分析(内存池篇)
2139 MEM_LOCK(pool, intSave); //获取自旋锁
2140 while (OsMemIsLastSentinelNode(endNode) == FALSE) { //哨兵节点是内存池结束的标记
2141 size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag);//获取节点大小
2142 firstNode = OsMemSentinelNodeGet(endNode);//获取下一块的开始地址
2143 endNode = OS_MEM_END_NODE(firstNode, size);//获取下一块的尾节点
2144 if (OS_MEM_MIDDLE_ADDR(firstNode, ptr, endNode)) {//判断地址是否在该块中
2145 MEM_UNLOCK(pool, intSave);
2146 return TRUE;
2147 }
2148 }
2149 MEM_UNLOCK(pool, intSave);
2150#endif
2151 return FALSE;
2152}
UINT8 * m_aucSysMem1
系统动态内存池地址的起始地址 @note_thinking 能否不要用 0,1来命名核心变量 ???
Definition: los_memory.c:108
函数调用图:
这是这个函数的调用关系图:

◆ OsMemIsLastSentinelNode()

STATIC INLINE BOOL OsMemIsLastSentinelNode ( struct OsMemNodeHead sentinelNode)

是否为最后一个哨兵节点

在文件 los_memory.c327 行定义.

328{
329 if (OsMemSentinelNodeCheck(sentinelNode) == FALSE) {
330 PRINT_ERR("%s %d, The current sentinel node is invalid\n", __FUNCTION__, __LINE__);
331 return TRUE;
332 }
333
334 if ((OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag) == 0) ||
335 (sentinelNode->ptr.next == NULL)) {
336 return TRUE;
337 }
338
339 return FALSE;
340}
STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode)
检查哨兵节点
Definition: los_memory.c:314
struct OsMemNodeHead * next
Definition: los_memory.c:173
函数调用图:
这是这个函数的调用关系图:

◆ OsMemIsNodeValid()

STATIC INLINE BOOL OsMemIsNodeValid ( const struct OsMemNodeHead node,
const struct OsMemNodeHead startNode,
const struct OsMemNodeHead endNode,
const struct OsMemPoolHead poolInfo 
)

在文件 los_memory.c1238 行定义.

1241{
1242 if (!OS_MEM_MIDDLE_ADDR(startNode, node, endNode)) {
1243 return FALSE;
1244 }
1245
1246 if (OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) {
1247 if (!OS_MEM_MAGIC_VALID(node)) {
1248 return FALSE;
1249 }
1250 return TRUE;
1251 }
1252
1253 if (!OsMemAddrValidCheck(poolInfo, node->ptr.prev)) {
1254 return FALSE;
1255 }
1256
1257 return TRUE;
1258}
函数调用图:
这是这个函数的调用关系图:

◆ OsMemLargeNodeFree()

UINT32 OsMemLargeNodeFree ( const VOID *  ptr)

大内存释放

在文件 los_memory.c382 行定义.

383{
384 LosVmPage *page = OsVmVaddrToPage((VOID *)ptr);//获取物理页
385 if ((page == NULL) || (page->nPages == 0)) {
386 return LOS_NOK;
387 }
388 LOS_PhysPagesFreeContiguous((VOID *)ptr, page->nPages);//释放连续的几个物理页
389
390 return LOS_OK;
391}
VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
释放指定页数地址连续的物理内存
Definition: los_vm_phys.c:494
LosVmPage * OsVmVaddrToPage(VOID *ptr)
通过虚拟地址找映射的物理页框
Definition: los_vm_phys.c:295
物理页框描述符 虚拟内存体现的是程序对内存资源的需求,而物理内存是对该请求的供应。 伙伴算法的思想是:把内存中连续的空闲页框空间看成是空闲页框块,并按照它们的大小(连续页框的数目)分组
Definition: los_vm_page.h:53
UINT16 nPages
Definition: los_vm_page.h:61
函数调用图:
这是这个函数的调用关系图:

◆ OsMemLastSentinelNodeGet()

STATIC INLINE struct OsMemNodeHead * OsMemLastSentinelNodeGet ( const struct OsMemNodeHead sentinelNode)

更新哨兵节点内容

在文件 los_memory.c299 行定义.

300{
301 struct OsMemNodeHead *node = NULL;
302 VOID *ptr = sentinelNode->ptr.next;//返回不连续的内存块
303 UINT32 size = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag); // 获取大小
304
305 while ((ptr != NULL) && (size != 0)) {
306 node = OS_MEM_END_NODE(ptr, size);
307 ptr = node->ptr.next;
308 size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);
309 }
310
311 return node;
312}
这是这个函数的调用关系图:

◆ OsMemLinkRegisterRecord()

STATIC INLINE VOID OsMemLinkRegisterRecord ( struct OsMemNodeHead node)

在文件 los_memory.c575 行定义.

576{
577 LOS_RecordLR(node->linkReg, LOS_RECORD_LR_CNT, LOS_RECORD_LR_CNT, LOS_OMIT_LR_CNT);
578}
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 recordCount, UINT32 jumpCount)
record LR function.
Definition: los_exc.c:1353
UINTPTR linkReg[LOS_RECORD_LR_CNT]
存放左右节点地址,用于检测
Definition: los_memory.c:176
函数调用图:
这是这个函数的调用关系图:

◆ OsMemListAdd()

STATIC INLINE VOID OsMemListAdd ( struct OsMemPoolHead pool,
UINT32  listIndex,
struct OsMemFreeNodeHead node 
)

在文件 los_memory.c769 行定义.

770{
771 struct OsMemFreeNodeHead *firstNode = pool->freeList[listIndex];
772 if (firstNode != NULL) {
773 firstNode->prev = node;
774 }
775 node->prev = NULL;
776 node->next = firstNode;
777 pool->freeList[listIndex] = node;
778 OsMemSetFreeListBit(pool, listIndex);
779 node->header.magic = OS_MEM_NODE_MAGIC;
780}
STATIC INLINE VOID OsMemSetFreeListBit(struct OsMemPoolHead *head, UINT32 index)
Definition: los_memory.c:759
UINT32 magic
魔法数字 0xABCDDCBA
Definition: los_memory.c:170
函数调用图:
这是这个函数的调用关系图:

◆ OsMemListDelete()

STATIC INLINE VOID OsMemListDelete ( struct OsMemPoolHead pool,
UINT32  listIndex,
struct OsMemFreeNodeHead node 
)

从空闲链表中删除

在文件 los_memory.c782 行定义.

783{
784 if (node == pool->freeList[listIndex]) {
785 pool->freeList[listIndex] = node->next;
786 if (node->next == NULL) {//如果链表空了
787 OsMemClearFreeListBit(pool, listIndex);//将位图位 置为 0
788 } else {
789 node->next->prev = NULL;
790 }
791 } else {
792 node->prev->next = node->next;
793 if (node->next != NULL) {
794 node->next->prev = node->prev;
795 }
796 }
797 node->header.magic = OS_MEM_NODE_MAGIC;
798}
STATIC INLINE VOID OsMemClearFreeListBit(struct OsMemPoolHead *head, UINT32 index)
Definition: los_memory.c:764
函数调用图:
这是这个函数的调用关系图:

◆ OsMemLog2()

STATIC INLINE UINT32 OsMemLog2 ( UINT32  size)

在文件 los_memory.c147 行定义.

148{
149 return OsMemFLS(size);
150}
STATIC INLINE UINT16 OsMemFLS(UINT32 bitmap)
Definition: los_memory.c:142
函数调用图:
这是这个函数的调用关系图:

◆ OsMemMagicCheckPrint()

STATIC INLINE VOID OsMemMagicCheckPrint ( struct OsMemNodeHead **  tmpNode)

在文件 los_memory.c1675 行定义.

1676{
1677 PRINT_ERR("[%s], %d, memory check error!\n"
1678 "memory used but magic num wrong, magic num = %#x\n",
1679 __FUNCTION__, __LINE__, (*tmpNode)->magic);
1680}
这是这个函数的调用关系图:

◆ OsMemMergeNode()

STATIC INLINE VOID OsMemMergeNode ( struct OsMemNodeHead node)

合并节点,和前面的节点合并 node 消失

在文件 los_memory.c834 行定义.

835{
836 struct OsMemNodeHead *nextNode = NULL;
837
838 node->ptr.prev->sizeAndFlag += node->sizeAndFlag; //前节点长度变长
839 nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); // 下一个节点位置
840 if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//不是哨兵节点
841 nextNode->ptr.prev = node->ptr.prev;//后一个节点的前节点变成前前节点
842 }
843}
这是这个函数的调用关系图:

◆ OsMemMergeNodeForReAllocBigger()

STATIC INLINE VOID OsMemMergeNodeForReAllocBigger ( VOID *  pool,
UINT32  allocSize,
struct OsMemNodeHead node,
UINT32  nodeSize,
struct OsMemNodeHead nextNode 
)

在文件 los_memory.c1432 行定义.

1434{
1435 node->sizeAndFlag = nodeSize;
1436 OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);
1437 OsMemMergeNode(nextNode);
1438#ifdef LOSCFG_KERNEL_LMS
1440#endif
1441 if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= node->sizeAndFlag) {
1442 OsMemSplitNode(pool, node, allocSize);
1443#ifdef LOSCFG_KERNEL_LMS
1445 } else {
1446 OsLmsReallocResizeMark(node, allocSize);
1447#endif
1448 }
1449 OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag);
1450 OsMemWaterUsedRecord((struct OsMemPoolHead *)pool, node->sizeAndFlag - nodeSize);
1451#ifdef LOSCFG_MEM_LEAKCHECK
1453#endif
1454}
STATIC INLINE VOID OsLmsReallocSplitNodeMark(struct OsMemNodeHead *node)
Definition: los_memory.c:553
STATIC INLINE VOID OsLmsReallocResizeMark(struct OsMemNodeHead *node, UINT32 resize)
Definition: los_memory.c:565
STATIC INLINE VOID OsLmsReallocMergeNodeMark(struct OsMemNodeHead *node)
Definition: los_memory.c:543
函数调用图:
这是这个函数的调用关系图:

◆ OsMemNodeBacktraceInfo()

STATIC VOID OsMemNodeBacktraceInfo ( const struct OsMemNodeHead tmpNode,
const struct OsMemNodeHead preNode 
)

在文件 los_memory.c659 行定义.

661{
662 int i;
663 PRINTK("\n broken node head LR info: \n");
664 for (i = 0; i < LOS_RECORD_LR_CNT; i++) {
665 PRINTK(" LR[%d]:%#x\n", i, tmpNode->linkReg[i]);
666 }
667
668 PRINTK("\n pre node head LR info: \n");
669 for (i = 0; i < LOS_RECORD_LR_CNT; i++) {
670 PRINTK(" LR[%d]:%#x\n", i, preNode->linkReg[i]);
671 }
672}
这是这个函数的调用关系图:

◆ OsMemNodeInfo()

STATIC VOID OsMemNodeInfo ( const struct OsMemNodeHead tmpNode,
const struct OsMemNodeHead preNode 
)

在文件 los_memory.c1806 行定义.

1808{
1809 struct OsMemUsedNodeHead *usedNode = NULL;
1810 struct OsMemFreeNodeHead *freeNode = NULL;
1811
1812 if (tmpNode == preNode) {
1813 PRINTK("\n the broken node is the first node\n");
1814 }
1815
1816 if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) {
1817 usedNode = (struct OsMemUsedNodeHead *)tmpNode;
1818 PRINTK("\n broken node head: %#x %#x %#x, ",
1819 usedNode->header.ptr.prev, usedNode->header.magic, usedNode->header.sizeAndFlag);
1820 } else {
1821 freeNode = (struct OsMemFreeNodeHead *)tmpNode;
1822 PRINTK("\n broken node head: %#x %#x %#x %#x, %#x",
1823 freeNode->header.ptr.prev, freeNode->next, freeNode->prev, freeNode->header.magic,
1824 freeNode->header.sizeAndFlag);
1825 }
1826
1827 if (OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) {
1828 usedNode = (struct OsMemUsedNodeHead *)preNode;
1829 PRINTK("prev node head: %#x %#x %#x\n",
1830 usedNode->header.ptr.prev, usedNode->header.magic, usedNode->header.sizeAndFlag);
1831 } else {
1832 freeNode = (struct OsMemFreeNodeHead *)preNode;
1833 PRINTK("prev node head: %#x %#x %#x %#x, %#x",
1834 freeNode->header.ptr.prev, freeNode->next, freeNode->prev, freeNode->header.magic,
1835 freeNode->header.sizeAndFlag);
1836 }
1837
1838#ifdef LOSCFG_MEM_LEAKCHECK
1839 OsMemNodeBacktraceInfo(tmpNode, preNode);
1840#endif
1841
1842 PRINTK("\n---------------------------------------------\n");
1843 PRINTK(" dump mem tmpNode:%#x ~ %#x\n", tmpNode, ((UINTPTR)tmpNode + OS_MEM_NODE_DUMP_SIZE));
1844 OsDumpMemByte(OS_MEM_NODE_DUMP_SIZE, (UINTPTR)tmpNode);
1845 PRINTK("\n---------------------------------------------\n");
1846 if (preNode != tmpNode) {
1847 PRINTK(" dump mem :%#x ~ tmpNode:%#x\n", ((UINTPTR)tmpNode - OS_MEM_NODE_DUMP_SIZE), tmpNode);
1848 OsDumpMemByte(OS_MEM_NODE_DUMP_SIZE, ((UINTPTR)tmpNode - OS_MEM_NODE_DUMP_SIZE));
1849 PRINTK("\n---------------------------------------------\n");
1850 }
1851}
STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode)
Definition: los_memory.c:659
VOID OsDumpMemByte(size_t length, UINTPTR addr)
函数调用图:
这是这个函数的调用关系图:

◆ OsMemNodeSetTaskID()

STATIC INLINE VOID OsMemNodeSetTaskID ( struct OsMemUsedNodeHead node)

在文件 los_memory.c275 行定义.

276{
277 node->taskID = LOS_CurTaskIDGet();//将当前任务ID绑定到内存池节点上
278}
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
Obtain current running task ID.
Definition: los_task.c:331
函数调用图:
这是这个函数的调用关系图:

◆ OsMemNotEmptyIndexGet()

STATIC INLINE UINT32 OsMemNotEmptyIndexGet ( struct OsMemPoolHead poolHead,
UINT32  index 
)

在文件 los_memory.c701 行定义.

702{
703 UINT32 mask;
704
705 mask = poolHead->freeListBitmap[BITMAP_INDEX(index)];
706 mask &= ~((1 << (index & OS_MEM_BITMAP_MASK)) - 1);
707 if (mask != 0) {
708 index = OsMemFFS(mask) + (index & ~OS_MEM_BITMAP_MASK);
709 return index;
710 }
711
712 return OS_MEM_FREE_LIST_COUNT;
713}
函数调用图:
这是这个函数的调用关系图:

◆ OsMemPoolAdd()

STATIC UINT32 OsMemPoolAdd ( VOID *  pool,
UINT32  size 
)

新增内存池

在文件 los_memory.c954 行定义.

955{
956 VOID *nextPool = g_poolHead;
957 VOID *curPool = g_poolHead;
958 UINTPTR poolEnd;
959 while (nextPool != NULL) {//单链表遍历方式
960 poolEnd = (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool);
961 if (((pool <= nextPool) && (((UINTPTR)pool + size) > (UINTPTR)nextPool)) ||
962 (((UINTPTR)pool < poolEnd) && (((UINTPTR)pool + size) >= poolEnd))) {
963 PRINT_ERR("pool [%#x, %#x) conflict with pool [%#x, %#x)\n",
964 pool, (UINTPTR)pool + size,
965 nextPool, (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool));
966 return LOS_NOK;
967 }
968 curPool = nextPool;
969 nextPool = ((struct OsMemPoolHead *)nextPool)->nextPool;
970 }
971
972 if (g_poolHead == NULL) {
973 g_poolHead = pool; //首个内存池
974 } else {
975 ((struct OsMemPoolHead *)curPool)->nextPool = pool; //两池扯上关系
976 }
977
978 ((struct OsMemPoolHead *)pool)->nextPool = NULL; //新池下一个无所指
979 return LOS_OK;
980}
VOID * g_poolHead
Definition: los_memory.c:111
VOID * nextPool
指向下一个内存池 OsMemPoolHead 类型
Definition: los_memory.c:210
函数调用图:
这是这个函数的调用关系图:

◆ OsMemPoolDeinit()

STATIC VOID OsMemPoolDeinit ( VOID *  pool)

在文件 los_memory.c949 行定义.

950{
951 (VOID)memset(pool, 0, sizeof(struct OsMemPoolHead));
952}
void * memset(void *addr, int c, size_t len)
Definition: lms_libc.c:36
函数调用图:
这是这个函数的调用关系图:

◆ OsMemPoolDelete()

STATIC UINT32 OsMemPoolDelete ( VOID *  pool)

删除内存池

在文件 los_memory.c982 行定义.

983{
984 UINT32 ret = LOS_NOK;
985 VOID *nextPool = NULL;
986 VOID *curPool = NULL;
987
988 do {
989 if (pool == g_poolHead) {
990 g_poolHead = ((struct OsMemPoolHead *)g_poolHead)->nextPool;
991 ret = LOS_OK;
992 break;
993 }
994
995 curPool = g_poolHead;
997 while (nextPool != NULL) {
998 if (pool == nextPool) {
999 ((struct OsMemPoolHead *)curPool)->nextPool = ((struct OsMemPoolHead *)nextPool)->nextPool;
1000 ret = LOS_OK;
1001 break;
1002 }
1003 curPool = nextPool;
1004 nextPool = ((struct OsMemPoolHead *)nextPool)->nextPool;
1005 }
1006 } while (0);
1007
1008 return ret;
1009}
这是这个函数的调用关系图:

◆ OsMemPoolExpand()

STATIC INLINE INT32 OsMemPoolExpand ( VOID *  pool,
UINT32  allocSize,
UINT32  intSave 
)

扩展内存池

允许指定内存池扩展

在文件 los_memory.c478 行定义.

函数调用图:
这是这个函数的调用关系图:

◆ OsMemPoolExpandSub()

STATIC INLINE INT32 OsMemPoolExpandSub ( VOID *  pool,
UINT32  size,
UINT32  intSave 
)

内存池扩展实现

在文件 los_memory.c428 行定义.

429{
430 UINT32 tryCount = MAX_SHRINK_PAGECACHE_TRY;
431 struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool;
432 struct OsMemNodeHead *newNode = NULL;
433 struct OsMemNodeHead *endNode = NULL;
434
435 size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE);//圆整
436 endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize);//获取哨兵节点
437
438RETRY:
439 newNode = (struct OsMemNodeHead *)LOS_PhysPagesAllocContiguous(size >> PAGE_SHIFT);//申请新的内存池 | 物理内存
440 if (newNode == NULL) {
441 if (tryCount > 0) {
442 tryCount--;
443 MEM_UNLOCK(poolInfo, intSave);
444 OsTryShrinkMemory(size >> PAGE_SHIFT);
445 MEM_LOCK(poolInfo, intSave);
446 goto RETRY;
447 }
448
449 PRINT_ERR("OsMemPoolExpand alloc failed size = %u\n", size);
450 return -1;
451 }
452#ifdef LOSCFG_KERNEL_LMS
453 UINT32 resize = 0;
454 if (g_lms != NULL) {
455 /*
456 * resize == 0, shadow memory init failed, no shadow memory for this pool, set poolSize as original size.
457 * resize != 0, shadow memory init successful, set poolSize as resize.
458 */
459 resize = g_lms->init(newNode, size);
460 size = (resize == 0) ? size : resize;
461 }
462#endif
463 newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE);//设置新节点大小
464 newNode->ptr.prev = OS_MEM_END_NODE(newNode, size);//新节点的前节点指向新节点的哨兵节点
465 OsMemSentinelNodeSet(endNode, newNode, size);//设置老内存池的哨兵节点信息,其实就是指向新内存块
466 OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//将新节点加入空闲链表
467
468 endNode = OS_MEM_END_NODE(newNode, size);//获取新节点的哨兵节点
469 (VOID)memset(endNode, 0, sizeof(*endNode));//清空内存
470 endNode->ptr.next = NULL;//新哨兵节点没有后续指向,因为它已成为最后
471 endNode->magic = OS_MEM_NODE_MAGIC;//设置新哨兵节的魔法数字
472 OsMemSentinelNodeSet(endNode, NULL, 0); //设置新哨兵节点内容
473 OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE);//更新内存池警戒线
474
475 return 0;
476}
STATIC INLINE VOID OsMemSentinelNodeSet(struct OsMemNodeHead *sentinelNode, VOID *newNode, UINT32 size)
设置哨兵节点内容
Definition: los_memory.c:342
int OsTryShrinkMemory(size_t nPage)
Definition: los_vm_scan.c:340
VOID * LOS_PhysPagesAllocContiguous(size_t nPages)
分配连续的物理页
Definition: los_vm_phys.c:478
UINT32(* init)(const VOID *pool, UINT32 size)
Definition: los_lms_pri.h:97
函数调用图:
这是这个函数的调用关系图:

◆ OsMemPoolHeadCheck()

STATIC VOID OsMemPoolHeadCheck ( const struct OsMemPoolHead pool)

在文件 los_memory.c1735 行定义.

1736{
1737 struct OsMemFreeNodeHead *tmpNode = NULL;
1738 UINT32 index;
1739 UINT32 flag = 0;
1740
1741 if ((pool->info.pool != pool) || !OS_MEM_IS_ALIGNED(pool, sizeof(VOID *))) {
1742 PRINT_ERR("wrong mem pool addr: %#x, func:%s, line:%d\n", pool, __FUNCTION__, __LINE__);
1743 return;
1744 }
1745
1746 for (index = 0; index < OS_MEM_FREE_LIST_COUNT; index++) {
1747 for (tmpNode = pool->freeList[index]; tmpNode != NULL; tmpNode = tmpNode->next) {
1748 if (OsMemFreeListNodeCheck(pool, tmpNode)) {
1749 flag = 1;
1750 PRINT_ERR("FreeListIndex: %u, node: %#x, bNode: %#x, prev: %#x, next: %#x\n",
1751 index, tmpNode, tmpNode->header.ptr.prev, tmpNode->prev, tmpNode->next);
1752 goto OUT;
1753 }
1754 }
1755 }
1756
1757OUT:
1758 if (flag) {
1759 PRINTK("mem pool info: poolAddr: %#x, poolSize: 0x%x\n", pool, pool->info.totalSize);
1760#ifdef LOSCFG_MEM_WATERLINE
1761 PRINTK("mem pool info: poolWaterLine: 0x%x, poolCurUsedSize: 0x%x\n", pool->info.waterLine,
1762 pool->info.curUsedSize);
1763#endif
1764#if OS_MEM_EXPAND_ENABLE
1765 UINT32 size;
1766 struct OsMemNodeHead *node = NULL;
1767 struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, pool->info.totalSize);
1768 while (OsMemIsLastSentinelNode(sentinel) == FALSE) {
1769 size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag);
1770 node = OsMemSentinelNodeGet(sentinel);
1771 sentinel = OS_MEM_END_NODE(node, size);
1772 PRINTK("expand node info: nodeAddr: %#x, nodeSize: 0x%x\n", node, size);
1773 }
1774#endif
1775 }
1776}
STATIC UINT32 OsMemFreeListNodeCheck(const struct OsMemPoolHead *pool, const struct OsMemFreeNodeHead *node)
Definition: los_memory.c:1715
UINT32 waterLine
Definition: los_memory.c:199
函数调用图:
这是这个函数的调用关系图:

◆ OsMemPoolInit()

STATIC UINT32 OsMemPoolInit ( VOID *  pool,
UINT32  size 
)

OsMemPoolInit 内存池初始化 内存池节点部分包含3种类型节点:未使用空闲内存节点(OsMemFreeNodeHead),已使用内存节点(OsMemUsedNodeHead) 和 尾节点(OsMemNodeHead)。
每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。
空闲内存节点和已使用内存节点后面的内存区域是数据域

参数
pool
size
返回
参见

在文件 los_memory.c894 行定义.

895{
896 struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool;
897 struct OsMemNodeHead *newNode = NULL;
898 struct OsMemNodeHead *endNode = NULL;
899#ifdef LOSCFG_KERNEL_LMS
900 UINT32 resize = 0;
901 if (g_lms != NULL) {
902 /*
903 * resize == 0, shadow memory init failed, no shadow memory for this pool, set poolSize as original size.
904 * resize != 0, shadow memory init successful, set poolSize as resize.
905 */
906 resize = g_lms->init(pool, size);
907 size = (resize == 0) ? size : resize;
908 }
909#endif
910 (VOID)memset(poolHead, 0, sizeof(struct OsMemPoolHead));
911
912 LOS_SpinInit(&poolHead->spinlock);
913 poolHead->info.pool = pool; //内存池的起始地址,但注意真正的内存并不是从此处分配,它只是用来记录这个内存块的开始位置而已.
914 poolHead->info.totalSize = size;//内存池总大小
915 poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. | 默认是上锁,不支持扩展,需扩展得另外设置*/
916
917 newNode = OS_MEM_FIRST_NODE(pool);//跳到第一个节点位置,即跳过结构体本身位置,真正的分配内存是从newNode开始的.
918 newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE);//这才是可供分配给外界使用的总内存块大小,即数据域
919 //OS_MEM_NODE_HEAD_SIZE 叫当前使用节点,即指 newNode占用的空间
920 newNode->ptr.prev = NULL;//开始是空指向
921 newNode->magic = OS_MEM_NODE_MAGIC;//魔法数字 用于标识这是一个 OsMemNodeHead 节点, 魔法数字不能被覆盖,
922 OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);//添加一个空闲节点,由此有了首个可供分配的空闲节点
923
924 /* The last mem node */
925 endNode = OS_MEM_END_NODE(pool, size);//确定尾节点位置,尾节点没有数据域
926 endNode->magic = OS_MEM_NODE_MAGIC; //填入尾节点的魔法数字
927#if OS_MEM_EXPAND_ENABLE //支持扩展
928 endNode->ptr.next = NULL;//尾节点没有后继节点
929 OsMemSentinelNodeSet(endNode, NULL, 0);//将尾节点设置为哨兵节点
930#else
931 endNode->sizeAndFlag = 0;//0代表没有数据域
932 endNode->ptr.prev = newNode;//前驱指针指向第一个节点
933 OS_MEM_NODE_SET_USED_FLAG(endNode->sizeAndFlag);
934#endif
935#ifdef LOSCFG_MEM_WATERLINE //吃水线开关
936 poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE;//内存池已使用了这么多空间,这些都是存内存池自身数据的空间,
937 //但此处是否还要算是 endNode ? @note_thinking
938 poolHead->info.waterLine = poolHead->info.curUsedSize; //设置吃水线
939#endif
940#ifdef LOSCFG_KERNEL_LMS
941 if (resize != 0) {
942 OsLmsFirstNodeMark(pool, newNode);
943 }
944#endif
945 return LOS_OK;
946}
STATIC INLINE VOID OsLmsFirstNodeMark(VOID *pool, struct OsMemNodeHead *node)
Definition: los_memory.c:511
VOID LOS_SpinInit(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:37
SPIN_LOCK_S spinlock
操作本池的自旋锁,涉及CPU多核竞争,所以必须得是自旋锁
Definition: los_memory.c:208
函数调用图:
这是这个函数的调用关系图:

◆ OsMemRealloc()

STATIC INLINE VOID * OsMemRealloc ( struct OsMemPoolHead pool,
const VOID *  ptr,
struct OsMemNodeHead node,
UINT32  size,
UINT32  intSave 
)

在文件 los_memory.c1477 行定义.

1479{
1480 struct OsMemNodeHead *nextNode = NULL;
1481 UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE);
1482 UINT32 nodeSize = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);
1483 VOID *tmpPtr = NULL;
1484
1485 if (nodeSize >= allocSize) {
1486 OsMemReAllocSmaller(pool, allocSize, node, nodeSize);
1487 return (VOID *)ptr;
1488 }
1489
1490 nextNode = OS_MEM_NEXT_NODE(node);
1491 if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag) &&
1492 ((nextNode->sizeAndFlag + nodeSize) >= allocSize)) {
1493 OsMemMergeNodeForReAllocBigger(pool, allocSize, node, nodeSize, nextNode);
1494 return (VOID *)ptr;
1495 }
1496
1497 tmpPtr = OsMemAlloc(pool, size, intSave);
1498 if (tmpPtr != NULL) {
1499 if (memcpy_s(tmpPtr, size, ptr, (nodeSize - OS_MEM_NODE_HEAD_SIZE)) != EOK) {
1500 MEM_UNLOCK(pool, intSave);
1501 (VOID)LOS_MemFree((VOID *)pool, (VOID *)tmpPtr);
1502 MEM_LOCK(pool, intSave);
1503 return NULL;
1504 }
1505 (VOID)OsMemFree(pool, node);
1506 }
1507 return tmpPtr;
1508}
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
Definition: los_memory.c:1369
STATIC INLINE VOID * OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave)
从指定动态内存池中申请size长度的内存
Definition: los_memory.c:1075
STATIC INLINE VOID OsMemReAllocSmaller(VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize)
Definition: los_memory.c:1408
STATIC INLINE VOID OsMemMergeNodeForReAllocBigger(VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize, struct OsMemNodeHead *nextNode)
Definition: los_memory.c:1432
函数调用图:
这是这个函数的调用关系图:

◆ OsMemReAllocSmaller()

STATIC INLINE VOID OsMemReAllocSmaller ( VOID *  pool,
UINT32  allocSize,
struct OsMemNodeHead node,
UINT32  nodeSize 
)

在文件 los_memory.c1408 行定义.

1409{
1410#ifdef LOSCFG_MEM_WATERLINE
1411 struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool;
1412#endif
1413 node->sizeAndFlag = nodeSize;
1414 if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= nodeSize) {
1415 OsMemSplitNode(pool, node, allocSize);
1416 OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag);
1417#ifdef LOSCFG_MEM_WATERLINE
1418 poolInfo->info.curUsedSize -= nodeSize - allocSize;
1419#endif
1420#ifdef LOSCFG_KERNEL_LMS
1422 } else {
1423 OsLmsReallocResizeMark(node, allocSize);
1424#endif
1425 }
1426 OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag);
1427#ifdef LOSCFG_MEM_LEAKCHECK
1429#endif
1430}
函数调用图:
这是这个函数的调用关系图:

◆ OsMemSentinelNodeCheck()

STATIC INLINE BOOL OsMemSentinelNodeCheck ( struct OsMemNodeHead sentinelNode)

检查哨兵节点

在文件 los_memory.c314 行定义.

315{
316 if (!OS_MEM_NODE_GET_USED_FLAG(sentinelNode->sizeAndFlag)) {
317 return FALSE;
318 }
319
320 if (!OS_MEM_MAGIC_VALID(sentinelNode)) {
321 return FALSE;
322 }
323
324 return TRUE;
325}
这是这个函数的调用关系图:

◆ OsMemSentinelNodeGet()

STATIC INLINE VOID * OsMemSentinelNodeGet ( struct OsMemNodeHead node)

在文件 los_memory.c354 行定义.

355{
356 return node->ptr.next;
357}
这是这个函数的调用关系图:

◆ OsMemSentinelNodeSet()

STATIC INLINE VOID OsMemSentinelNodeSet ( struct OsMemNodeHead sentinelNode,
VOID *  newNode,
UINT32  size 
)

设置哨兵节点内容

在文件 los_memory.c342 行定义.

343{
344 if (sentinelNode->ptr.next != NULL) { //哨兵节点有 逻辑地址不连续的衔接内存块
345 sentinelNode = OsMemLastSentinelNodeGet(sentinelNode);//更新哨兵节点内容
346 }
347
348 sentinelNode->sizeAndFlag = size;
349 sentinelNode->ptr.next = newNode;
350 OS_MEM_NODE_SET_USED_FLAG(sentinelNode->sizeAndFlag);
351 OS_MEM_NODE_SET_LAST_FLAG(sentinelNode->sizeAndFlag);
352}
STATIC INLINE struct OsMemNodeHead * OsMemLastSentinelNodeGet(const struct OsMemNodeHead *sentinelNode)
更新哨兵节点内容
Definition: los_memory.c:299
函数调用图:
这是这个函数的调用关系图:

◆ OsMemSetFreeListBit()

STATIC INLINE VOID OsMemSetFreeListBit ( struct OsMemPoolHead head,
UINT32  index 
)

在文件 los_memory.c759 行定义.

760{
761 head->freeListBitmap[BITMAP_INDEX(index)] |= 1U << (index & 0x1f);
762}
这是这个函数的调用关系图:

◆ OsMemSlGet()

STATIC INLINE UINT32 OsMemSlGet ( UINT32  size,
UINT32  fl 
)

在文件 los_memory.c162 行定义.

163{
164 return (((size << OS_MEM_SLI) >> fl) - OS_MEM_FREE_LIST_NUM);
165}
这是这个函数的调用关系图:

◆ OsMemSplitNode()

STATIC INLINE VOID OsMemSplitNode ( VOID *  pool,
struct OsMemNodeHead allocNode,
UINT32  allocSize 
)

切割节点

在文件 los_memory.c845 行定义.

846{
847 struct OsMemFreeNodeHead *newFreeNode = NULL;
848 struct OsMemNodeHead *nextNode = NULL;
849
850 newFreeNode = (struct OsMemFreeNodeHead *)(VOID *)((UINT8 *)allocNode + allocSize);//切割后出现的新空闲节点,在分配节点的右侧
851 newFreeNode->header.ptr.prev = allocNode;//新节点指向前节点,说明是从左到右切割
852 newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize;//新空闲节点大小
853 allocNode->sizeAndFlag = allocSize;//分配节点大小
854 nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header);//获取新节点的下一个节点
855 if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点不是哨兵节点(末尾节点)
856 nextNode->ptr.prev = &newFreeNode->header;//下一个节点的前节点为新空闲节点
857 if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) {//如果下一个节点也是空闲的
858 OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);//删除下一个节点信息
859 OsMemMergeNode(nextNode);//下一个节点和新空闲节点 合并成一个新节点
860 }
861 }
862
863 OsMemFreeNodeAdd(pool, newFreeNode);//挂入空闲链表
864}
unsigned char UINT8
Definition: los_typedef.h:55
函数调用图:
这是这个函数的调用关系图:

◆ OsMemUsedNodePrint()

STATIC INLINE VOID OsMemUsedNodePrint ( struct OsMemNodeHead node)

在文件 los_memory.c580 行定义.

581{
582 UINT32 count;
583
584 if (OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) {
585#ifdef __LP64__
586 PRINTK("0x%018x: ", node);
587#else
588 PRINTK("0x%010x: ", node);
589#endif
590 for (count = 0; count < LOS_RECORD_LR_CNT; count++) {
591#ifdef __LP64__
592 PRINTK(" 0x%018x ", node->linkReg[count]);
593#else
594 PRINTK(" 0x%010x ", node->linkReg[count]);
595#endif
596 }
597 PRINTK("\n");
598 }
599}
这是这个函数的调用关系图:

◆ OsMemUsedNodeShow()

VOID OsMemUsedNodeShow ( VOID *  pool)

打印已使用的节点

在文件 los_memory.c601 行定义.

602{
603 if (pool == NULL) {
604 PRINTK("input param is NULL\n");
605 return;
606 }
607 if (LOS_MemIntegrityCheck(pool)) {
608 PRINTK("LOS_MemIntegrityCheck error\n");
609 return;
610 }
611 struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool;
612 struct OsMemNodeHead *tmpNode = NULL;
613 struct OsMemNodeHead *endNode = NULL;
614 UINT32 size;
615 UINT32 intSave;
616 UINT32 count;
617
618#ifdef __LP64__
619 PRINTK("\n\rnode ");
620#else
621 PRINTK("\n\rnode ");
622#endif
623 for (count = 0; count < LOS_RECORD_LR_CNT; count++) {
624#ifdef __LP64__
625 PRINTK(" LR[%u] ", count);
626#else
627 PRINTK(" LR[%u] ", count);
628#endif
629 }
630 PRINTK("\n");
631
632 MEM_LOCK(poolInfo, intSave);
633 endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize);
634#if OS_MEM_EXPAND_ENABLE
635 for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode;
636 tmpNode = OS_MEM_NEXT_NODE(tmpNode)) {
637 if (tmpNode == endNode) {
638 if (OsMemIsLastSentinelNode(endNode) == FALSE) {
639 size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag);
640 tmpNode = OsMemSentinelNodeGet(endNode);
641 endNode = OS_MEM_END_NODE(tmpNode, size);
642 continue;
643 } else {
644 break;
645 }
646 } else {
647 OsMemUsedNodePrint(tmpNode);
648 }
649 }
650#else
651 for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode;
652 tmpNode = OS_MEM_NEXT_NODE(tmpNode)) {
653 OsMemUsedNodePrint(tmpNode);
654 }
655#endif
656 MEM_UNLOCK(poolInfo, intSave);
657}
UINT32 LOS_MemIntegrityCheck(const VOID *pool)
对指定内存池做完整性检查
Definition: los_memory.c:1903
STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node)
Definition: los_memory.c:580
函数调用图:
这是这个函数的调用关系图:

◆ OsMemWaterUsedRecord()

STATIC INLINE VOID OsMemWaterUsedRecord ( struct OsMemPoolHead pool,
UINT32  size 
)

在文件 los_memory.c282 行定义.

283{
284 pool->info.curUsedSize += size; //延长可使用空间
285 if (pool->info.curUsedSize > pool->info.waterLine) {
286 pool->info.waterLine = pool->info.curUsedSize; //警戒线加高
287 }
288}
这是这个函数的调用关系图:

◆ PreSentinelNodeGet()

STATIC INLINE struct OsMemNodeHead * PreSentinelNodeGet ( const VOID *  pool,
const struct OsMemNodeHead node 
)

在文件 los_memory.c359 行定义.

360{
361 UINT32 nextSize;
362 struct OsMemNodeHead *nextNode = NULL;
363 struct OsMemNodeHead *sentinelNode = NULL;
364
365 sentinelNode = OS_MEM_END_NODE(pool, ((struct OsMemPoolHead *)pool)->info.totalSize);
366 while (sentinelNode != NULL) {
367 if (OsMemIsLastSentinelNode(sentinelNode)) {
368 PRINT_ERR("PreSentinelNodeGet can not find node %#x\n", node);
369 return NULL;
370 }
371 nextNode = OsMemSentinelNodeGet(sentinelNode);
372 if (nextNode == node) {
373 return sentinelNode;
374 }
375 nextSize = OS_MEM_NODE_GET_SIZE(sentinelNode->sizeAndFlag);
376 sentinelNode = OS_MEM_END_NODE(nextNode, nextSize);
377 }
378
379 return NULL;
380}
函数调用图:
这是这个函数的调用关系图:

◆ TryShrinkPool()

STATIC INLINE BOOL TryShrinkPool ( const VOID *  pool,
const struct OsMemNodeHead node 
)

在文件 los_memory.c393 行定义.

394{
395 struct OsMemNodeHead *mySentinel = NULL;
396 struct OsMemNodeHead *preSentinel = NULL;
397 size_t totalSize = (UINTPTR)node->ptr.prev - (UINTPTR)node;
398 size_t nodeSize = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);
399
400 if (nodeSize != totalSize) {
401 return FALSE;
402 }
403
404 preSentinel = PreSentinelNodeGet(pool, node);
405 if (preSentinel == NULL) {
406 return FALSE;
407 }
408
409 mySentinel = node->ptr.prev;
410 if (OsMemIsLastSentinelNode(mySentinel)) { /* prev node becomes sentinel node */
411 preSentinel->ptr.next = NULL;
412 OsMemSentinelNodeSet(preSentinel, NULL, 0);
413 } else {
414 preSentinel->sizeAndFlag = mySentinel->sizeAndFlag;
415 preSentinel->ptr.next = mySentinel->ptr.next;
416 }
417
418 if (OsMemLargeNodeFree(node) != LOS_OK) {
419 PRINT_ERR("TryShrinkPool free %#x failed!\n", node);
420 return FALSE;
421 }
422#ifdef LOSCFG_KERNEL_LMS
424#endif
425 return TRUE;
426}
VOID LOS_LmsCheckPoolDel(const VOID *pool)
Definition: los_lms.c:189
STATIC INLINE struct OsMemNodeHead * PreSentinelNodeGet(const VOID *pool, const struct OsMemNodeHead *node)
Definition: los_memory.c:359
UINT32 OsMemLargeNodeFree(const VOID *ptr)
大内存释放
Definition: los_memory.c:382
函数调用图:
这是这个函数的调用关系图:

变量说明

◆ g_poolHead

VOID* g_poolHead = NULL

在文件 los_memory.c111 行定义.