feat: support non-continuous memory regions

The multiple non-continuous memory regions are supported when the macro
LOSCFG_MEM_MUL_REGIONS is enabled. The array of the type LOS_MEM_REGION should be defined,
and each array element defines the start address and the length for each memory regions, \
begining from the lower address to the higher memory address.

close #I43XOP

Signed-off-by: kenneth <zhushangyuan@huawei.com>
This commit is contained in:
kenneth 2021-08-04 22:12:56 +08:00
parent 870cf67c51
commit 0facb0c017
7 changed files with 410 additions and 8 deletions

View File

@ -538,6 +538,14 @@ extern UINT8 *m_aucSysMem0;
#define OS_SYS_NOCACHEMEM_ADDR (&g_sysNoCacheMem0[0]) #define OS_SYS_NOCACHEMEM_ADDR (&g_sysNoCacheMem0[0])
#endif #endif
/**
* @ingroup los_config
* Configuration of multiple non-continuous memory regions as one memory pool
*/
#ifndef LOSCFG_MEM_MUL_REGIONS
#define LOSCFG_MEM_MUL_REGIONS 0
#endif
/* ============================================================================= /* =============================================================================
Exception module configuration Exception module configuration
============================================================================= */ ============================================================================= */

View File

@ -120,6 +120,47 @@ extern UINT32 LOS_MemDeInit(VOID *pool);
extern UINT32 LOS_MemPoolList(VOID); extern UINT32 LOS_MemPoolList(VOID);
#endif #endif
#if (LOSCFG_MEM_MUL_REGIONS == 1)
typedef struct {
VOID *startAddress;
UINT32 length;
} LosMemRegion;
/**
* @ingroup los_memory
* @brief Initialize multiple non-continuous memory regions.
*
* @par Description:
* <ul>
* <li>This API is used to initialize multiple non-continuous memory regions. If the starting address of a pool is specified,
* the memory regions will be linked to the pool as free nodes. Otherwise, the first memory region will be initialized as a
* new pool, and the rest regions will be linked as free nodes to the new pool.</li>
* </ul>
*
* @attention
* <ul>
* <li>If the starting address of a memory pool is specified, the start address of the non-continuous memory regions should be
* greater than the end address of the memory pool.</li>
* <li>The multiple non-continuous memory regions shouldn't conflict with each other.</li>
* </ul>
*
* @param pool [IN] The memory pool address. If NULL is specified, the start address of first memory region will be
* initialized as the memory pool address. If not NULL, it should be a valid address of a memory pool.
* @param memRegions [IN] The LosMemRegion array that contains multiple non-continuous memory regions. The start address
* of the memory regions are placed in ascending order.
* @param memRegionCount [IN] The count of non-continuous memory regions, and it should be the length of the LosMemRegion array.
*
* @retval #LOS_NOK The multiple non-continuous memory regions fails to be initialized.
* @retval #LOS_OK The multiple non-continuous memory regions is initialized successfully.
* @par Dependency:
* <ul>
* <li>los_memory.h: the header file that contains the API declaration.</li>
* </ul>
* @see None.
*/
extern UINT32 LOS_MemRegionsAdd(VOID *pool, const LosMemRegion * const memRegions, UINT32 memRegionCount);
#endif
/** /**
* @ingroup los_memory * @ingroup los_memory
* Memory pool extern information structure * Memory pool extern information structure

View File

@ -149,6 +149,9 @@ struct OsMemPoolInfo {
UINT32 waterLine; /* Maximum usage size in a memory pool */ UINT32 waterLine; /* Maximum usage size in a memory pool */
UINT32 curUsedSize; /* Current usage size in a memory pool */ UINT32 curUsedSize; /* Current usage size in a memory pool */
#endif #endif
#if (LOSCFG_MEM_MUL_REGIONS == 1)
UINT32 totalGapSize;
#endif
}; };
struct OsMemPoolHead { struct OsMemPoolHead {
@ -269,6 +272,20 @@ STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave)
#define OS_MEM_MAGIC_VALID(node) TRUE #define OS_MEM_MAGIC_VALID(node) TRUE
#endif #endif
#if (LOSCFG_MEM_MUL_REGIONS == 1)
/**
* When LOSCFG_MEM_MUL_REGIONS is enabled to support multiple non-continuous memory regions, the gap between two memory regions
* is marked as a used OsMemNodeHead node. The gap node couldn't be freed, and would also be skipped in some DFX functions. The
* 'ptr.prev' pointer of this node is set to OS_MEM_GAP_NODE_MAGIC to identify that this is a gap node.
*/
#define OS_MEM_GAP_NODE_MAGIC 0xDCBAABCD
#define OS_MEM_MARK_GAP_NODE(node) (((struct OsMemNodeHead *)(node))->ptr.prev = (struct OsMemNodeHead *)OS_MEM_GAP_NODE_MAGIC)
#define OS_MEM_IS_GAP_NODE(node) (((struct OsMemNodeHead *)(node))->ptr.prev == (struct OsMemNodeHead *)OS_MEM_GAP_NODE_MAGIC)
#else
#define OS_MEM_MARK_GAP_NODE(node)
#define OS_MEM_IS_GAP_NODE(node) FALSE
#endif
STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node); STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node);
STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node); STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node);
STATIC VOID OsMemInfoPrint(VOID *pool); STATIC VOID OsMemInfoPrint(VOID *pool);
@ -507,8 +524,8 @@ STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node)
{ {
UINT32 count; UINT32 count;
if (OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { if (OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag) && !OS_MEM_IS_GAP_NODE(node)) {
PRINTK("0x%x: 0x%x ", node, OS_MEM_NODE_GET_SIZE(node->sizeAndFlag)); PRINTK("0x%x: 0x%x ", (UINTPTR)node, OS_MEM_NODE_GET_SIZE(node->sizeAndFlag));
for (count = 0; count < LOSCFG_MEM_RECORD_LR_CNT; count++) { for (count = 0; count < LOSCFG_MEM_RECORD_LR_CNT; count++) {
PRINTK(" 0x%x ", node->linkReg[count]); PRINTK(" 0x%x ", node->linkReg[count]);
} }
@ -744,7 +761,7 @@ STATIC INLINE VOID OsMemMergeNode(struct OsMemNodeHead *node)
node->ptr.prev->sizeAndFlag += node->sizeAndFlag; node->ptr.prev->sizeAndFlag += node->sizeAndFlag;
nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag); nextNode = (struct OsMemNodeHead *)((UINTPTR)node + node->sizeAndFlag);
if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag) && !OS_MEM_IS_GAP_NODE(nextNode)) {
nextNode->ptr.prev = node->ptr.prev; nextNode->ptr.prev = node->ptr.prev;
} }
} }
@ -759,7 +776,7 @@ STATIC INLINE VOID OsMemSplitNode(VOID *pool, struct OsMemNodeHead *allocNode, U
newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize; newFreeNode->header.sizeAndFlag = allocNode->sizeAndFlag - allocSize;
allocNode->sizeAndFlag = allocSize; allocNode->sizeAndFlag = allocSize;
nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header); nextNode = OS_MEM_NEXT_NODE(&newFreeNode->header);
if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag) && !OS_MEM_IS_GAP_NODE(nextNode)) {
nextNode->ptr.prev = &newFreeNode->header; nextNode->ptr.prev = &newFreeNode->header;
if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) {
OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);
@ -1127,6 +1144,10 @@ STATIC UINT32 OsMemCheckUsedNode(const struct OsMemPoolHead *pool, const struct
do { do {
do { do {
if (OS_MEM_IS_GAP_NODE(node)) {
break;
}
if (!OsMemIsNodeValid(node, startNode, endNode, pool)) { if (!OsMemIsNodeValid(node, startNode, endNode, pool)) {
break; break;
} }
@ -1140,7 +1161,7 @@ STATIC UINT32 OsMemCheckUsedNode(const struct OsMemPoolHead *pool, const struct
break; break;
} }
if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag)) { if (!OS_MEM_NODE_GET_LAST_FLAG(nextNode->sizeAndFlag) && !OS_MEM_IS_GAP_NODE(nextNode)) {
if (nextNode->ptr.prev != node) { if (nextNode->ptr.prev != node) {
break; break;
} }
@ -1422,6 +1443,9 @@ UINT32 LOS_MemPoolSizeGet(const VOID *pool)
} }
count += ((struct OsMemPoolHead *)pool)->info.totalSize; count += ((struct OsMemPoolHead *)pool)->info.totalSize;
#if (LOSCFG_MEM_MUL_REGIONS == 1)
count -= ((struct OsMemPoolHead *)pool)->info.totalGapSize;
#endif
#if OS_MEM_EXPAND_ENABLE #if OS_MEM_EXPAND_ENABLE
UINT32 size; UINT32 size;
@ -1474,7 +1498,9 @@ UINT32 LOS_MemTotalUsedGet(VOID *pool)
} }
#else #else
for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode;) { for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode;) {
if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { if (OS_MEM_IS_GAP_NODE(tmpNode)) {
memUsed += OS_MEM_NODE_HEAD_SIZE;
} else if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) {
memUsed += OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag); memUsed += OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag);
} }
tmpNode = OS_MEM_NEXT_NODE(tmpNode); tmpNode = OS_MEM_NEXT_NODE(tmpNode);
@ -1606,6 +1632,9 @@ STATIC UINT32 OsMemIntegrityCheck(const struct OsMemPoolHead *pool, struct OsMem
*preNode = OS_MEM_FIRST_NODE(pool); *preNode = OS_MEM_FIRST_NODE(pool);
do { do {
for (*tmpNode = *preNode; *tmpNode < endNode; *tmpNode = OS_MEM_NEXT_NODE(*tmpNode)) { for (*tmpNode = *preNode; *tmpNode < endNode; *tmpNode = OS_MEM_NEXT_NODE(*tmpNode)) {
if (OS_MEM_IS_GAP_NODE(*tmpNode)) {
continue;
}
if (OsMemIntegrityCheckSub(tmpNode, pool, endNode) == LOS_NOK) { if (OsMemIntegrityCheckSub(tmpNode, pool, endNode) == LOS_NOK) {
return LOS_NOK; return LOS_NOK;
} }
@ -1803,7 +1832,11 @@ STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNode
maxFreeSize = size; maxFreeSize = size;
} }
} else { } else {
size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); if (OS_MEM_IS_GAP_NODE(node)) {
size = OS_MEM_NODE_HEAD_SIZE;
} else {
size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);
}
++usedNodeNum; ++usedNodeNum;
totalUsedSize += size; totalUsedSize += size;
} }
@ -1894,7 +1927,7 @@ STATIC VOID OsMemInfoPrint(VOID *pool)
PRINTK("--------------- -------- ------- -------- " PRINTK("--------------- -------- ------- -------- "
"-------------- ------------- ------------\n"); "-------------- ------------- ------------\n");
PRINTK("%-16p 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x\n", PRINTK("%-16p 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x\n",
(UINTPTR)poolInfo->info.pool, LOS_MemPoolSizeGet(pool), status.totalUsedSize, poolInfo->info.pool, LOS_MemPoolSizeGet(pool), status.totalUsedSize,
status.totalFreeSize, status.maxFreeNodeSize, status.usedNodeNum, status.totalFreeSize, status.maxFreeNodeSize, status.usedNodeNum,
status.freeNodeNum); status.freeNodeNum);
#endif #endif
@ -1956,6 +1989,149 @@ VOID LOS_MemUnlockEnable(VOID *pool)
((struct OsMemPoolHead *)pool)->info.attr |= OS_MEM_POOL_UNLOCK_ENABLE; ((struct OsMemPoolHead *)pool)->info.attr |= OS_MEM_POOL_UNLOCK_ENABLE;
} }
#if (LOSCFG_MEM_MUL_REGIONS == 1)
STATIC INLINE UINT32 OsMemMulRegionsParamCheck(VOID *pool, const LosMemRegion * const memRegions, UINT32 memRegionCount)
{
const LosMemRegion *memRegion = NULL;
VOID *lastStartAddress = NULL;
VOID *curStartAddress = NULL;
UINT32 lastLength;
UINT32 curLength;
UINT32 regionCount;
if ((pool != NULL) && (((struct OsMemPoolHead *)pool)->info.pool != pool)) {
PRINT_ERR("wrong mem pool addr: %p, func: %s, line: %d\n", pool, __FUNCTION__, __LINE__);
return LOS_NOK;
}
if (pool != NULL) {
lastStartAddress = pool;
lastLength = ((struct OsMemPoolHead *)pool)->info.totalSize;
}
memRegion = memRegions;
regionCount = 0;
while (regionCount < memRegionCount) {
curStartAddress = memRegion->startAddress;
curLength = memRegion->length;
if ((curStartAddress == NULL) || (curLength == 0)) {
PRINT_ERR("Memory address or length configured wrongly:address:0x%x, the length:0x%x\n", (UINTPTR)curStartAddress, curLength);
return LOS_NOK;
}
if (((UINTPTR)curStartAddress & (OS_MEM_ALIGN_SIZE - 1)) || (curLength & (OS_MEM_ALIGN_SIZE - 1))) {
PRINT_ERR("Memory address or length configured not aligned:address:0x%x, the length:0x%x, alignsize:%d\n", \
(UINTPTR)curStartAddress, curLength, OS_MEM_ALIGN_SIZE);
return LOS_NOK;
}
if ((lastStartAddress != NULL) && (((UINT8 *)lastStartAddress + lastLength) >= (UINT8 *)curStartAddress)) {
PRINT_ERR("Memory regions overlapped, the last start address:0x%x, the length:0x%x, the current start address:0x%x\n", \
(UINTPTR)lastStartAddress, lastLength, (UINTPTR)curStartAddress);
return LOS_NOK;
}
memRegion++;
regionCount++;
lastStartAddress = curStartAddress;
lastLength = curLength;
}
return LOS_OK;
}
STATIC INLINE VOID OsMemMulRegionsLink(struct OsMemPoolHead *poolHead, VOID *lastStartAddress, UINT32 lastLength, struct OsMemNodeHead *lastEndNode, const LosMemRegion *memRegion)
{
UINT32 curLength;
UINT32 gapSize;
struct OsMemNodeHead *curEndNode = NULL;
struct OsMemNodeHead *curFreeNode = NULL;
VOID *curStartAddress = NULL;
curStartAddress = memRegion->startAddress;
curLength = memRegion->length;
// mark the gap between two regions as one used node
gapSize = (UINT8 *)(curStartAddress) - ((UINT8 *)(lastStartAddress) + lastLength);
lastEndNode->sizeAndFlag = gapSize + OS_MEM_NODE_HEAD_SIZE;
OS_MEM_SET_MAGIC(lastEndNode);
OS_MEM_NODE_SET_USED_FLAG(lastEndNode->sizeAndFlag);
// mark the gap node with magic number
OS_MEM_MARK_GAP_NODE(lastEndNode);
poolHead->info.totalSize += (curLength + gapSize);
poolHead->info.totalGapSize += gapSize;
curFreeNode = (struct OsMemNodeHead *)curStartAddress;
curFreeNode->sizeAndFlag = curLength - OS_MEM_NODE_HEAD_SIZE;
curFreeNode->ptr.prev = lastEndNode;
OS_MEM_SET_MAGIC(curFreeNode);
OsMemFreeNodeAdd(poolHead, (struct OsMemFreeNodeHead *)curFreeNode);
curEndNode = OS_MEM_END_NODE(curStartAddress, curLength);
curEndNode->sizeAndFlag = 0;
curEndNode->ptr.prev = curFreeNode;
OS_MEM_SET_MAGIC(curEndNode);
OS_MEM_NODE_SET_USED_FLAG(curEndNode->sizeAndFlag);
#if (LOSCFG_MEM_WATERLINE == 1)
poolHead->info.curUsedSize += OS_MEM_NODE_HEAD_SIZE;
poolHead->info.waterLine = poolHead->info.curUsedSize;
#endif
}
UINT32 LOS_MemRegionsAdd(VOID *pool, const LosMemRegion *const memRegions, UINT32 memRegionCount)
{
UINT32 ret;
UINT32 lastLength;
UINT32 curLength;
UINT32 regionCount;
struct OsMemPoolHead *poolHead = NULL;
struct OsMemNodeHead *lastEndNode = NULL;
struct OsMemNodeHead *firstFreeNode = NULL;
const LosMemRegion *memRegion = NULL;
VOID *lastStartAddress = NULL;
VOID *curStartAddress = NULL;
ret = OsMemMulRegionsParamCheck(pool, memRegions, memRegionCount);
if (ret != LOS_OK) {
return ret;
}
memRegion = memRegions;
regionCount = 0;
if (pool != NULL) { // add the memory regions to the specified memory pool
poolHead = (struct OsMemPoolHead *)pool;
lastStartAddress = pool;
lastLength = poolHead->info.totalSize;
} else { // initialize the memory pool with the first memory region
lastStartAddress = memRegion->startAddress;
lastLength = memRegion->length;
poolHead = (struct OsMemPoolHead *)lastStartAddress;
ret = LOS_MemInit(lastStartAddress, lastLength);
if (ret != LOS_OK) {
return ret;
}
memRegion++;
regionCount++;
}
firstFreeNode = OS_MEM_FIRST_NODE(lastStartAddress);
lastEndNode = OS_MEM_END_NODE(lastStartAddress, lastLength);
while (regionCount < memRegionCount) { // traverse the rest memory regions, and initialize them as free nodes and link together
curStartAddress = memRegion->startAddress;
curLength = memRegion->length;
OsMemMulRegionsLink(poolHead, lastStartAddress, lastLength, lastEndNode, memRegion);
lastStartAddress = curStartAddress;
lastLength = curLength;
lastEndNode = OS_MEM_END_NODE(curStartAddress, curLength);
memRegion++;
regionCount++;
}
firstFreeNode->ptr.prev = lastEndNode;
return ret;
}
#endif
UINT32 OsMemSystemInit(VOID) UINT32 OsMemSystemInit(VOID)
{ {
UINT32 ret; UINT32 ret;

View File

@ -55,6 +55,8 @@ static_library("test_mem") {
"It_los_mem_038.c", "It_los_mem_038.c",
"It_los_mem_040.c", "It_los_mem_040.c",
"It_los_mem_045.c", "It_los_mem_045.c",
"It_los_mem_046.c",
"It_los_mem_047.c",
"It_los_tick_001.c", "It_los_tick_001.c",
"it_los_mem.c", "it_los_mem.c",
] ]

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "osTest.h"
#include "It_los_mem.h"
#if (LOSCFG_MEM_MUL_REGIONS == 1)
// simulate two non-continuous memory regions
STATIC UINT8 g_memPool_TC46_01[0x200];
STATIC UINT8 g_memGap_TC46[0x10];
STATIC UINT8 g_memPool_TC46_02[0x400];
static UINT32 TestCase(VOID)
{
UINT32 ret;
void *p = NULL;
LosMemRegion memRegions[] =
{
{g_memPool_TC46_01, 0x200},
{g_memPool_TC46_02, 0x400}
};
// Initialize the LOS_MemRegionsAdd
ret = LOS_MemRegionsAdd(m_aucSysMem0, memRegions, sizeof(memRegions) / sizeof(memRegions[0]));
if (ret != LOS_OK) {
return ret;
}
// p points to the start address of the gap node between g_memPool_TC46_01 and g_memPool_TC46_02
p = g_memPool_TC46_01 + 0x200;
(void)memset_s(g_memGap_TC46, 0x10, 1, 0x10);
ret = LOS_MemFree(m_aucSysMem0, p);
ICUNIT_GOTO_EQUAL(ret, LOS_NOK, ret, EXIT);
EXIT:
return LOS_OK;
}
#else
static UINT32 TestCase(VOID)
{
return LOS_OK;
}
#endif
VOID ItLosMem046(void)
{
TEST_ADD_CASE("ItLosMem046", TestCase, TEST_LOS, TEST_MEM, TEST_LEVEL1, TEST_FUNCTION);
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "osTest.h"
#include "It_los_mem.h"
#if (LOSCFG_MEM_MUL_REGIONS == 1)
// simulate two non-continuous memory regions
STATIC UINT8 g_memGap_TC47_Gap1[0x10];
STATIC UINT8 g_memPool_TC47_01[0x1000];
STATIC UINT8 g_memGap_TC47_Gap2[0x10];
STATIC UINT8 g_memPool_TC47_02[0x400];
static UINT32 TestCase(VOID)
{
UINT32 ret;
UINT32 size;
void *p = NULL;
LosMemRegion memRegions[] =
{
{g_memPool_TC47_01, 0x1000},
{g_memPool_TC47_02, 0x400}
};
// Initialize the LOS_MemRegionsAdd
ret = LOS_MemRegionsAdd(NULL, memRegions, sizeof(memRegions) / sizeof(memRegions[0]));
if (ret != LOS_OK) {
return ret;
}
// p points to the start address of the gap node between g_memPool_TC47_01 and g_memPool_TC47_02
p = g_memPool_TC47_01 + 0x1000;
ret = LOS_MemFree((void *)&g_memPool_TC47_01, p);
ICUNIT_ASSERT_EQUAL(ret, LOS_NOK, ret);
size = 0x100;
p = LOS_MemAlloc((void *)&g_memPool_TC47_01, size);
ICUNIT_ASSERT_NOT_EQUAL(p, NULL, 0);
(void)memset_s(p, size, 1, size);
(void)memset_s(g_memGap_TC47_Gap1, 0x10, 1, 0x10);
(void)memset_s(g_memGap_TC47_Gap2, 0x10, 1, 0x10);
ret = LOS_MemFree((void *)&g_memPool_TC47_01, p);
ICUNIT_ASSERT_EQUAL(ret, LOS_OK, 0);
return LOS_OK;
}
#else
static UINT32 TestCase(VOID)
{
return LOS_OK;
}
#endif
VOID ItLosMem047(void)
{
TEST_ADD_CASE("ItLosMem047", TestCase, TEST_LOS, TEST_MEM, TEST_LEVEL1, TEST_FUNCTION);
}

View File

@ -104,6 +104,10 @@ VOID ItSuiteLosMem(void)
#endif #endif
ItLosMem040(); ItLosMem040();
ItLosMem045(); ItLosMem045();
#if (LOSCFG_MEM_MUL_REGIONS == 1)
ItLosMem046();
ItLosMem047();
#endif
#if (LOS_KERNEL_TEST_FULL == 1) #if (LOS_KERNEL_TEST_FULL == 1)
ItLosTick001(); ItLosTick001();