app_mem.c
来自「最新MTK手机软件源码」· C语言 代码 · 共 1,684 行 · 第 1/5 页
C
1,684 行
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 < APPLIB_MEM_AP_ID_TOTAL)
{
return KAL_TRUE;
}
else
{
return KAL_FALSE;
}
}
else
{
if (g_applib_mem_cntx.app_alloc_count > 0 &&
mem_ptr == g_applib_mem_ap_pool)
{
return KAL_TRUE;
}
else
{
return KAL_FALSE;
}
}
}
/*****************************************************************************
* FUNCTION
* applib_mem_ap_check_integrity
* DESCRIPTION
* Check if the internal state of app-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_ap_check_integrity(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
applib_mem_header_struct *node;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (g_applib_mem_cntx.app_pool_id)
{
node = g_applib_mem_cntx.app_head.next;
while (node)
{
ASSERT(applib_mem_ap_is_valid_block(node + 1));
node = node->next;
}
}
}
/*****************************************************************************
* Screen-based ASM
*****************************************************************************/
/*****************************************************************************
* FUNCTION
* applib_mem_screen_init
* DESCRIPTION
* Initialize screen-based ASM.
* PARAMETERS
* screen_id_callback [IN] callback handler to get current MMI screen ID
* pool_size [IN] size for screen-based ASM
* pool_ptr [IN] pre-allocated memory pool for screen-based ASM
* RETURNS
* void
*****************************************************************************/
void applib_mem_screen_init(
kal_uint32 (*screen_id_callback)(void),
kal_uint32 pool_size,
void *pool_ptr)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
ASSERT(APPLIB_MEM_ALIGNED_4(pool_ptr));
if (g_applib_mem_cntx.screen_pool_id != 0)
{
/* Already initialized */
return;
}
#ifdef APPLIB_MEM_USE_ADM
g_applib_mem_cntx.screen_pool_id = kal_adm_create(
pool_ptr,
pool_size,
(kal_uint32*) g_applib_mem_pool_chunk_size,
KAL_FALSE);
#else /* APPLIB_MEM_USE_ADM */
g_applib_mem_cntx.screen_pool_id = 0;
#endif /* APPLIB_MEM_USE_ADM */
g_applib_mem_cntx.screen_pool_size = pool_size;
g_applib_mem_cntx.screen_alloc_count = 0;
ASSERT(screen_id_callback != NULL);
g_applib_mem_cntx.screen_id_callback = screen_id_callback;
g_applib_mem_cntx.screen_head.next = NULL;
}
/*****************************************************************************
* FUNCTION
* applib_mem_screen_alloc
* DESCRIPTION
* Allocate screen-based ASM
*
* Remark:
* 1. It might return NULL if the allocate failed.
* 2. Please keep allocation count as few as possible; for example, allocate an
* array with 100 elements instead of using applib_mem_screen_alloc() 100 times.
*
* Reason A: the space overheads is hard to estimate when
* underlying implementation is changed.
* Reason B: performance is better when there are fewer allocations
*
* This function can be used in non-MMI task.
* PARAMETERS
* mem_size [IN] Memory size
* RETURNS
* Allocated memory block
*****************************************************************************/
void *applib_mem_screen_alloc(kal_uint32 mem_size)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
applib_mem_header_struct *header;
applib_mem_footer_struct *footer;
kal_uint32 chunk_size;
void *chunk;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
chunk_size = (((mem_size + 3) >> 2) << 2); /* round to multiple of 4 */
if (chunk_size == 0)
{
/* To avoid return NULL when allocated size = 0 */
chunk_size = 4;
}
#ifdef APPLIB_MEM_USE_ADM
chunk = kal_adm_alloc(
g_applib_mem_cntx.screen_pool_id,
chunk_size + sizeof(applib_mem_header_struct) + sizeof(applib_mem_footer_struct));
#else /* APPLIB_MEM_USE_ADM */
chunk = malloc((size_t) chunk_size + sizeof(applib_mem_header_struct) + sizeof(applib_mem_footer_struct));
#endif /* APPLIB_MEM_USE_ADM */
if (chunk == NULL)
{
return NULL;
}
header = (applib_mem_header_struct*) chunk;
chunk = header + 1;
footer = (applib_mem_footer_struct*) (((char*)chunk) + chunk_size);
/* header */
header->owner_id = g_applib_mem_cntx.screen_id_callback();
header->chunk_size = chunk_size;
APPLIB_MEM_SET_PATTERN(header->guard_pattern, APPLIB_MEM_HEADER_PATTERN1);
/* footer */
APPLIB_MEM_SET_PATTERN(footer->guard_pattern, APPLIB_MEM_FOOTER_PATTERN1);
/* update linked list */
header->next = g_applib_mem_cntx.screen_head.next;
g_applib_mem_cntx.screen_head.next = header;
/* system context */
g_applib_mem_cntx.screen_alloc_count++;
return chunk;
}
/*****************************************************************************
* FUNCTION
* applib_mem_screen_free
* DESCRIPTION
* Free screen-based ASM
*
* This function can be used in non-MMI task.
* PARAMETERS
* mem_ptr [IN] Memory block to be released
* RETURNS
* void
*****************************************************************************/
void applib_mem_screen_free(void *mem_ptr)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
applib_mem_header_struct *header, *prev_node, *remove_node;
applib_mem_footer_struct *footer;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
ASSERT(mem_ptr && APPLIB_MEM_ALIGNED_4(mem_ptr));
header = ((applib_mem_header_struct*) mem_ptr) - 1;
footer = (applib_mem_footer_struct*) (((char*)mem_ptr) + header->chunk_size);
ASSERT(APPLIB_MEM_COMP_PATTERN(header->guard_pattern, APPLIB_MEM_HEADER_PATTERN1) &&
APPLIB_MEM_COMP_PATTERN(footer->guard_pattern, APPLIB_MEM_FOOTER_PATTERN1));
/*
* Remove the block from linked list
*
* It is not a fast algorithm, we can improve it by using double linked list,
* but we choose simpler design because
* 1. Typically total allocation count is small
* 2. We don't want to increase space overheads
* 3. We don't want to access KAL ADM internal data structure
*/
prev_node = &g_applib_mem_cntx.screen_head;
ASSERT(prev_node->next);
for (remove_node = prev_node->next;
remove_node;
prev_node = remove_node, remove_node = prev_node->next)
{
if (remove_node == header)
{
break;
}
}
ASSERT(remove_node);
prev_node->next = remove_node->next;
/* Set guard pattern */
APPLIB_MEM_SET_PATTERN(header->guard_pattern, APPLIB_MEM_HEADER_PATTERN2);
APPLIB_MEM_SET_PATTERN(footer->guard_pattern, APPLIB_MEM_FOOTER_PATTERN2);
/* Release the block */
#ifdef APPLIB_MEM_USE_ADM
kal_adm_free(g_applib_mem_cntx.screen_pool_id, header);
#else
free(header);
#endif
ASSERT(g_applib_mem_cntx.screen_alloc_count > 0);
g_applib_mem_cntx.screen_alloc_count--;
}
/*****************************************************************************
* FUNCTION
* applib_mem_screen_free_all
* DESCRIPTION
* Release all screen-based ASM
*
* This function can be used in non-MMI task.
* PARAMETERS
* void
* RETURNS
* void
*****************************************************************************/
void applib_mem_screen_free_all(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
applib_mem_header_struct *node, *next;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
node = g_applib_mem_cntx.screen_head.next;
while (node)
{
next = node->next;
applib_mem_screen_free(node + 1);
node = next;
}
}
/*****************************************************************************
* FUNCTION
* applib_mem_screen_get_total_left_size
* DESCRIPTION
* Get available size of screen-based ASM.
*
* Remark: this function is only suggested for *debug* purpose because
* 1. The memory pool may be fragmented (total left free space is meaningless
* if the pool has serious memory fragmentation)
* 2. Even if the free space is contiguous, we still cannot allocate 10 * 10KB blocks
* with 100KB free space because of the overheads of memory management bookkeeping
*
* Please use applib_mem_screen_get_max_alloc_size() or applib_mem_screen_get_pool_size()
* instead.
*
* This function can be used in non-MMI task.
* PARAMETERS
* void
* RETURNS
* Total left space in byte
*****************************************************************************/
kal_uint32 applib_mem_screen_get_total_left_size(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
#ifdef APPLIB_MEM_USE_ADM
return kal_adm_get_total_left_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 */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?