app_mem.c
来自「最新MTK手机软件源码」· C语言 代码 · 共 1,684 行 · 第 1/5 页
C
1,684 行
/*****************************************************************************
* FUNCTION
* applib_mem_ap_stop_app_by_MMI_task
* DESCRIPTION
* Stop an application. This function must be invoked by MMI task only.
* (The API is used by MMI framework only)
* PARAMETERS
* app_id [IN] ID of the application to be stopped
* RETURNS
* void
*****************************************************************************/
void applib_mem_ap_stop_app_by_MMI_task(kal_uint32 app_id)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
ASSERT(app_id < APPLIB_MEM_AP_ID_TOTAL &&
!g_applib_mem_cntx.app_is_stopping[app_id]); /* Not stopped before */
g_applib_mem_cntx.app_is_stopping[app_id] = KAL_TRUE;
(g_applib_mem_cntx.app_stop_callbacks[app_id])();
}
/*****************************************************************************
* FUNCTION
* applib_mem_ap_get_current_usage
* DESCRIPTION
* List memory consumption by current applications
* (The API is used by MMI framework only)
* PARAMETERS
* applist [OUT] List of applications and its memory consumption
* max_items [IN] The maximum size of 'applist'
* RETURNS
* the number of applications listed
*****************************************************************************/
kal_uint32 applib_mem_ap_get_current_usage(applib_mem_ap_usage_struct *applist, kal_uint32 max_items)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_int32 item_count;
applib_mem_header_struct *node;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (g_applib_mem_cntx.app_pool_id) /* Normal mode */
{
item_count = 0;
node = g_applib_mem_cntx.app_head.next;
while (node)
{
kal_int32 idx;
for (idx = 0; idx < item_count; idx++)
{
if (applist[idx].app_id == node->owner_id)
{
break;
}
}
if (idx == item_count)
{
if (item_count == max_items)
{
node = node->next;
continue;
}
else
{
applist[item_count].app_id = node->owner_id;
applist[item_count].string_id = g_applib_mem_cntx.app_names[node->owner_id];
applist[item_count].icon_id = g_applib_mem_cntx.app_icons[node->owner_id];
applist[item_count].mem_size = 0;
applist[item_count].is_stopping = g_applib_mem_cntx.app_is_stopping[node->owner_id];
item_count++;
}
}
applist[idx].mem_size += node->chunk_size + APPLIB_MEM_CHUNK_EXTRA_SIZE;
node = node->next;
}
}
else /* Full pool mode */
{
item_count = 0;
if (g_applib_mem_cntx.app_alloc_count)
{
kal_uint32 app_id = g_applib_mem_cntx.app_id_of_full_pool;
applist[item_count].app_id = app_id;
applist[item_count].string_id = g_applib_mem_cntx.app_names[app_id];
applist[item_count].icon_id = g_applib_mem_cntx.app_icons[app_id];
applist[item_count].mem_size = APPLIB_MEM_AP_POOL_SIZE;
applist[item_count].is_stopping = g_applib_mem_cntx.app_is_stopping[app_id];
item_count++;
}
}
return item_count;
}
/*****************************************************************************
* FUNCTION
* applib_mem_ap_register
* DESCRIPTION
* Register an application that uses app-based ASM
*
* Remark:
* 1. This function should be used when an application is initialized at boot
* 2. 'stop_callback_by_MMI' is executed in MMI task. If we need to notify another
* task to stop the application, please send primitive (source module: MOD_MMI)
* to the destination task inside the registered function 'stop_callback_by_MMI'.
*
* This function can be used in non-MMI task.
* PARAMETERS
* app_id [IN] Application ID defined in applib_mem_ap_id_enum
* app_string_id [IN] The MMI string ID of application name
* app_icon_id [IN] The MMI image ID of application icon
* stop_callback_by_MMI [IN] Callback function when user chooses to stop the application
* RETURNS
* void
*****************************************************************************/
void applib_mem_ap_register(
kal_uint32 app_id,
kal_uint32 app_string_id,
kal_uint32 app_icon_id,
void (*stop_callback_by_MMI)(void))
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
ASSERT(app_id < APPLIB_MEM_AP_ID_TOTAL &&
app_string_id &&
stop_callback_by_MMI);
g_applib_mem_cntx.app_stop_callbacks[app_id] = stop_callback_by_MMI;
g_applib_mem_cntx.app_names[app_id] = app_string_id;
g_applib_mem_cntx.app_icons[app_id] = app_icon_id;
}
/*****************************************************************************
* FUNCTION
* applib_mem_ap_notify_stop_finished
* DESCRIPTION
* This function is invoked by an application to notify MMI framework when
* it was requested to be stopped and it finished the stop operation.
* (Memory used by it are all released)
*
* Warning: This function can only be used in MMI task.
* PARAMETERS
* app_id [IN] ID of the application requested to stop (applib_mem_ap_id_enum)
* result [IN] Whether the stop operation succeeded or not
* RETURNS
* void
*****************************************************************************/
void applib_mem_ap_notify_stop_finished(kal_uint32 app_id, kal_bool result)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
#ifndef MMI_ON_WIN32
// TODO: We should handle non-MMI task in the future!
extern unsigned char mmiapi_is_MMI_task(void);
ASSERT(mmiapi_is_MMI_task());
#endif /* MMI_ON_WIN32 */
#ifdef DEBUG_KAL
/* Note: If memory allocated by applib_mem_ap_alloc_full_pool() is released,
it should create ADM pool again. */
ASSERT(g_applib_mem_cntx.app_pool_id);
if (result)
{
/* Its memory should be released */
applib_mem_header_struct *node;
node = g_applib_mem_cntx.app_head.next;
while (node)
{
ASSERT(node->owner_id != app_id);
node = node->next;
}
}
#endif /* DEBUG_KAL */
g_applib_mem_cntx.app_is_stopping[app_id] = KAL_FALSE;
g_applib_mem_cntx.app_stop_finish_callback(app_id, g_applib_mem_cntx.app_names[app_id], result);
}
/*****************************************************************************
* FUNCTION
* applib_mem_ap_alloc
* DESCRIPTION
* Allocate app-based ASM
*
* Remark:
* 1. It might return NULL if the allocation failed.
* 2. Please keep allocation count as few as possible; for example, allocate an
* array with 100 elements instead of using applib_mem_ap_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
* app_id [IN] ID of owner application (applib_mem_ap_id_enum)
* mem_size [IN] Memory size
* RETURNS
* Allocated memory block
*****************************************************************************/
void *applib_mem_ap_alloc(kal_uint32 app_id, kal_uint32 mem_size)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
applib_mem_header_struct *header;
applib_mem_footer_struct *footer;
kal_uint32 chunk_size;
void *chunk;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (!g_applib_mem_cntx.app_pool_id) /* The whole pool was allocated by applib_mem_ap_alloc_full_pool() */
{
return NULL;
}
ASSERT(g_applib_mem_cntx.app_stop_callbacks[app_id] && g_applib_mem_cntx.app_names[app_id]); /* App registered */
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.app_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 = app_id;
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.app_head.next;
g_applib_mem_cntx.app_head.next = header;
/* system context */
g_applib_mem_cntx.app_alloc_count++;
return chunk;
}
/*****************************************************************************
* FUNCTION
* applib_mem_ap_alloc_full_pool
* DESCRIPTION
* Allocate the whole pool of app-based ASM
*
* Note: it is typically used with APPLIB_MEM_AP_POOL_ALIGN to get a aligned
* buffer pool (Example: Java FBBR requires 256KB or 512KB alignment)
* PARAMETERS
* app_id [IN] ID of owner application (applib_mem_ap_id_enum)
* pool_size [OUT] Allocated size (== the whole pool size)
* RETURNS
* Allocated memory block
*****************************************************************************/
void *applib_mem_ap_alloc_full_pool(kal_uint32 app_id, kal_uint32 *pool_size)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (g_applib_mem_cntx.app_alloc_count)
{
return NULL;
}
if (g_applib_mem_cntx.app_pool_id)
{
#ifdef APPLIB_MEM_USE_ADM
kal_adm_delete(g_applib_mem_cntx.app_pool_id);
#endif
g_applib_mem_cntx.app_pool_id = 0;
}
g_applib_mem_cntx.app_id_of_full_pool = app_id;
g_applib_mem_cntx.app_alloc_count = 1;
*pool_size = APPLIB_MEM_AP_POOL_SIZE;
return g_applib_mem_ap_pool;
}
/*****************************************************************************
* FUNCTION
* applib_mem_ap_free
* DESCRIPTION
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?