1. 程式人生 > >VPP程式碼閱讀中文註解--vec.c

VPP程式碼閱讀中文註解--vec.c

#include <vppinfra/vec.h>
#include <vppinfra/mem.h>

/* 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中。