X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Fvec.h;h=d19ff998137323cf290e534fd36a3e8e9f84d250;hb=7554aef84a8a406c9dae73a7445e8b97920a83b3;hp=1fcb5f1a37471c06cbc34b058227c4ca8ec384ac;hpb=e09ae01f6777434f41ba8a5a564c8078565ecfea;p=vpp.git diff --git a/src/vppinfra/vec.h b/src/vppinfra/vec.h index 1fcb5f1a374..d19ff998137 100644 --- a/src/vppinfra/vec.h +++ b/src/vppinfra/vec.h @@ -209,6 +209,21 @@ _vec_resize_will_expand (void *v, return 1; } +/** \brief Determine if vector will resize with next allocation + + @param V pointer to a vector + @param N number of elements to add + @return 1 if vector will resize 0 otherwise +*/ + +#define vec_resize_will_expand(V, N) \ + ({ \ + word _v (n) = (N); \ + word _v (l) = vec_len (V); \ + _vec_resize_will_expand ((V), _v (n), \ + (_v (l) + _v (n)) * sizeof ((V)[0]), 0, 0); \ + }) + /** \brief Predicate function, says whether the supplied vector is a clib heap object (general version). @@ -650,13 +665,19 @@ do { \ @param A alignment (may be zero) @return V (value-result macro parameter) */ -#define vec_add_ha(V,E,N,H,A) \ -do { \ - word _v(n) = (N); \ - word _v(l) = vec_len (V); \ - V = _vec_resize ((V), _v(n), (_v(l) + _v(n)) * sizeof ((V)[0]), (H), (A)); \ - clib_memcpy_fast ((V) + _v(l), (E), _v(n) * sizeof ((V)[0])); \ -} while (0) +#define vec_add_ha(V, E, N, H, A) \ + do \ + { \ + word _v (n) = (N); \ + if (PREDICT_TRUE (_v (n) > 0)) \ + { \ + word _v (l) = vec_len (V); \ + V = _vec_resize ((V), _v (n), (_v (l) + _v (n)) * sizeof ((V)[0]), \ + (H), (A)); \ + clib_memcpy_fast ((V) + _v (l), (E), _v (n) * sizeof ((V)[0])); \ + } \ + } \ + while (0) /** \brief Add N elements to end of vector V (no header, unspecified alignment) @@ -804,22 +825,23 @@ do { \ @return V (value-result macro parameter) */ -#define vec_insert_elts_ha(V,E,N,M,H,A) \ -do { \ - word _v(l) = vec_len (V); \ - word _v(n) = (N); \ - word _v(m) = (M); \ - V = _vec_resize ((V), \ - _v(n), \ - (_v(l) + _v(n))*sizeof((V)[0]), \ - (H), (A)); \ - ASSERT (_v(m) <= _v(l)); \ - memmove ((V) + _v(m) + _v(n), \ - (V) + _v(m), \ - (_v(l) - _v(m)) * sizeof ((V)[0])); \ - clib_memcpy_fast ((V) + _v(m), (E), \ - _v(n) * sizeof ((V)[0])); \ -} while (0) +#define vec_insert_elts_ha(V, E, N, M, H, A) \ + do \ + { \ + word _v (n) = (N); \ + if (PREDICT_TRUE (_v (n) > 0)) \ + { \ + word _v (l) = vec_len (V); \ + word _v (m) = (M); \ + V = _vec_resize ((V), _v (n), (_v (l) + _v (n)) * sizeof ((V)[0]), \ + (H), (A)); \ + ASSERT (_v (m) <= _v (l)); \ + memmove ((V) + _v (m) + _v (n), (V) + _v (m), \ + (_v (l) - _v (m)) * sizeof ((V)[0])); \ + clib_memcpy_fast ((V) + _v (m), (E), _v (n) * sizeof ((V)[0])); \ + } \ + } \ + while (0) /** \brief Insert N vector elements starting at element M, insert given elements (no header, unspecified alignment) @@ -887,15 +909,21 @@ do { \ @param V2 vector to append */ -#define vec_append(v1,v2) \ -do { \ - uword _v(l1) = vec_len (v1); \ - uword _v(l2) = vec_len (v2); \ - \ - v1 = _vec_resize ((v1), _v(l2), \ - (_v(l1) + _v(l2)) * sizeof ((v1)[0]), 0, 0); \ - clib_memcpy_fast ((v1) + _v(l1), (v2), _v(l2) * sizeof ((v2)[0])); \ -} while (0) +#define vec_append(v1, v2) \ + do \ + { \ + uword _v (l1) = vec_len (v1); \ + uword _v (l2) = vec_len (v2); \ + \ + if (PREDICT_TRUE (_v (l2) > 0)) \ + { \ + v1 = _vec_resize ((v1), _v (l2), \ + (_v (l1) + _v (l2)) * sizeof ((v1)[0]), 0, 0); \ + clib_memcpy_fast ((v1) + _v (l1), (v2), \ + _v (l2) * sizeof ((v2)[0])); \ + } \ + } \ + while (0) /** \brief Append v2 after v1. Result in v1. Specified alignment. @param V1 target vector @@ -903,31 +931,42 @@ do { \ @param align required alignment */ -#define vec_append_aligned(v1,v2,align) \ -do { \ - uword _v(l1) = vec_len (v1); \ - uword _v(l2) = vec_len (v2); \ - \ - v1 = _vec_resize ((v1), _v(l2), \ - (_v(l1) + _v(l2)) * sizeof ((v1)[0]), 0, align); \ - clib_memcpy_fast ((v1) + _v(l1), (v2), _v(l2) * sizeof ((v2)[0])); \ -} while (0) +#define vec_append_aligned(v1, v2, align) \ + do \ + { \ + uword _v (l1) = vec_len (v1); \ + uword _v (l2) = vec_len (v2); \ + \ + if (PREDICT_TRUE (_v (l2) > 0)) \ + { \ + v1 = _vec_resize ( \ + (v1), _v (l2), (_v (l1) + _v (l2)) * sizeof ((v1)[0]), 0, align); \ + clib_memcpy_fast ((v1) + _v (l1), (v2), \ + _v (l2) * sizeof ((v2)[0])); \ + } \ + } \ + while (0) /** \brief Prepend v2 before v1. Result in v1. @param V1 target vector @param V2 vector to prepend */ -#define vec_prepend(v1,v2) \ -do { \ - uword _v(l1) = vec_len (v1); \ - uword _v(l2) = vec_len (v2); \ - \ - v1 = _vec_resize ((v1), _v(l2), \ - (_v(l1) + _v(l2)) * sizeof ((v1)[0]), 0, 0); \ - memmove ((v1) + _v(l2), (v1), _v(l1) * sizeof ((v1)[0])); \ - clib_memcpy_fast ((v1), (v2), _v(l2) * sizeof ((v2)[0])); \ -} while (0) +#define vec_prepend(v1, v2) \ + do \ + { \ + uword _v (l1) = vec_len (v1); \ + uword _v (l2) = vec_len (v2); \ + \ + if (PREDICT_TRUE (_v (l2) > 0)) \ + { \ + v1 = _vec_resize ((v1), _v (l2), \ + (_v (l1) + _v (l2)) * sizeof ((v1)[0]), 0, 0); \ + memmove ((v1) + _v (l2), (v1), _v (l1) * sizeof ((v1)[0])); \ + clib_memcpy_fast ((v1), (v2), _v (l2) * sizeof ((v2)[0])); \ + } \ + } \ + while (0) /** \brief Prepend v2 before v1. Result in v1. Specified alignment @param V1 target vector @@ -935,17 +974,21 @@ do { \ @param align required alignment */ -#define vec_prepend_aligned(v1,v2,align) \ -do { \ - uword _v(l1) = vec_len (v1); \ - uword _v(l2) = vec_len (v2); \ - \ - v1 = _vec_resize ((v1), _v(l2), \ - (_v(l1) + _v(l2)) * sizeof ((v1)[0]), 0, align); \ - memmove ((v1) + _v(l2), (v1), _v(l1) * sizeof ((v1)[0])); \ - clib_memcpy_fast ((v1), (v2), _v(l2) * sizeof ((v2)[0])); \ -} while (0) - +#define vec_prepend_aligned(v1, v2, align) \ + do \ + { \ + uword _v (l1) = vec_len (v1); \ + uword _v (l2) = vec_len (v2); \ + \ + if (PREDICT_TRUE (_v (l2) > 0)) \ + { \ + v1 = _vec_resize ( \ + (v1), _v (l2), (_v (l1) + _v (l2)) * sizeof ((v1)[0]), 0, align); \ + memmove ((v1) + _v (l2), (v1), _v (l1) * sizeof ((v1)[0])); \ + clib_memcpy_fast ((v1), (v2), _v (l2) * sizeof ((v2)[0])); \ + } \ + } \ + while (0) /** \brief Zero all vector elements. Null-pointer tolerant. @param var Vector to zero