app_mem.c

来自「最新MTK手机软件源码」· C语言 代码 · 共 1,684 行 · 第 1/5 页

C
1,684
字号
 *  Free app-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_ap_free(void *mem_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    applib_mem_header_struct *header, *prev_node, *remove_node;
    applib_mem_footer_struct *footer;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (g_applib_mem_cntx.app_pool_id)    /* Normal mode */
    {
        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.app_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.app_pool_id, header);
    #else 
        free(header);
    #endif 

        ASSERT(g_applib_mem_cntx.app_alloc_count > 0);
        g_applib_mem_cntx.app_alloc_count--;
    }
    else /* Full pool mode */
    {
        ASSERT(mem_ptr == g_applib_mem_ap_pool && g_applib_mem_cntx.app_alloc_count == 1);
        g_applib_mem_cntx.app_alloc_count = 0;
        g_applib_mem_cntx.app_id_of_full_pool = APPLIB_MEM_AP_ID_DUMMY; /* 0 */
        
    #ifdef APPLIB_MEM_USE_ADM    
        g_applib_mem_cntx.app_pool_id = kal_adm_create(
                                            g_applib_mem_ap_pool,
                                            APPLIB_MEM_AP_POOL_SIZE,
                                            (kal_uint32*) g_applib_mem_pool_chunk_size,
                                            KAL_FALSE);
    #else /* APPLIB_MEM_USE_ADM */
        g_applib_mem_cntx.app_pool_id = APPLIB_DUMMY_POOL_ID;
    #endif /* APPLIB_MEM_USE_ADM */
    }
}


/*****************************************************************************
 * FUNCTION
 *  applib_mem_ap_free_all
 * DESCRIPTION
 *  Release all app-based ASM belong to an application
 *
 *  This function can be used in non-MMI task.
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
void applib_mem_ap_free_all(kal_uint32 app_id)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    applib_mem_header_struct *node, *next;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (g_applib_mem_cntx.app_pool_id)  /* Normal mode */
    {
        node = g_applib_mem_cntx.app_head.next;
        while (node)
        {
            next = node->next;
            if (node->owner_id == app_id)
            {
                applib_mem_ap_free(node + 1);
            }
            node = next;
        }
    }
    else /* Full pool mode */
    {
        ASSERT(g_applib_mem_cntx.app_alloc_count == 1);
        g_applib_mem_cntx.app_alloc_count = 0;
        g_applib_mem_cntx.app_id_of_full_pool = APPLIB_MEM_AP_ID_DUMMY; /* 0 */
        
    #ifdef APPLIB_MEM_USE_ADM    
        g_applib_mem_cntx.app_pool_id = kal_adm_create(
                                            g_applib_mem_ap_pool,
                                            APPLIB_MEM_AP_POOL_SIZE,
                                            (kal_uint32*) g_applib_mem_pool_chunk_size,
                                            KAL_FALSE);
    #else /* APPLIB_MEM_USE_ADM */
        g_applib_mem_cntx.app_pool_id = APPLIB_DUMMY_POOL_ID;
    #endif /* APPLIB_MEM_USE_ADM */        
    }
}


/*****************************************************************************
 * FUNCTION
 *  applib_mem_ap_get_total_left_size
 * DESCRIPTION
 *  Get available size of app-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, sometimes we still cannot allocate 10 * 10KB blocks 
 *     with 100KB free space because of the overheads of memory management bookkeeping
 *
 *  Please use applib_mem_ap_get_max_alloc_size() or applib_mem_ap_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_ap_get_total_left_size(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#ifdef APPLIB_MEM_USE_ADM
    if (g_applib_mem_cntx.app_pool_id)
    {
        return kal_adm_get_total_left_size(g_applib_mem_cntx.app_pool_id) -
            sizeof(applib_mem_header_struct) - sizeof(applib_mem_footer_struct);
    }
    else
    {
        return 0;
    }
#else /* APPLIB_MEM_USE_ADM */ 
    return (10 * 1024 * 1024);  /* Return dummy value */
#endif /* APPLIB_MEM_USE_ADM */ 
}


/*****************************************************************************
 * FUNCTION
 *  applib_mem_ap_get_max_alloc_size
 * DESCRIPTION
 *  Get the max possible size of single allocation from app-based ASM. 
 *  Return value of it is typically less than applib_mem_ap_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 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 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 available allocation size in byte
 *****************************************************************************/
kal_uint32 applib_mem_ap_get_max_alloc_size(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#ifdef APPLIB_MEM_USE_ADM
    if (g_applib_mem_cntx.app_pool_id)
    {
        return kal_adm_get_max_alloc_size(g_applib_mem_cntx.app_pool_id) -
            sizeof(applib_mem_header_struct) - sizeof(applib_mem_footer_struct);
    }
    else
    {
        return 0;
    }
#else /* APPLIB_MEM_USE_ADM */ 
    return (10 * 1024 * 1024);  /* Return dummy value */
#endif /* APPLIB_MEM_USE_ADM */
}


/*****************************************************************************
 * FUNCTION
 *  applib_mem_ap_get_pool_size
 * DESCRIPTION
 *  Return the fixed size of app-based ASM pool
 *
 *  Remark: we can use this function to decide the maximum possible memory 
 *  we can allocate (the whole pool size).
 * 
 *  However, sometimes we 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 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
 *  Pool size in byte
 *****************************************************************************/
kal_uint32 applib_mem_ap_get_pool_size(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    return APPLIB_MEM_AP_POOL_SIZE - APPLIB_MEM_POOL_EXTRA_SIZE - APPLIB_MEM_CHUNK_EXTRA_SIZE;
}


/*****************************************************************************
 * FUNCTION
 *  applib_mem_ap_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_ap_get_alloc_count(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    return g_applib_mem_cntx.app_alloc_count;
}


/*****************************************************************************
 * FUNCTION
 *  applib_mem_ap_is_valid_block
 * DESCRIPTION
 *  Check if a app-based ASM memory block is valid by inspecting its guard patterns.
 *
 *  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_ap_is_valid_block(void *mem_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    applib_mem_header_struct *header;
    applib_mem_footer_struct *footer;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (g_applib_mem_cntx.app_pool_id)
    {
        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);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?