上一节我们介绍hash的使用,本来这节打算介绍mhash,但是mhash结构中使用了另外一种结构heap:可变长度的内存池管理结构。下面是vpp官方对heap的说明:
Rarely used (pool are faster)
很少使用,pool内存池更快
still efficient
但是也很有用
to be used if you need variably sized allocations
如果需要可变大小的分配,则使用
heap结构比pool结构处理比较复杂,我们可以先从heap的测试用例来了解heap的使用方法,再深入了解其内部处理逻辑。
从vppinfra/test_heap.c文件里面截取一部分代码来大概介绍一下具体的使用。heap和pool一样,有两种使用方式:
1:固定内存大小,静态heap--超过大小可能会报异常,这个应该和pool一样的,需要注意。
2: 动态申请内存大小,动态heap--这个对使用者没有限制。
我们主要介绍动态申请heap内存方式:
/* 动态heap内存使用函数。我们可以参考单元测试用例。
* u32 *v;heap管理堆数据区域头指针
* u32 handle:管理内存块结构体的下标:如:heap_elt_t *p =H->elts[handle]。
* u32 size :要申请数据的占用多少sizeof ((v)[0]),因为底层是vec操作函数。
* 这个可能比传入size要大,可能会进行 align字节对齐。
* u32 align:内存对齐的大小
*/
u32 offset = heap_alloc_aligned(v,size,align,handle);
/*我们申请内存的首地址head 可以通过下面方式直接得到*/
u32 * head = v + offset;
/*headle 我们必须要保存的,通过headle 我们可以用来释放这块内存*/
heap_dealloc (v, handle);
/*heap_elt_with_handle(v,handle)*/
heap_elt_with_handle(v,handle);
/* Header for heaps. */
typedef struct
{
/* Vector of used and free elements. heap管理数据块*/
heap_elt_t *elts;
/* For elt_bytes < sizeof (u32) we need some extra space
per elt to store free list index. */
u32 *small_free_elt_free_index;
/* Vector of free indices of elts array. */
u32 *free_elts;
/* Indices of free elts indexed by size bin. */
u32 **free_lists;
format_function_t *format_elt;
/* Used for validation/debugging. */
uword *used_elt_bitmap;
/* First and last element of doubly linked chain of elements. */
u32 head, tail;
/*used_count : 已经使用的个数,max_len 静态heap使用的,最大大小*/
u32 used_count, max_len;
/* Number of bytes in a help element.
*这个比较关键,heap堆的数据类型的字节数 ,等于size(v[0])*/
u32 elt_bytes;
u32 flags;
/* Static heaps are made from external memory given to
us by user and are not re-sizable vectors. */
#define HEAP_IS_STATIC (1)
} heap_header_t;
heap堆内存的块管理结构:
主要是offset :bit31 位:表示当前内存块是free还是busy状态。
bit0~30:表示举例heap 堆头指针V的偏移量大小。
next 和prev : 当前管理内存块的前后内存块是连续的,这样在heap_dealloc释放内存块时,我们可以判断前后是否free的,如果是free的,我们需要合并成大的内存块。
heap_header 结构中elts和free_elts 说明:
elts 是vector结构,主要是保存heap堆管理结构,heap_alloc的参数handle表示当前申请的内存块的管理结构在elts的下标。
free_elts :比较好理解,就是存放已经不使用的heap_elt_t 数据块。
heap内存分布及内存块free区管理
这里有个疑问small_free_elt_free_index 结构的作用是什么?
在源码注释的地方有说明,当elt_bytes < 4字节时使用。存储
small_free_elt_free_index【handle index】= free_list_index的。
这个主要是在合并free elts时候使用。v【0】的大小因为不满足4字节,无法存储free_list_index,所有我们使用small_free_elt_free_index[handle]来找到在free_list[bin]的下标,从未可以从free_list中删除。
本文分享自 DPDK VPP源码分析 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!