app_mem.c
来自「最新MTK手机软件源码」· C语言 代码 · 共 1,684 行 · 第 1/5 页
C
1,684 行
#endif /* APPLIB_MEM_USE_ADM */
}
/*****************************************************************************
* FUNCTION
* applib_mem_screen_get_max_alloc_size
* DESCRIPTION
* Get the max possible size of single allocation of screen-based ASM.
* Return value of it is typically less than applib_mem_screen_get_total_left_size()
* if the pool is fragmented.
*
* Remark: we can use this function to dynamically decide the allocation size
* (for example, use larger image cache when there is more memory)
*
* However, sometimes we cannot allocate 2 * 10KB blocks if the maximum allocation size
* is 20KB because of overheads of memory management bookkeeping.
*
* It is suggested to use "fail-safe" allocation regardless the internal
* implementation of ASM if we want to allocate more memory adaptively according to
* the free space.
* Step 1. Decide the size of free space => e.g. 100KB
* Step 2. Allocate 100KB
* Step 3. If failed, allocate 95 KB
* Step 4. If failed, allocate 90 KB
* Step 5. ...
*
* This function can be used in non-MMI task.
* PARAMETERS
* void
* RETURNS
* Maximum allocation size in byte
*****************************************************************************/
kal_uint32 applib_mem_screen_get_max_alloc_size(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
#ifdef APPLIB_MEM_USE_ADM
return kal_adm_get_max_alloc_size(g_applib_mem_cntx.screen_pool_id) -
sizeof(applib_mem_header_struct) - sizeof(applib_mem_footer_struct);
#else /* APPLIB_MEM_USE_ADM */
return (10 * 1024 * 1024); /* Return dummy value */
#endif /* APPLIB_MEM_USE_ADM */
}
/*****************************************************************************
* FUNCTION
* applib_mem_screen_get_pool_size
* DESCRIPTION
* Return the fixed size of screen-based ASM pool
*
* Remark: we can use this function to decide the maximum possible memory
* we can allocate (the whole pool size)
*
* However, we still cannot allocate 10 * 10KB blocks in an 100KB memory pool
* because of the overheads of memory management bookkeeping.
*
* It is suggested to use "fail-safe" allocation regardless the internal
* implementation of ASM if we want to allocate more memory adaptively
* according to the pool size:
* Step 1. Decide pool size => e.g. 100KB
* Step 2. Allocate 100KB
* Step 3. If failed, allocate 95 KB
* Step 4. If failed, allocate 90 KB
* Step 5. ...
*
* This function can be used in non-MMI task.
* PARAMETERS
* void
* RETURNS
* Pool size in byte
*****************************************************************************/
kal_uint32 applib_mem_screen_get_pool_size(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
return g_applib_mem_cntx.screen_pool_size -
APPLIB_MEM_POOL_EXTRA_SIZE - APPLIB_MEM_CHUNK_EXTRA_SIZE;
}
/*****************************************************************************
* FUNCTION
* applib_mem_screen_get_alloc_count
* DESCRIPTION
* Return the number of allocated blocks
*
* This function can be used in non-MMI task.
* PARAMETERS
* void
* RETURNS
* The number of allocated blocks
*****************************************************************************/
kal_uint32 applib_mem_screen_get_alloc_count(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
return g_applib_mem_cntx.screen_alloc_count;
}
/*****************************************************************************
* FUNCTION
* applib_mem_screen_is_valid_block
* DESCRIPTION
* Check if a screen-based ASM memory block is valid by
* 1. Inspecting its guard patterns
* 2. Checking if it belongs to the current MMI screen.
*
* This function can be used in non-MMI task.
* PARAMETERS
* mem_ptr [IN] Memory block to check
* RETURNS
* Return KAL_TRUE if 'mem_ptr' is a valid block
*****************************************************************************/
kal_bool applib_mem_screen_is_valid_block(void *mem_ptr)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
applib_mem_header_struct *header;
applib_mem_footer_struct *footer;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (!mem_ptr || !APPLIB_MEM_ALIGNED_4(mem_ptr))
{
return KAL_FALSE;
}
header = ((applib_mem_header_struct*) mem_ptr) - 1;
footer = (applib_mem_footer_struct*) (((char*)mem_ptr) + header->chunk_size);
if (APPLIB_MEM_COMP_PATTERN(header->guard_pattern, APPLIB_MEM_HEADER_PATTERN1) &&
APPLIB_MEM_COMP_PATTERN(footer->guard_pattern, APPLIB_MEM_FOOTER_PATTERN1) &&
header->owner_id == g_applib_mem_cntx.screen_id_callback())
{
return KAL_TRUE;
}
else
{
return KAL_FALSE;
}
}
/*****************************************************************************
* FUNCTION
* applib_mem_screen_check_integrity
* DESCRIPTION
* Check if the internal state of screen-based ASM is correct.
* If not, then ASSERT!
*
* Remark: This function takes a lot of computation time, and it should not be
* used in normal case.
* The function call can be inserted in application code when we need to locate
* hard-to-find memory corruption issue.
*
* This function can be used in non-MMI task.
* PARAMETERS
* void
* RETURNS
* void
*****************************************************************************/
void applib_mem_screen_check_integrity(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
applib_mem_header_struct *node;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
node = g_applib_mem_cntx.screen_head.next;
while (node)
{
ASSERT(applib_mem_screen_is_valid_block(node + 1));
node = node->next;
}
}
/*****************************************************************************
* Unit Test
*****************************************************************************/
#ifdef APPLIB_MEM_UNIT_TEST
#include "stdlib.h"
/*****************************************************************************
* FUNCTION
* applib_mem_screen_simple_test
* DESCRIPTION
* Simple program to test screen-based ASM
* PARAMETERS
* void
* RETURNS
* void
*****************************************************************************/
void applib_mem_screen_simple_test(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_uint32 *ptr_list[100];
kal_int32 i, count, free_space_original, tmp;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
applib_mem_screen_free_all();
free_space_original = applib_mem_screen_get_total_left_size();
#define ALLOC_SIZE(_idx) ((_idx) + (_idx) * 256)
#define PTR_LIST_SIZE (sizeof(ptr_list) / sizeof(void*))
for (i = 0; i < PTR_LIST_SIZE; i++)
{
if ((ptr_list[i] = applib_mem_screen_alloc(ALLOC_SIZE(i))) == NULL)
{
ASSERT(applib_mem_screen_get_max_alloc_size() < ALLOC_SIZE(i));
break;
}
}
count = i;
ASSERT(count > 0);
ASSERT(applib_mem_screen_get_alloc_count() == count);
applib_mem_screen_check_integrity();
tmp = 0;
for (i = 0; i < count; i += 2)
{
tmp += ALLOC_SIZE(i);
applib_mem_screen_free(ptr_list[i]);
}
ASSERT(tmp < free_space_original - applib_mem_screen_get_total_left_size());
applib_mem_screen_check_integrity();
if (count >= 2)
{
for (i = 1; i < count; i += 2)
{
ASSERT(applib_mem_screen_is_valid_block(ptr_list[i]));
}
}
applib_mem_screen_check_integrity();
applib_mem_screen_free_all();
ASSERT(free_space_original == applib_mem_screen_get_total_left_size());
ASSERT(applib_mem_screen_get_alloc_count() == 0);
/* Random alloc/free */
for (i = 0; i < PTR_LIST_SIZE; i++)
{
ptr_list[i] = NULL;
}
for (;;)
{
kal_int32 key = rand();
if ((key % 1000) == 0)
{
break;
}
if (applib_mem_screen_get_alloc_count() == PTR_LIST_SIZE ||
key % 3 == 0)
{
i = ((key + 1) % PTR_LIST_SIZE);
for (; i != key % PTR_LIST_SIZE; i++, i %= PTR_LIST_SIZE)
{
if (ptr_list[i])
{
applib_mem_screen_free(ptr_list[i]);
ptr_list[i] = NULL;
break;
}
}
}
else
{
for (i = 0; i < PTR_LIST_SIZE; i++)
{
if (!ptr_list[i])
{
kal_uint32 size = key % applib_mem_screen_get_pool_size();
ptr_list[i] = applib_mem_screen_alloc(size);
/* Test memory corruption detection */
// ptr_list[i][size/4] = 1;
// ptr_list[i][size/4 + 1] = 1;
// ptr_list[i][size/4 + 2] = 1;
break;
}
}
}
applib_mem_screen_check_integrity();
}
applib_mem_screen_free_all();
ASSERT(free_space_original == applib_mem_screen_get_total_left_size());
ASSERT(applib_mem_screen_get_alloc_count() == 0);
}
#endif /* APPLIB_MEM_UNIT_TEST */
#endif /* !defined(NEPTUNE_MMI) && !defined(MMI_NOT_PRESENT) */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?