#include
#include
/* Vector resize operator. Called as needed by various macros such as
vec_add1() when we need to allocate memory. */
void *
vec_resize_allocate_memory (void *v,
word length_increment,
uword data_bytes,
uword header_bytes, uword data_align)
{
vec_header_t *vh = _vec_find (v);
uword old_alloc_bytes, new_alloc_bytes;
void *old, *new;
header_bytes = vec_header_bytes (header_bytes);
data_bytes += header_bytes;
if (!v)
{
new = clib_mem_alloc_aligned_at_offset (data_bytes, data_align, header_bytes, 1 /* yes, call os_out_of_memory */
);
data_bytes = clib_mem_size (new);
memset (new, 0, data_bytes);
v = new + header_bytes;
_vec_len (v) = length_increment;
return v;
}
当动态数组需要申请内存时,会调用到这个函数
如果v是空指针,则表示新增动态数组,而不是扩展已有的数组。则直接申请好数组内存,并初始化动态数组的头,返回数组元素0的首地址。其它内容初始化成0。
vh->len += length_increment;
old = v - header_bytes;
/* Vector header must start heap object. */
ASSERT (clib_mem_is_heap_object (old));
old_alloc_bytes = clib_mem_size (old);
/* Need to resize? */
if (data_bytes <= old_alloc_bytes)
return v;
也许当前的内存块,能满足需求,这样的话,就不必申请新内存了。
new_alloc_bytes = (old_alloc_bytes * 3) / 2;
if (new_alloc_bytes < data_bytes)
new_alloc_bytes = data_bytes;
new =
clib_mem_alloc_aligned_at_offset (new_alloc_bytes, data_align,
header_bytes,
1 /* yes, call os_out_of_memory */ );
/* FIXME fail gracefully. */
if (!new)
clib_panic
("vec_resize fails, length increment %d, data bytes %d, alignment %d",
length_increment, data_bytes, data_align);
按之前内存大小的3/2倍增长能满足需求的话,则按这个比例扩展,否则一步到位。
申请新的数组内存空间。
clib_memcpy (new, old, old_alloc_bytes);
clib_mem_free (old);
/* Allocator may give a bit of extra room. */
new_alloc_bytes = clib_mem_size (new);
v = new;
/* Zero new memory. */
memset (v + old_alloc_bytes, 0, new_alloc_bytes - old_alloc_bytes);
return v + header_bytes;
拷贝旧数组中的数据到新数组中,并释放旧数组。新数组新增的元素,其值置0. 返回新数组0号元素的地址。
uword
clib_mem_is_vec_h (void *v, uword header_bytes)
{
return clib_mem_is_heap_object (vec_header (v, header_bytes));
}
此动态数组是否状态CLIB heap中。