aboutsummaryrefslogtreecommitdiffstats
path: root/src/vppinfra/vec_bootstrap.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vppinfra/vec_bootstrap.h')
-rw-r--r--src/vppinfra/vec_bootstrap.h16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/vppinfra/vec_bootstrap.h b/src/vppinfra/vec_bootstrap.h
index a94c1a19ba7..567041550a4 100644
--- a/src/vppinfra/vec_bootstrap.h
+++ b/src/vppinfra/vec_bootstrap.h
@@ -58,7 +58,8 @@ typedef struct
u8 hdr_size; /**< header size divided by VEC_MIN_ALIGN */
u8 log2_align : 7; /**< data alignment */
u8 default_heap : 1; /**< vector uses default heap */
- u8 vpad[2]; /**< pad to 8 bytes */
+ u8 grow_elts; /**< number of elts vector can grow without realloc */
+ u8 vpad[1]; /**< pad to 8 bytes */
u8 vector_data[0]; /**< Vector data . */
} vec_header_t;
@@ -168,18 +169,31 @@ _vec_max_len (void *v, uword elt_sz)
#define vec_max_len(v) _vec_max_len (v, _vec_elt_sz (v))
+static_always_inline void
+_vec_set_grow_elts (void *v, uword n_elts)
+{
+ uword max = pow2_mask (BITS (_vec_find (0)->grow_elts));
+
+ if (PREDICT_FALSE (n_elts > max))
+ n_elts = max;
+
+ _vec_find (v)->grow_elts = n_elts;
+}
+
always_inline void
_vec_set_len (void *v, uword len, uword elt_sz)
{
ASSERT (v);
ASSERT (len <= _vec_max_len (v, elt_sz));
uword old_len = _vec_len (v);
+ uword grow_elts = _vec_find (v)->grow_elts;
if (len > old_len)
clib_mem_unpoison (v + old_len * elt_sz, (len - old_len) * elt_sz);
else if (len > old_len)
clib_mem_poison (v + len * elt_sz, (old_len - len) * elt_sz);
+ _vec_set_grow_elts (v, old_len + grow_elts - len);
_vec_find (v)->len = len;
}