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 + -
显示快捷键?