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