vppinfra: don't fail if config.h is missing, fallback to defaults instead
[vpp.git] / src / vppinfra / vec.c
index 1e0164a..970f7f7 100644 (file)
 #include <vppinfra/vec.h>
 #include <vppinfra/mem.h>
 
+#ifndef CLIB_VECTOR_GROW_BY_ONE
+#define CLIB_VECTOR_GROW_BY_ONE 0
+#endif
+
 /* Vector resize operator.  Called as needed by various macros such as
    vec_add1() when we need to allocate memory. */
-void *
+__clib_export void *
 vec_resize_allocate_memory (void *v,
                            word length_increment,
                            uword data_bytes,
-                           uword header_bytes, uword data_align)
+                           uword header_bytes, uword data_align,
+                           uword numa_id)
 {
   vec_header_t *vh = _vec_find (v);
   uword old_alloc_bytes, new_alloc_bytes;
   void *old, *new;
+  void *oldheap;
 
   header_bytes = vec_header_bytes (header_bytes);
 
   data_bytes += header_bytes;
 
+  if (PREDICT_FALSE (numa_id != VEC_NUMA_UNSPECIFIED))
+    {
+      oldheap = clib_mem_get_per_cpu_heap ();
+      clib_mem_set_per_cpu_heap (clib_mem_get_per_numa_heap (numa_id));
+    }
+
   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);
-      clib_memset (new, 0, data_bytes);
+      new_alloc_bytes = clib_mem_size (new);
+      CLIB_MEM_UNPOISON (new + data_bytes, new_alloc_bytes - data_bytes);
+      clib_memset (new, 0, new_alloc_bytes);
+      CLIB_MEM_POISON (new + data_bytes, new_alloc_bytes - data_bytes);
       v = new + header_bytes;
       _vec_len (v) = length_increment;
+      _vec_numa (v) = numa_id;
+      if (PREDICT_FALSE (numa_id != VEC_NUMA_UNSPECIFIED))
+       clib_mem_set_per_cpu_heap (oldheap);
       return v;
     }
 
@@ -75,11 +92,20 @@ vec_resize_allocate_memory (void *v,
 
   /* Need to resize? */
   if (data_bytes <= old_alloc_bytes)
-    return v;
+    {
+      CLIB_MEM_UNPOISON (v, data_bytes);
+      if (PREDICT_FALSE (numa_id != VEC_NUMA_UNSPECIFIED))
+       clib_mem_set_per_cpu_heap (oldheap);
+      return v;
+    }
 
+#if CLIB_VECTOR_GROW_BY_ONE > 0
+  new_alloc_bytes = data_bytes;
+#else
   new_alloc_bytes = (old_alloc_bytes * 3) / 2;
   if (new_alloc_bytes < data_bytes)
     new_alloc_bytes = data_bytes;
+#endif
 
   new =
     clib_mem_alloc_aligned_at_offset (new_alloc_bytes, data_align,
@@ -92,7 +118,8 @@ vec_resize_allocate_memory (void *v,
       ("vec_resize fails, length increment %d, data bytes %d, alignment %d",
        length_increment, data_bytes, data_align);
 
-  clib_memcpy (new, old, old_alloc_bytes);
+  CLIB_MEM_UNPOISON (old, old_alloc_bytes);
+  clib_memcpy_fast (new, old, old_alloc_bytes);
   clib_mem_free (old);
 
   /* Allocator may give a bit of extra room. */
@@ -100,17 +127,35 @@ vec_resize_allocate_memory (void *v,
   v = new;
 
   /* Zero new memory. */
-  clib_memset (v + old_alloc_bytes, 0, new_alloc_bytes - old_alloc_bytes);
+  CLIB_MEM_UNPOISON (new + data_bytes, new_alloc_bytes - data_bytes);
+  memset (v + old_alloc_bytes, 0, new_alloc_bytes - old_alloc_bytes);
+  CLIB_MEM_POISON (new + data_bytes, new_alloc_bytes - data_bytes);
+
+  _vec_numa ((v + header_bytes)) = numa_id;
+  if (PREDICT_FALSE (numa_id != VEC_NUMA_UNSPECIFIED))
+    clib_mem_set_per_cpu_heap (oldheap);
 
   return v + header_bytes;
 }
 
-uword
+__clib_export uword
 clib_mem_is_vec_h (void *v, uword header_bytes)
 {
   return clib_mem_is_heap_object (vec_header (v, header_bytes));
 }
 
+__clib_export u32
+vec_len_not_inline (void *v)
+{
+  return vec_len (v);
+}
+
+__clib_export void
+vec_free_not_inline (void *v)
+{
+  vec_free (v);
+}
+
 /** \cond */
 
 #ifdef TEST