昨天说到了内存的分配。下面看一下内存释放
主要进行了3步:
static void applib_mem_ap_free_int(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 */ } }
- 取得内存的头部和尾部,(调试版本可以判断内存是否越界)
- 从链表中删除这个节点
- 调用 kal_adm_free 释放内存
在MTK 内存管理简单总结 2 提到调用 applib_mem_ap_alloc 分配内存是需要一个应用id,这个id是需要自己增加,
而且在调用这个函数之前必须 调用 applib_mem_ap_register 注册这个id。需要注意的是最后一个参数,是一个回调函数,
这个回调函数是在共享内存不够使用时,ASM会调用这个函数,告诉应用需要释放共享内存,供其它应用使用。
增加 id 在 app_mem.h 的 applib_mem_ap_id_enum 里面,只要添加一个id就可以。
同样 屏幕内存也是通过ADM来管理,屏幕内存 是用来 创建 layer 用的,在MTK的某个版本开始,创建layer的内存是有要求的,
需要applib_mem_screen_alloc 分配的内存。