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