90#ifdef LOSCFG_KERNEL_LMS
91#include "los_lms_pri.h"
95#define OS_MEM_FREE_BY_TASKID 0
96#ifdef LOSCFG_KERNEL_VM
97#define OS_MEM_EXPAND_ENABLE 1
99#define OS_MEM_EXPAND_ENABLE 0
103#define OS_MEM_NODE_DUMP_SIZE 64
105#define OS_MEM_COLUMN_NUM 8
110#ifdef LOSCFG_MEM_MUL_POOL
119#define OS_MEM_SMALL_BUCKET_COUNT 31
120#define OS_MEM_SMALL_BUCKET_MAX_SIZE 128
122#define OS_MEM_LARGE_BUCKET_COUNT 24
123#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI)
125#define OS_MEM_LARGE_START_BUCKET 7
128#define OS_MEM_FREE_LIST_COUNT (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI))
130#define OS_MEM_BITMAP_WORDS ((OS_MEM_FREE_LIST_COUNT >> 5) + 1)
132#define OS_MEM_BITMAP_MASK 0x1FU
137 bitmap &= ~bitmap + 1;
138 return (OS_MEM_BITMAP_MASK - CLZ(bitmap));
144 return (OS_MEM_BITMAP_MASK - CLZ(bitmap));
155 if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) {
156 return ((size >> 2) - 1);
164 return (((size << OS_MEM_SLI) >> fl) - OS_MEM_FREE_LIST_NUM);
175#ifdef LOSCFG_MEM_LEAKCHECK
183#if OS_MEM_FREE_BY_TASKID
198#ifdef LOSCFG_MEM_WATERLINE
209#ifdef LOSCFG_MEM_MUL_POOL
215#define MEM_LOCK(pool, state) LOS_SpinLockSave(&(pool)->spinlock, &(state))
216#define MEM_UNLOCK(pool, state) LOS_SpinUnlockRestore(&(pool)->spinlock, (state))
219#define OS_MEM_POOL_EXPAND_ENABLE 0x01
221#define OS_MEM_POOL_LOCK_ENABLE 0x02
223#define OS_MEM_NODE_MAGIC 0xABCDDCBA
224#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead))
226#define OS_MEM_NODE_USED_FLAG 0x80000000U
227#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U
228#define OS_MEM_NODE_LAST_FLAG 0x20000000U
229#define OS_MEM_NODE_ALIGNED_AND_USED_FLAG (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LAST_FLAG)
231#define OS_MEM_NODE_GET_ALIGNED_FLAG(sizeAndFlag) \
232 ((sizeAndFlag) & OS_MEM_NODE_ALIGNED_FLAG)
233#define OS_MEM_NODE_SET_ALIGNED_FLAG(sizeAndFlag) \
234 ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_ALIGNED_FLAG))
235#define OS_MEM_NODE_GET_ALIGNED_GAPSIZE(sizeAndFlag) \
236 ((sizeAndFlag) & ~OS_MEM_NODE_ALIGNED_FLAG)
237#define OS_MEM_NODE_GET_USED_FLAG(sizeAndFlag) \
238 ((sizeAndFlag) & OS_MEM_NODE_USED_FLAG)
239#define OS_MEM_NODE_SET_USED_FLAG(sizeAndFlag) \
240 ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_USED_FLAG))
241#define OS_MEM_NODE_GET_SIZE(sizeAndFlag) \
242 ((sizeAndFlag) & ~OS_MEM_NODE_ALIGNED_AND_USED_FLAG)
243#define OS_MEM_NODE_SET_LAST_FLAG(sizeAndFlag) \
244 ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_LAST_FLAG))
245#define OS_MEM_NODE_GET_LAST_FLAG(sizeAndFlag) \
246 ((sizeAndFlag) & OS_MEM_NODE_LAST_FLAG)
248#define OS_MEM_ALIGN_SIZE sizeof(UINTPTR)
249#define OS_MEM_IS_POW_TWO(value) ((((UINTPTR)(value)) & ((UINTPTR)(value) - 1)) == 0)
250#define OS_MEM_ALIGN(p, alignSize) (((UINTPTR)(p) + (alignSize) - 1) & ~((UINTPTR)((alignSize) - 1)))
251#define OS_MEM_IS_ALIGNED(a, b) (!(((UINTPTR)(a)) & (((UINTPTR)(b)) - 1)))
252#define OS_MEM_NODE_HEAD_SIZE sizeof(struct OsMemUsedNodeHead)
253#define OS_MEM_MIN_POOL_SIZE (OS_MEM_NODE_HEAD_SIZE + sizeof(struct OsMemPoolHead))
254#define OS_MEM_NEXT_NODE(node) \
255 ((struct OsMemNodeHead *)(VOID *)((UINT8 *)(node) + OS_MEM_NODE_GET_SIZE((node)->sizeAndFlag)))
256#define OS_MEM_FIRST_NODE(pool) \
257 (struct OsMemNodeHead *)((UINT8 *)(pool) + sizeof(struct OsMemPoolHead))
258#define OS_MEM_END_NODE(pool, size) \
259 (struct OsMemNodeHead *)((UINT8 *)(pool) + (size) - OS_MEM_NODE_HEAD_SIZE)
260#define OS_MEM_MIDDLE_ADDR_OPEN_END(startAddr, middleAddr, endAddr) \
261 (((UINT8 *)(startAddr) <= (UINT8 *)(middleAddr)) && ((UINT8 *)(middleAddr) < (UINT8 *)(endAddr)))
262#define OS_MEM_MIDDLE_ADDR(startAddr, middleAddr, endAddr) \
263 (((UINT8 *)(startAddr) <= (UINT8 *)(middleAddr)) && ((UINT8 *)(middleAddr) <= (UINT8 *)(endAddr)))
264#define OS_MEM_SET_MAGIC(node) ((node)->magic = OS_MEM_NODE_MAGIC)
265#define OS_MEM_MAGIC_VALID(node) ((node)->magic == OS_MEM_NODE_MAGIC)
270#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK
274#if OS_MEM_FREE_BY_TASKID
281#ifdef LOSCFG_MEM_WATERLINE
297#if OS_MEM_EXPAND_ENABLE
305 while ((
ptr != NULL) && (size != 0)) {
306 node = OS_MEM_END_NODE(
ptr, size);
316 if (!OS_MEM_NODE_GET_USED_FLAG(sentinelNode->
sizeAndFlag)) {
320 if (!OS_MEM_MAGIC_VALID(sentinelNode)) {
330 PRINT_ERR(
"%s %d, The current sentinel node is invalid\n", __FUNCTION__, __LINE__);
334 if ((OS_MEM_NODE_GET_SIZE(sentinelNode->
sizeAndFlag) == 0) ||
335 (sentinelNode->
ptr.
next == NULL)) {
344 if (sentinelNode->
ptr.
next != NULL) {
349 sentinelNode->
ptr.
next = newNode;
350 OS_MEM_NODE_SET_USED_FLAG(sentinelNode->
sizeAndFlag);
351 OS_MEM_NODE_SET_LAST_FLAG(sentinelNode->
sizeAndFlag);
365 sentinelNode = OS_MEM_END_NODE(pool, ((
struct OsMemPoolHead *)pool)->info.totalSize);
366 while (sentinelNode != NULL) {
368 PRINT_ERR(
"PreSentinelNodeGet can not find node %#x\n", node);
372 if (nextNode == node) {
375 nextSize = OS_MEM_NODE_GET_SIZE(sentinelNode->
sizeAndFlag);
376 sentinelNode = OS_MEM_END_NODE(nextNode, nextSize);
385 if ((page == NULL) || (page->
nPages == 0)) {
398 size_t nodeSize = OS_MEM_NODE_GET_SIZE(node->
sizeAndFlag);
400 if (nodeSize != totalSize) {
405 if (preSentinel == NULL) {
419 PRINT_ERR(
"TryShrinkPool free %#x failed!\n", node);
422#ifdef LOSCFG_KERNEL_LMS
430 UINT32 tryCount = MAX_SHRINK_PAGECACHE_TRY;
435 size = ROUNDUP(size + OS_MEM_NODE_HEAD_SIZE, PAGE_SIZE);
440 if (newNode == NULL) {
443 MEM_UNLOCK(poolInfo, intSave);
445 MEM_LOCK(poolInfo, intSave);
449 PRINT_ERR(
"OsMemPoolExpand alloc failed size = %u\n", size);
452#ifdef LOSCFG_KERNEL_LMS
460 size = (resize == 0) ? size : resize;
463 newNode->
sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE);
464 newNode->
ptr.
prev = OS_MEM_END_NODE(newNode, size);
468 endNode = OS_MEM_END_NODE(newNode, size);
469 (VOID)
memset(endNode, 0,
sizeof(*endNode));
471 endNode->
magic = OS_MEM_NODE_MAGIC;
481 UINT32 expandSize = MAX(expandDefault, allocSize);
491 if (allocSize > expandDefault) {
494 expandSize = allocSize;
495 }
while (tryCount--);
506 ((
struct OsMemPoolHead *)pool)->info.attr |= OS_MEM_POOL_EXPAND_ENABLE;
510#ifdef LOSCFG_KERNEL_LMS
520 LMS_SHADOW_REDZONE_U8);
522 LMS_SHADOW_AFTERFREE_U8);
529 if ((
g_lms == NULL) || (
ptr == NULL)) {
533 if (
ptr != alignedPtr) {
540 LMS_SHADOW_REDZONE_U8);
550 LMS_SHADOW_ACCESSABLE_U8);
560 (
UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE, LMS_SHADOW_REDZONE_U8);
562 (
UINTPTR)OS_MEM_NEXT_NODE(OS_MEM_NEXT_NODE(node)), LMS_SHADOW_AFTERFREE_U8);
574#ifdef LOSCFG_MEM_LEAKCHECK
584 if (OS_MEM_NODE_GET_USED_FLAG(node->
sizeAndFlag)) {
586 PRINTK(
"0x%018x: ", node);
588 PRINTK(
"0x%010x: ", node);
590 for (count = 0; count < LOS_RECORD_LR_CNT; count++) {
592 PRINTK(
" 0x%018x ", node->
linkReg[count]);
594 PRINTK(
" 0x%010x ", node->
linkReg[count]);
604 PRINTK(
"input param is NULL\n");
608 PRINTK(
"LOS_MemIntegrityCheck error\n");
623 for (count = 0; count < LOS_RECORD_LR_CNT; count++) {
625 PRINTK(
" LR[%u] ", count);
627 PRINTK(
" LR[%u] ", count);
632 MEM_LOCK(poolInfo, intSave);
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) {
641 endNode = OS_MEM_END_NODE(tmpNode, size);
651 for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode;
652 tmpNode = OS_MEM_NEXT_NODE(tmpNode)) {
656 MEM_UNLOCK(poolInfo, intSave);
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]);
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]);
678 if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) {
683 return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl);
691 for (node = poolHead->
freeList[index]; node != NULL; node = node->
next) {
700#define BITMAP_INDEX(index) ((index) >> 5)
706 mask &= ~((1 << (index & OS_MEM_BITMAP_MASK)) - 1);
708 index =
OsMemFFS(mask) + (index & ~OS_MEM_BITMAP_MASK);
712 return OS_MEM_FREE_LIST_COUNT;
721 UINT32 curIndex = OS_MEM_FREE_LIST_COUNT;
725 if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) {
729 curIndex = ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl + OS_MEM_SMALL_BUCKET_COUNT;
730 index = curIndex + 1;
734 if (tmp != OS_MEM_FREE_LIST_COUNT) {
739 for (index =
LOS_Align(index + 1, 32); index < OS_MEM_FREE_LIST_COUNT; index += 32) {
748 if (curIndex == OS_MEM_FREE_LIST_COUNT) {
752 *outIndex = curIndex;
761 head->
freeListBitmap[BITMAP_INDEX(index)] |= 1U << (index & 0x1f);
766 head->
freeListBitmap[BITMAP_INDEX(index)] &= ~(1U << (index & 0x1f));
772 if (firstNode != NULL) {
773 firstNode->
prev = node;
776 node->
next = firstNode;
784 if (node == pool->
freeList[listIndex]) {
786 if (node->
next == NULL) {
793 if (node->
next != NULL) {
803 if (index >= OS_MEM_FREE_LIST_COUNT) {
804 LOS_Panic(
"The index of free lists is error, index = %u\n", index);
813 if (index >= OS_MEM_FREE_LIST_COUNT) {
814 LOS_Panic(
"The index of free lists is error, index = %u\n", index);
825 if (firstNode == NULL) {
831 return &firstNode->
header;
840 if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->
sizeAndFlag)) {
854 nextNode = OS_MEM_NEXT_NODE(&newFreeNode->
header);
855 if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->
sizeAndFlag)) {
857 if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->
sizeAndFlag)) {
870#if OS_MEM_FREE_BY_TASKID
874#ifdef LOSCFG_KERNEL_LMS
877 g_lms->
mallocMark(newNode, OS_MEM_NEXT_NODE(newNode), OS_MEM_NODE_HEAD_SIZE);
899#ifdef LOSCFG_KERNEL_LMS
907 size = (resize == 0) ? size : resize;
915 poolHead->
info.
attr = OS_MEM_POOL_LOCK_ENABLE;
917 newNode = OS_MEM_FIRST_NODE(pool);
921 newNode->
magic = OS_MEM_NODE_MAGIC;
925 endNode = OS_MEM_END_NODE(pool, size);
926 endNode->
magic = OS_MEM_NODE_MAGIC;
927#if OS_MEM_EXPAND_ENABLE
935#ifdef LOSCFG_MEM_WATERLINE
940#ifdef LOSCFG_KERNEL_LMS
948#ifdef LOSCFG_MEM_MUL_POOL
962 (((
UINTPTR)pool < poolEnd) && (((
UINTPTR)pool + size) >= poolEnd))) {
963 PRINT_ERR(
"pool [%#x, %#x) conflict with pool [%#x, %#x)\n",
986 VOID *curPool = NULL;
1023 if ((pool == NULL) || (size <= OS_MEM_MIN_POOL_SIZE)) {
1027 size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE);
1032#ifdef LOSCFG_MEM_MUL_POOL
1039 OsHookCall(LOS_HOOK_TYPE_MEM_INIT, pool, size);
1043#ifdef LOSCFG_MEM_MUL_POOL
1057 OsHookCall(LOS_HOOK_TYPE_MEM_DEINIT, pool);
1066 PRINTK(
"pool%u :\n", index);
1079#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK
1085 UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE);
1086#if OS_MEM_EXPAND_ENABLE
1090 if (allocNode == NULL) {
1091#if OS_MEM_EXPAND_ENABLE
1092 if (pool->
info.
attr & OS_MEM_POOL_EXPAND_ENABLE) {
1099 MEM_UNLOCK(pool, intSave);
1100 PRINT_ERR(
"---------------------------------------------------"
1101 "--------------------------------------------------------\n");
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);
1110 if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->
sizeAndFlag) {
1114 OS_MEM_NODE_SET_USED_FLAG(allocNode->
sizeAndFlag);
1117#ifdef LOSCFG_MEM_LEAKCHECK
1125 if ((pool == NULL) || (size == 0)) {
1129 if (size < OS_MEM_MIN_ALLOC_SIZE) {
1130 size = OS_MEM_MIN_ALLOC_SIZE;
1138 if (OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) {
1141 MEM_LOCK(poolHead, intSave);
1143 MEM_UNLOCK(poolHead, intSave);
1146 OsHookCall(LOS_HOOK_TYPE_MEM_ALLOC, pool, ptr, size);
1154 if ((pool == NULL) || (size == 0) || (boundary == 0) || !OS_MEM_IS_POW_TWO(boundary) ||
1155 !OS_MEM_IS_ALIGNED(boundary,
sizeof(VOID *))) {
1159 if (size < OS_MEM_MIN_ALLOC_SIZE) {
1160 size = OS_MEM_MIN_ALLOC_SIZE;
1168 if ((boundary -
sizeof(gapSize)) > ((
UINT32)(-1) - size)) {
1172 UINT32 useSize = (size + boundary) -
sizeof(gapSize);
1173 if (OS_MEM_NODE_GET_USED_FLAG(useSize) || OS_MEM_NODE_GET_ALIGNED_FLAG(useSize)) {
1180 VOID *alignedPtr = NULL;
1183 MEM_LOCK(poolHead, intSave);
1185 MEM_UNLOCK(poolHead, intSave);
1186 alignedPtr = (VOID *)OS_MEM_ALIGN(ptr, boundary);
1187 if (ptr == alignedPtr) {
1188#ifdef LOSCFG_KERNEL_LMS
1198 OS_MEM_NODE_SET_ALIGNED_FLAG(gapSize);
1199 *(
UINT32 *)((
UINTPTR)alignedPtr -
sizeof(gapSize)) = gapSize;
1200#ifdef LOSCFG_KERNEL_LMS
1206 OsHookCall(LOS_HOOK_TYPE_MEM_ALLOCALIGN, pool, ptr, size, boundary);
1220 if (OS_MEM_MIDDLE_ADDR_OPEN_END(pool + 1, addr, (
UINTPTR)pool + size)) {
1223#if OS_MEM_EXPAND_ENABLE
1225 struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, size);
1227 size = OS_MEM_NODE_GET_SIZE(sentinel->
sizeAndFlag);
1229 sentinel = OS_MEM_END_NODE(node, size);
1230 if (OS_MEM_MIDDLE_ADDR_OPEN_END(node, addr, (
UINTPTR)node + size)) {
1242 if (!OS_MEM_MIDDLE_ADDR(startNode, node, endNode)) {
1246 if (OS_MEM_NODE_GET_USED_FLAG(node->
sizeAndFlag)) {
1247 if (!OS_MEM_MAGIC_VALID(node)) {
1267 if (!OS_MEM_NODE_GET_USED_FLAG(node->
sizeAndFlag)) {
1271 const struct OsMemNodeHead *nextNode = OS_MEM_NEXT_NODE(node);
1276 if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->
sizeAndFlag)) {
1277 if (nextNode->
ptr.
prev != node) {
1282 if ((node != startNode) &&
1284 (OS_MEM_NEXT_NODE(node->
ptr.
prev) != node))) {
1295 BOOL doneFlag = FALSE;
1300#if OS_MEM_EXPAND_ENABLE
1303 endNode = OS_MEM_END_NODE(startNode, OS_MEM_NODE_GET_SIZE(endNode->
sizeAndFlag));
1309 }
while (!doneFlag);
1317 if (ret != LOS_OK) {
1318 PRINT_ERR(
"OsMemFree check error!\n");
1322#ifdef LOSCFG_MEM_WATERLINE
1327#ifdef LOSCFG_MEM_LEAKCHECK
1330#ifdef LOSCFG_KERNEL_LMS
1331 struct OsMemNodeHead *nextNodeBackup = OS_MEM_NEXT_NODE(node);
1333 if (
g_lms != NULL) {
1338 if ((preNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(preNode->
sizeAndFlag)) {
1345 if ((nextNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(nextNode->
sizeAndFlag)) {
1350#if OS_MEM_EXPAND_ENABLE
1351 if (pool->
info.
attr & OS_MEM_POOL_EXPAND_ENABLE) {
1361#ifdef LOSCFG_KERNEL_LMS
1362 if (
g_lms != NULL) {
1363 g_lms->
freeMark(curNodeBackup, nextNodeBackup, OS_MEM_NODE_HEAD_SIZE);
1374 if ((pool == NULL) || (
ptr == NULL) || !OS_MEM_IS_ALIGNED(pool,
sizeof(VOID *)) ||
1375 !OS_MEM_IS_ALIGNED(
ptr,
sizeof(VOID *))) {
1378 OsHookCall(LOS_HOOK_TYPE_MEM_FREE, pool,
ptr);
1385 if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) {
1386 PRINT_ERR(
"[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize);
1392 if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) {
1393 gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize);
1394 if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) || (gapSize > ((
UINTPTR)
ptr - OS_MEM_NODE_HEAD_SIZE))) {
1395 PRINT_ERR(
"illegal gapSize: 0x%x\n", gapSize);
1400 MEM_LOCK(poolHead, intSave);
1402 MEM_UNLOCK(poolHead, intSave);
1410#ifdef LOSCFG_MEM_WATERLINE
1414 if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= nodeSize) {
1417#ifdef LOSCFG_MEM_WATERLINE
1420#ifdef LOSCFG_KERNEL_LMS
1427#ifdef LOSCFG_MEM_LEAKCHECK
1438#ifdef LOSCFG_KERNEL_LMS
1441 if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= node->
sizeAndFlag) {
1443#ifdef LOSCFG_KERNEL_LMS
1451#ifdef LOSCFG_MEM_LEAKCHECK
1458 VOID *realPtr = ptr;
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);
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);
1481 UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE);
1483 VOID *tmpPtr = NULL;
1485 if (nodeSize >= allocSize) {
1490 nextNode = OS_MEM_NEXT_NODE(node);
1491 if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->
sizeAndFlag) &&
1492 ((nextNode->
sizeAndFlag + nodeSize) >= allocSize)) {
1498 if (tmpPtr != NULL) {
1499 if (memcpy_s(tmpPtr, size,
ptr, (nodeSize - OS_MEM_NODE_HEAD_SIZE)) != EOK) {
1500 MEM_UNLOCK(pool, intSave);
1502 MEM_LOCK(pool, intSave);
1512 if ((pool == NULL) || OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) {
1515 OsHookCall(LOS_HOOK_TYPE_MEM_REALLOC, pool,
ptr, size);
1516 if (size < OS_MEM_MIN_ALLOC_SIZE) {
1517 size = OS_MEM_MIN_ALLOC_SIZE;
1531 VOID *newPtr = NULL;
1534 MEM_LOCK(poolHead, intSave);
1548 MEM_UNLOCK(poolHead, intSave);
1553#if OS_MEM_FREE_BY_TASKID
1560 if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
1571 MEM_LOCK(poolHead, intSave);
1573 for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode;) {
1574 if (tmpNode == endNode) {
1576 size = OS_MEM_NODE_GET_SIZE(endNode->
sizeAndFlag);
1578 endNode = OS_MEM_END_NODE(tmpNode, size);
1584 if (!OS_MEM_NODE_GET_USED_FLAG(tmpNode->
sizeAndFlag)) {
1585 tmpNode = OS_MEM_NEXT_NODE(tmpNode);
1590 tmpNode = OS_MEM_NEXT_NODE(tmpNode);
1597 MEM_UNLOCK(poolHead, intSave);
1613#if OS_MEM_EXPAND_ENABLE
1616 struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, count);
1619 size = OS_MEM_NODE_GET_SIZE(sentinel->
sizeAndFlag);
1621 sentinel = OS_MEM_END_NODE(node, size);
1640 MEM_LOCK(poolInfo, intSave);
1642#if OS_MEM_EXPAND_ENABLE
1644 for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode;) {
1645 if (tmpNode == endNode) {
1646 memUsed += OS_MEM_NODE_HEAD_SIZE;
1648 size = OS_MEM_NODE_GET_SIZE(endNode->
sizeAndFlag);
1650 endNode = OS_MEM_END_NODE(tmpNode, size);
1656 if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->
sizeAndFlag)) {
1657 memUsed += OS_MEM_NODE_GET_SIZE(tmpNode->
sizeAndFlag);
1659 tmpNode = OS_MEM_NEXT_NODE(tmpNode);
1663 for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode;) {
1664 if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->
sizeAndFlag)) {
1665 memUsed += OS_MEM_NODE_GET_SIZE(tmpNode->
sizeAndFlag);
1667 tmpNode = OS_MEM_NEXT_NODE(tmpNode);
1670 MEM_UNLOCK(poolInfo, intSave);
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);
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);
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);
1702 if (!OS_MEM_MAGIC_VALID(*tmpNode)) {
1707 if (!OS_MEM_NODE_GET_USED_FLAG((*tmpNode)->sizeAndFlag)) {
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 *))) {
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__);
1746 for (index = 0; index < OS_MEM_FREE_LIST_COUNT; index++) {
1747 for (tmpNode = pool->
freeList[index]; tmpNode != NULL; tmpNode = tmpNode->
next) {
1750 PRINT_ERR(
"FreeListIndex: %u, node: %#x, bNode: %#x, prev: %#x, next: %#x\n",
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,
1764#if OS_MEM_EXPAND_ENABLE
1769 size = OS_MEM_NODE_GET_SIZE(sentinel->
sizeAndFlag);
1771 sentinel = OS_MEM_END_NODE(node, size);
1772 PRINTK(
"expand node info: nodeAddr: %#x, nodeSize: 0x%x\n", node, size);
1785 *preNode = OS_MEM_FIRST_NODE(pool);
1787 for (*tmpNode = *preNode; *tmpNode < endNode; *tmpNode = OS_MEM_NEXT_NODE(*tmpNode)) {
1791 *preNode = *tmpNode;
1793#if OS_MEM_EXPAND_ENABLE
1796 endNode = OS_MEM_END_NODE(*preNode, OS_MEM_NODE_GET_SIZE((*tmpNode)->sizeAndFlag));
1812 if (tmpNode == preNode) {
1813 PRINTK(
"\n the broken node is the first node\n");
1816 if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->
sizeAndFlag)) {
1818 PRINTK(
"\n broken node head: %#x %#x %#x, ",
1822 PRINTK(
"\n broken node head: %#x %#x %#x %#x, %#x",
1827 if (OS_MEM_NODE_GET_USED_FLAG(preNode->
sizeAndFlag)) {
1829 PRINTK(
"prev node head: %#x %#x %#x\n",
1833 PRINTK(
"prev node head: %#x %#x %#x %#x, %#x",
1838#ifdef LOSCFG_MEM_LEAKCHECK
1842 PRINTK(
"\n---------------------------------------------\n");
1843 PRINTK(
" dump mem tmpNode:%#x ~ %#x\n", tmpNode, ((
UINTPTR)tmpNode + OS_MEM_NODE_DUMP_SIZE));
1845 PRINTK(
"\n---------------------------------------------\n");
1846 if (preNode != tmpNode) {
1847 PRINTK(
" dump mem :%#x ~ tmpNode:%#x\n", ((
UINTPTR)tmpNode - OS_MEM_NODE_DUMP_SIZE), tmpNode);
1849 PRINTK(
"\n---------------------------------------------\n");
1860#if OS_MEM_FREE_BY_TASKID
1862 if (OS_MEM_NODE_GET_USED_FLAG(preNode->
sizeAndFlag)) {
1865 if (OS_TID_CHECK_INVALID(
taskID)) {
1866 MEM_UNLOCK(pool, intSave);
1871 taskCB = OS_TCB_FROM_TID(
taskID);
1873 MEM_UNLOCK(pool, intSave);
1878 PRINTK(
"The prev node is free\n");
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);
1884 MEM_UNLOCK(pool, intSave);
1885 LOS_Panic(
"Memory integrity check error, cur node: %#x, pre node: %#x\n", tmpNode, preNode);
1889#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK
1914 MEM_LOCK(poolHead, intSave);
1918 MEM_UNLOCK(poolHead, intSave);
1929 UINT32 totalUsedSize = 0;
1930 UINT32 totalFreeSize = 0;
1936 if (!OS_MEM_NODE_GET_USED_FLAG(node->
sizeAndFlag)) {
1939 totalFreeSize += size;
1940 if (maxFreeSize < size) {
1946 totalUsedSize += size;
1969 if (poolStatus == NULL) {
1970 PRINT_ERR(
"can't use NULL addr to save info\n");
1974 if ((pool == NULL) || (poolInfo->
info.
pool != pool)) {
1975 PRINT_ERR(
"wrong mem pool addr: %#x, line:%d\n", poolInfo, __LINE__);
1985 MEM_LOCK(poolInfo, intSave);
1987#if OS_MEM_EXPAND_ENABLE
1989 for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode; tmpNode = OS_MEM_NEXT_NODE(tmpNode)) {
1990 if (tmpNode == endNode) {
1994 size = OS_MEM_NODE_GET_SIZE(endNode->
sizeAndFlag);
1996 endNode = OS_MEM_END_NODE(tmpNode, size);
2006 for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode; tmpNode = OS_MEM_NEXT_NODE(tmpNode)) {
2010#ifdef LOSCFG_MEM_WATERLINE
2013 MEM_UNLOCK(poolInfo, intSave);
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",
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",
2053 PRINT_ERR(
"wrong mem pool addr: %#x, line:%d\n", poolInfo, __LINE__);
2058 UINT32 countNum[OS_MEM_FREE_LIST_COUNT] = {0};
2062 MEM_LOCK(poolInfo, intSave);
2063 for (index = 0; index < OS_MEM_FREE_LIST_COUNT; index++) {
2070 MEM_UNLOCK(poolInfo, intSave);
2072 PRINTK(
"\n ************************ left free node number**********************\n");
2073 for (index = 0; index < OS_MEM_FREE_LIST_COUNT; index++) {
2074 if (countNum[index] == 0) {
2078 PRINTK(
"free index: %03u, ", index);
2079 if (index < OS_MEM_SMALL_BUCKET_COUNT) {
2080 PRINTK(
"size: [%#x], num: %u\n", (index + 1) << 2, countNum[index]);
2082 UINT32 val = 1 << (((index - OS_MEM_SMALL_BUCKET_COUNT) >> OS_MEM_SLI) + OS_MEM_LARGE_START_BUCKET);
2083 UINT32 offset = val >> OS_MEM_SLI;
2084 PRINTK(
"size: [%#x, %#x], num: %u\n",
2085 (offset * ((index - OS_MEM_SMALL_BUCKET_COUNT) % (1 << OS_MEM_SLI))) + val,
2086 ((offset * (((index - OS_MEM_SMALL_BUCKET_COUNT) % (1 << OS_MEM_SLI)) + 1)) + val - 1),
2090 PRINTK(
"\n ********************************************************************\n\n");
2109 PRINT_ERR(
"vmm_kheap_init boot_alloc_mem failed! %d\n", size);
2115 if (ret != LOS_OK) {
2116 PRINT_ERR(
"vmm_kheap_init LOS_MemInit failed!\n");
2120#if OS_MEM_EXPAND_ENABLE
2132 if (OS_MEM_MIDDLE_ADDR(firstNode,
ptr, endNode)) {
2136#if OS_MEM_EXPAND_ENABLE
2139 MEM_LOCK(pool, intSave);
2141 size = OS_MEM_NODE_GET_SIZE(endNode->
sizeAndFlag);
2143 endNode = OS_MEM_END_NODE(firstNode, size);
2144 if (OS_MEM_MIDDLE_ADDR(firstNode,
ptr, endNode)) {
2145 MEM_UNLOCK(pool, intSave);
2149 MEM_UNLOCK(pool, intSave);
LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
Align the value (addr) by some bytes (boundary) you specify.
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 recordCount, UINT32 jumpCount)
record LR function.
NORETURN VOID LOS_Panic(const CHAR *fmt,...)
Kernel panic function.
UINT32 LOS_MemPoolList(VOID)
打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
UINT8 * m_aucSysMem1
系统动态内存池地址的起始地址 @note_thinking 能否不要用 0,1来命名核心变量 ???
VOID * LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size)
按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块
UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus)
LOS_MemInfoGet 获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小
VOID * LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
从指定内存池中申请size长度的内存且地址按boundary字节对齐的内存
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
UINT32 LOS_MemFreeNodeShow(VOID *pool)
打印指定内存池的空闲内存块的大小及数量
UINT32 LOS_MemPoolSizeGet(const VOID *pool)
获取指定动态内存池的总大小
VOID LOS_MemExpandEnable(VOID *pool)
Enable memory pool to support dynamic expansion.
UINT32 LOS_MemTotalUsedGet(VOID *pool)
获取指定动态内存池的总使用量大小
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
UINT32 LOS_MemDeInit(VOID *pool)
删除指定内存池
UINT32 LOS_MemInit(VOID *pool, UINT32 size)
LOS_MemInit 初始化一块指定的动态内存池,大小为size 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。
UINT32 LOS_MemIntegrityCheck(const VOID *pool)
对指定内存池做完整性检查
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
Obtain current running task ID.
void * memset(void *addr, int c, size_t len)
VOID LOS_LmsCheckPoolDel(const VOID *pool)
UINT32 LOS_MemFreeByTaskID(VOID *pool, UINT32 taskID)
STATIC INLINE VOID OsMemLinkRegisterRecord(struct OsMemNodeHead *node)
STATIC INLINE UINT32 OsMemFreeListIndexGet(UINT32 size)
BOOL OsMemIsHeapNode(const VOID *ptr)
STATIC INLINE VOID OsLmsFirstNodeMark(VOID *pool, struct OsMemNodeHead *node)
STATIC INLINE VOID OsLmsReallocSplitNodeMark(struct OsMemNodeHead *node)
STATIC INLINE struct OsMemFreeNodeHead * OsMemFindCurSuitableBlock(struct OsMemPoolHead *poolHead, UINT32 index, UINT32 size)
STATIC INLINE struct OsMemFreeNodeHead * OsMemFindNextSuitableBlock(VOID *pool, UINT32 size, UINT32 *outIndex)
找到下一个合适的块
STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size)
STATIC UINT32 OsMemPoolDelete(VOID *pool)
删除内存池
STATIC VOID OsMemPoolHeadCheck(const struct OsMemPoolHead *pool)
STATIC INLINE VOID OsMemSetFreeListBit(struct OsMemPoolHead *head, UINT32 index)
VOID OsMemUsedNodeShow(VOID *pool)
打印已使用的节点
STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNodeHead *node, LOS_MEM_POOL_STATUS *poolStatus)
STATIC INLINE INT32 OsMemPoolExpandSub(VOID *pool, UINT32 size, UINT32 intSave)
内存池扩展实现
STATIC INLINE UINT16 OsMemFLS(UINT32 bitmap)
STATIC INLINE VOID OsMemMergeNode(struct OsMemNodeHead *node)
合并节点,和前面的节点合并 node 消失
STATIC INLINE UINT32 OsMemFlGet(UINT32 size)
STATIC UINT32 OsMemCheckUsedNode(const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node)
STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const VOID *addr)
内存池有效性检查
STATIC VOID OsMemNodeInfo(const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode)
STATIC INLINE VOID OsMemSentinelNodeSet(struct OsMemNodeHead *sentinelNode, VOID *newNode, UINT32 size)
设置哨兵节点内容
STATIC INLINE VOID OsMemClearFreeListBit(struct OsMemPoolHead *head, UINT32 index)
STATIC INLINE VOID OsMemSplitNode(VOID *pool, struct OsMemNodeHead *allocNode, UINT32 allocSize)
切割节点
STATIC INLINE VOID * OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave)
从指定动态内存池中申请size长度的内存
STATIC INLINE struct OsMemNodeHead * OsMemFreeNodeGet(VOID *pool, UINT32 size)
STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode)
STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size)
OsMemPoolInit 内存池初始化 内存池节点部分包含3种类型节点:未使用空闲内存节点(OsMemFreeNodeHead),已使用内存节点(OsMemUsedNodeHead) 和 尾节点(Os...
STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node)
释放内存
STATIC INLINE VOID OsMemReAllocSmaller(VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize)
STATIC UINT32 OsMemAddrValidCheckPrint(const VOID *pool, struct OsMemFreeNodeHead **tmpNode)
STATIC INLINE VOID OsMemMagicCheckPrint(struct OsMemNodeHead **tmpNode)
STATIC INLINE UINT16 OsMemFFS(UINT32 bitmap)
STATIC INLINE BOOL TryShrinkPool(const VOID *pool, const struct OsMemNodeHead *node)
STATIC INLINE BOOL OsMemIsNodeValid(const struct OsMemNodeHead *node, const struct OsMemNodeHead *startNode, const struct OsMemNodeHead *endNode, const struct OsMemPoolHead *poolInfo)
STATIC UINT32 OsMemIntegrityCheck(const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, struct OsMemNodeHead **preNode)
STATIC INLINE BOOL OsMemSentinelNodeCheck(struct OsMemNodeHead *sentinelNode)
检查哨兵节点
STATIC INLINE VOID OsMemFreeNodeDelete(VOID *pool, struct OsMemFreeNodeHead *node)
从空闲链表上摘除节点
STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node)
从空闲链表中删除
STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID *pool, const struct OsMemNodeHead *endNode)
STATUS_T OsKHeapInit(size_t size)
内核空间动态内存(堆内存)初始化 , 争取系统动态内存池
STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node)
添加一个空闲节点
STATIC INLINE VOID * OsMemCreateUsedNode(VOID *addr)
STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node)
STATIC INLINE UINT32 OsMemNotEmptyIndexGet(struct OsMemPoolHead *poolHead, UINT32 index)
STATIC INLINE INT32 OsMemPoolExpand(VOID *pool, UINT32 allocSize, UINT32 intSave)
扩展内存池
STATIC INLINE UINT32 OsMemLog2(UINT32 size)
STATIC INLINE struct OsMemNodeHead * PreSentinelNodeGet(const VOID *pool, const struct OsMemNodeHead *node)
STATIC VOID OsMemIntegrityCheckError(struct OsMemPoolHead *pool, const struct OsMemNodeHead *tmpNode, const struct OsMemNodeHead *preNode, UINT32 intSave)
STATIC INLINE VOID * OsGetRealPtr(const VOID *pool, VOID *ptr)
STATIC INLINE struct OsMemNodeHead * OsMemLastSentinelNodeGet(const struct OsMemNodeHead *sentinelNode)
更新哨兵节点内容
STATIC INLINE VOID OsMemMergeNodeForReAllocBigger(VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize, struct OsMemNodeHead *nextNode)
STATIC INLINE BOOL OsMemIsLastSentinelNode(struct OsMemNodeHead *sentinelNode)
是否为最后一个哨兵节点
STATIC UINT32 OsMemFreeListNodeCheck(const struct OsMemPoolHead *pool, const struct OsMemFreeNodeHead *node)
UINT32 OsMemLargeNodeFree(const VOID *ptr)
大内存释放
STATIC BOOL MemCheckUsedNode(const struct OsMemPoolHead *pool, const struct OsMemNodeHead *node, const struct OsMemNodeHead *startNode, const struct OsMemNodeHead *endNode)
STATIC INLINE VOID OsLmsReallocResizeMark(struct OsMemNodeHead *node, UINT32 resize)
STATIC VOID OsMemPoolDeinit(VOID *pool)
STATIC INLINE UINT32 OsMemSlGet(UINT32 size, UINT32 fl)
STATIC INLINE VOID * OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, struct OsMemNodeHead *node, UINT32 size, UINT32 intSave)
STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave)
STATIC INLINE VOID OsMemNodeSetTaskID(struct OsMemUsedNodeHead *node)
STATIC INLINE VOID OsLmsAllocAlignMark(VOID *ptr, VOID *alignedPtr, UINT32 size)
STATIC INLINE VOID * OsMemSentinelNodeGet(struct OsMemNodeHead *node)
STATIC INLINE VOID OsMemListAdd(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node)
STATIC VOID OsMemInfoPrint(VOID *pool)
STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size)
新增内存池
STATIC INLINE VOID OsLmsReallocMergeNodeMark(struct OsMemNodeHead *node)
VOID OsDumpMemByte(size_t length, UINTPTR addr)
VOID LOS_SpinInit(SPIN_LOCK_S *lock)
STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
任务是否在使用
VOID * OsVmBootMemAlloc(size_t len)
UINTPTR g_vmBootMemBase
虚拟内存区间检查, 需理解 los_vm_zone.h 中画出的鸿蒙虚拟内存全景图
int OsTryShrinkMemory(size_t nPage)
VOID * LOS_PhysPagesAllocContiguous(size_t nPages)
分配连续的物理页
VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
释放指定页数地址连续的物理内存
LosVmPage * OsVmVaddrToPage(VOID *ptr)
通过虚拟地址找映射的物理页框
VOID(* simpleMark)(UINTPTR startAddr, UINTPTR endAddr, UINT32 value)
UINT32(* init)(const VOID *pool, UINT32 size)
VOID(* mallocMark)(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize)
VOID(* check)(UINTPTR checkAddr, BOOL isFreeCheck)
VOID(* freeMark)(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize)
struct OsMemFreeNodeHead * next
后一个空闲后继节点
struct OsMemFreeNodeHead * prev
前一个空闲前驱节点
struct OsMemNodeHead header
内存池节点
struct OsMemNodeHead * prev
union OsMemNodeHead::@5 ptr
UINT32 sizeAndFlag
节点总大小+标签
struct OsMemNodeHead * next
UINTPTR linkReg[LOS_RECORD_LR_CNT]
存放左右节点地址,用于检测
UINT32 magic
魔法数字 0xABCDDCBA
struct OsMemFreeNodeHead * freeList[OS_MEM_FREE_LIST_COUNT]
空闲节点链表 32 + 24 * 8 = 224
struct OsMemPoolInfo info
记录内存池的信息
VOID * nextPool
指向下一个内存池 OsMemPoolHead 类型
SPIN_LOCK_S spinlock
操作本池的自旋锁,涉及CPU多核竞争,所以必须得是自旋锁
UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]
空闲位图 int[7] = 32 * 7 = 224 > 223
UINT32 totalSize
总大小,确定了内存池的边界
VOID * pool
指向内存块基地址,仅做记录而已,真正的分配内存跟它没啥关系
UINT32 attr
属性 default attr: lock, not expand.
struct OsMemNodeHead header
已被使用节点
CHAR taskName[OS_TCB_NAME_LEN]
物理页框描述符 虚拟内存体现的是程序对内存资源的需求,而物理内存是对该请求的供应。 伙伴算法的思想是:把内存中连续的空闲页框空间看成是空闲页框块,并按照它们的大小(连续页框的数目)分组