|
FD.io VPP
v21.06-3-gbb25fbf28
Vector Packet Processing
|
Go to the documentation of this file.
38 #ifndef included_vec_h
39 #define included_vec_h
103 word length_increment,
119 #define _vec_resize_numa(V,L,DB,HB,A,S) \
121 __typeof__ ((V)) _V; \
122 _V = _vec_resize_inline((void *)V,L,DB,HB,clib_max((__alignof__((V)[0])),(A)),(S)); \
126 #define _vec_resize(V,L,DB,HB,A) \
127 _vec_resize_numa(V,L,DB,HB,A,VEC_NUMA_UNSPECIFIED)
130 _vec_resize_inline (
void *v,
131 word length_increment,
136 uword new_data_bytes, aligned_header_bytes;
141 new_data_bytes = data_bytes + aligned_header_bytes;
145 void *p = v - aligned_header_bytes;
160 vh->
len += length_increment;
173 data_align), numa_id);
187 _vec_resize_will_expand (
void *v,
188 word length_increment,
192 uword new_data_bytes, aligned_header_bytes;
196 new_data_bytes = data_bytes + aligned_header_bytes;
200 void *p = v - aligned_header_bytes;
219 #define vec_resize_will_expand(V, N) \
222 word _v (l) = vec_len (V); \
223 _vec_resize_will_expand ((V), _v (n), \
224 (_v (l) + _v (n)) * sizeof ((V)[0]), 0, 0); \
250 #define _v(var) _vec_##var
265 #define vec_resize_has(V,N,H,A,S) \
268 word _v(l) = vec_len (V); \
269 V = _vec_resize_numa ((V), _v(n), \
270 (_v(l) + _v(n)) * sizeof ((V)[0]), \
285 #define vec_resize_ha(V,N,H,A) vec_resize_has(V,N,H,A,VEC_NUMA_UNSPECIFIED)
296 #define vec_resize(V,N) vec_resize_ha(V,N,0,0)
309 #define vec_resize_aligned(V,N,A) vec_resize_ha(V,N,0,A)
320 #define vec_alloc_ha(V,N,H,A) \
322 uword _v(l) = vec_len (V); \
323 vec_resize_ha (V, N, H, A); \
324 _vec_len (V) = _v(l); \
334 #define vec_alloc(V,N) vec_alloc_ha(V,N,0,0)
343 #define vec_alloc_aligned(V,N,A) vec_alloc_ha(V,N,0,A)
352 #define vec_new_ha(T,N,H,A) \
355 (T *)_vec_resize ((T *) 0, _v(n), _v(n) * sizeof (T), (H), (A)); \
365 #define vec_new(T,N) vec_new_ha(T,N,0,0)
374 #define vec_new_aligned(T,N,A) vec_new_ha(T,N,0,A)
382 #define vec_free_h(V,H) \
386 clib_mem_free (vec_header ((V), (H))); \
395 #define vec_free(V) vec_free_h(V,0)
403 #define vec_free_header(h) clib_mem_free (h)
415 #define vec_dup_ha_numa(V,H,A,S) \
417 __typeof__ ((V)[0]) * _v(v) = 0; \
418 uword _v(l) = vec_len (V); \
421 vec_resize_has (_v(v), _v(l), (H), (A), (S)); \
422 clib_memcpy_fast (_v(v), (V), _v(l) * sizeof ((V)[0]));\
435 #define vec_dup_ha(V,H,A) \
436 vec_dup_ha_numa(V,H,A,VEC_NUMA_UNSPECIFIED)
444 #define vec_dup(V) vec_dup_ha(V,0,0)
453 #define vec_dup_aligned(V,A) vec_dup_ha(V,0,A)
461 #define vec_copy(DST,SRC) clib_memcpy_fast (DST, SRC, vec_len (DST) * \
470 #define vec_clone(NEW_V,OLD_V) \
473 (NEW_V) = _vec_resize ((NEW_V), vec_len (OLD_V), \
474 vec_len (OLD_V) * sizeof ((NEW_V)[0]), (0), (0)); \
487 #define vec_validate_han(V,I,H,A,N) \
490 STATIC_ASSERT(A==0 || ((A % sizeof(V[0]))==0) \
491 || ((sizeof(V[0]) % A) == 0), \
492 "vector validate aligned on incorrectly sized object"); \
494 word _v(l) = vec_len (V); \
495 if (_v(i) >= _v(l)) \
498 if (PREDICT_FALSE(N != VEC_NUMA_UNSPECIFIED)) \
500 oldheap = clib_mem_get_per_cpu_heap(); \
501 clib_mem_set_per_cpu_heap (clib_mem_get_per_numa_heap(N)); \
504 vec_resize_ha ((V), 1 + (_v(i) - _v(l)), (H), (A)); \
507 clib_memset ((V) + _v(l), 0, \
508 (1 + (_v(i) - _v(l))) * sizeof ((V)[0])); \
510 if (PREDICT_FALSE (N != VEC_NUMA_UNSPECIFIED)) \
511 clib_mem_set_per_cpu_heap (oldheap); \
515 #define vec_validate_ha(V,I,H,A) vec_validate_han(V,I,H,A,VEC_NUMA_UNSPECIFIED)
524 #define vec_validate(V,I) vec_validate_ha(V,I,0,0)
535 #define vec_validate_aligned(V,I,A) vec_validate_ha(V,I,0,A)
547 #define vec_validate_init_empty_ha(V,I,INIT,H,A) \
550 word _v(l) = vec_len (V); \
551 if (_v(i) >= _v(l)) \
553 vec_resize_ha ((V), 1 + (_v(i) - _v(l)), (H), (A)); \
554 while (_v(l) <= _v(i)) \
556 (V)[_v(l)] = (INIT); \
571 #define vec_validate_init_empty(V,I,INIT) \
572 vec_validate_init_empty_ha(V,I,INIT,0,0)
583 #define vec_validate_init_empty_aligned(V,I,INIT,A) \
584 vec_validate_init_empty_ha(V,I,INIT,0,A)
594 #define vec_add1_ha(V,E,H,A) \
596 word _v(l) = vec_len (V); \
597 V = _vec_resize ((V), 1, (_v(l) + 1) * sizeof ((V)[0]), (H), (A)); \
607 #define vec_add1(V,E) vec_add1_ha(V,E,0,0)
616 #define vec_add1_aligned(V,E,A) vec_add1_ha(V,E,0,A)
628 #define vec_add2_ha(V,P,N,H,A) \
631 word _v(l) = vec_len (V); \
632 V = _vec_resize ((V), _v(n), (_v(l) + _v(n)) * sizeof ((V)[0]), (H), (A)); \
645 #define vec_add2(V,P,N) vec_add2_ha(V,P,N,0,0)
657 #define vec_add2_aligned(V,P,N,A) vec_add2_ha(V,P,N,0,A)
668 #define vec_add_ha(V, E, N, H, A) \
672 if (PREDICT_TRUE (_v (n) > 0)) \
674 word _v (l) = vec_len (V); \
675 V = _vec_resize ((V), _v (n), (_v (l) + _v (n)) * sizeof ((V)[0]), \
677 clib_memcpy_fast ((V) + _v (l), (E), _v (n) * sizeof ((V)[0])); \
689 #define vec_add(V,E,N) vec_add_ha(V,E,N,0,0)
699 #define vec_add_aligned(V,E,N,A) vec_add_ha(V,E,N,0,A)
708 uword _v(l) = vec_len (V); \
709 ASSERT (_v(l) > 0); \
711 _vec_len (V) = _v (l); \
722 #define vec_pop2(V,E) \
724 uword _v(l) = vec_len (V); \
725 if (_v(l) > 0) (E) = vec_pop (V); \
740 #define vec_insert_init_empty_ha(V,N,M,INIT,H,A) \
742 word _v(l) = vec_len (V); \
745 V = _vec_resize ((V), \
747 (_v(l) + _v(n))*sizeof((V)[0]), \
749 ASSERT (_v(m) <= _v(l)); \
750 memmove ((V) + _v(m) + _v(n), \
752 (_v(l) - _v(m)) * sizeof ((V)[0])); \
753 clib_memset ((V) + _v(m), INIT, _v(n) * sizeof ((V)[0])); \
766 #define vec_insert_ha(V,N,M,H,A) vec_insert_init_empty_ha(V,N,M,0,H,A)
776 #define vec_insert(V,N,M) vec_insert_ha(V,N,M,0,0)
787 #define vec_insert_aligned(V,N,M,A) vec_insert_ha(V,N,M,0,A)
799 #define vec_insert_init_empty(V,N,M,INIT) \
800 vec_insert_init_empty_ha(V,N,M,INIT,0,0)
813 #define vec_insert_init_empty_aligned(V,N,M,INIT,A) \
814 vec_insert_init_empty_ha(V,N,M,INIT,0,A)
828 #define vec_insert_elts_ha(V, E, N, M, H, A) \
832 if (PREDICT_TRUE (_v (n) > 0)) \
834 word _v (l) = vec_len (V); \
836 V = _vec_resize ((V), _v (n), (_v (l) + _v (n)) * sizeof ((V)[0]), \
838 ASSERT (_v (m) <= _v (l)); \
839 memmove ((V) + _v (m) + _v (n), (V) + _v (m), \
840 (_v (l) - _v (m)) * sizeof ((V)[0])); \
841 clib_memcpy_fast ((V) + _v (m), (E), _v (n) * sizeof ((V)[0])); \
855 #define vec_insert_elts(V,E,N,M) vec_insert_elts_ha(V,E,N,M,0,0)
867 #define vec_insert_elts_aligned(V,E,N,M,A) vec_insert_elts_ha(V,E,N,M,0,A)
876 #define vec_delete(V,N,M) \
878 word _v(l) = vec_len (V); \
882 if (_v(l) - _v(n) - _v(m) > 0) \
883 memmove ((V) + _v(m), (V) + _v(m) + _v(n), \
884 (_v(l) - _v(n) - _v(m)) * sizeof ((V)[0])); \
887 clib_memset ((V) + _v(l) - _v(n), 0, _v(n) * sizeof ((V)[0])); \
888 _vec_len (V) -= _v(n); \
889 CLIB_MEM_POISON(vec_end(V), _v(n) * sizeof ((V)[0])); \
897 #define vec_del1(v,i) \
899 uword _vec_del_l = _vec_len (v) - 1; \
900 uword _vec_del_i = (i); \
901 if (_vec_del_i < _vec_del_l) \
902 (v)[_vec_del_i] = (v)[_vec_del_l]; \
903 _vec_len (v) = _vec_del_l; \
904 CLIB_MEM_POISON(vec_end(v), sizeof ((v)[0])); \
912 #define vec_append(v1, v2) \
915 uword _v (l1) = vec_len (v1); \
916 uword _v (l2) = vec_len (v2); \
918 if (PREDICT_TRUE (_v (l2) > 0)) \
920 v1 = _vec_resize ((v1), _v (l2), \
921 (_v (l1) + _v (l2)) * sizeof ((v1)[0]), 0, 0); \
922 clib_memcpy_fast ((v1) + _v (l1), (v2), \
923 _v (l2) * sizeof ((v2)[0])); \
934 #define vec_append_aligned(v1, v2, align) \
937 uword _v (l1) = vec_len (v1); \
938 uword _v (l2) = vec_len (v2); \
940 if (PREDICT_TRUE (_v (l2) > 0)) \
943 (v1), _v (l2), (_v (l1) + _v (l2)) * sizeof ((v1)[0]), 0, align); \
944 clib_memcpy_fast ((v1) + _v (l1), (v2), \
945 _v (l2) * sizeof ((v2)[0])); \
955 #define vec_prepend(v1, v2) \
958 uword _v (l1) = vec_len (v1); \
959 uword _v (l2) = vec_len (v2); \
961 if (PREDICT_TRUE (_v (l2) > 0)) \
963 v1 = _vec_resize ((v1), _v (l2), \
964 (_v (l1) + _v (l2)) * sizeof ((v1)[0]), 0, 0); \
965 memmove ((v1) + _v (l2), (v1), _v (l1) * sizeof ((v1)[0])); \
966 clib_memcpy_fast ((v1), (v2), _v (l2) * sizeof ((v2)[0])); \
977 #define vec_prepend_aligned(v1, v2, align) \
980 uword _v (l1) = vec_len (v1); \
981 uword _v (l2) = vec_len (v2); \
983 if (PREDICT_TRUE (_v (l2) > 0)) \
986 (v1), _v (l2), (_v (l1) + _v (l2)) * sizeof ((v1)[0]), 0, align); \
987 memmove ((v1) + _v (l2), (v1), _v (l1) * sizeof ((v1)[0])); \
988 clib_memcpy_fast ((v1), (v2), _v (l2) * sizeof ((v2)[0])); \
996 #define vec_zero(var) \
999 clib_memset ((var), 0, vec_len (var) * sizeof ((var)[0])); \
1006 #define vec_set(v,val) \
1009 __typeof__ ((v)[0]) _val = (val); \
1010 for (_v(i) = 0; _v(i) < vec_len (v); _v(i)++) \
1011 (v)[_v(i)] = _val; \
1024 #define vec_is_equal(v1,v2) \
1025 (vec_len (v1) == vec_len (v2) && ! memcmp ((v1), (v2), vec_len (v1) * sizeof ((v1)[0])))
1034 #define vec_cmp(v1,v2) \
1036 word _v(i), _v(cmp), _v(l); \
1037 _v(l) = clib_min (vec_len (v1), vec_len (v2)); \
1039 for (_v(i) = 0; _v(i) < _v(l); _v(i)++) { \
1040 _v(cmp) = (v1)[_v(i)] - (v2)[_v(i)]; \
1044 if (_v(cmp) == 0 && _v(l) > 0) \
1045 _v(cmp) = vec_len(v1) - vec_len(v2); \
1046 (_v(cmp) < 0 ? -1 : (_v(cmp) > 0 ? +1 : 0)); \
1055 #define vec_search(v,E) \
1058 while (_v(i) < vec_len(v)) \
1060 if ((v)[_v(i)] == E) \
1064 if (_v(i) == vec_len(v)) \
1076 #define vec_search_with_function(v,E,fn) \
1079 while (_v(i) < vec_len(v)) \
1081 if (0 != fn(&(v)[_v(i)], (E))) \
1085 if (_v(i) == vec_len(v)) \
1098 #define vec_sort_with_function(vec,f) \
1100 if (vec_len (vec) > 1) \
1101 qsort (vec, vec_len (vec), sizeof (vec[0]), (void *) (f)); \
1110 #define vec_validate_init_c_string(V, S, L) \
1112 vec_reset_length (V); \
1113 vec_validate ((V), (L)); \
1115 clib_memcpy_fast ((V), (S), (L)); \
1125 #define vec_c_string_is_terminated(V) \
1126 (((V) != 0) && (vec_len (V) != 0) && ((V)[vec_len ((V)) - 1] == 0))
1133 #define vec_terminate_c_string(V) \
1135 u32 vl = vec_len ((V)); \
1136 if (!vec_c_string_is_terminated(V)) \
1138 vec_validate ((V), vl); \
static uword clib_mem_is_vec(void *v)
Predicate function, says whether the supplied vector is a clib heap object.
#define VEC_NUMA_UNSPECIFIED
uword clib_mem_is_vec_h(void *v, uword header_bytes)
Predicate function, says whether the supplied vector is a clib heap object (general version).
static void * clib_mem_get_per_numa_heap(u32 numa_id)
static clib_mem_heap_t * clib_mem_get_per_cpu_heap(void)
static uword clib_mem_size(void *p)
void vec_free_not_inline(void *v)
#define CLIB_MEM_UNPOISON(a, s)
static void * clib_mem_set_per_cpu_heap(void *new_heap)
void * vec_resize_allocate_memory(void *v, word length_increment, uword data_bytes, uword header_bytes, uword data_align, uword numa_id)
Low-level resize allocation function, usually not called directly.
static uword vec_header_bytes(uword header_bytes)
static uword clib_mem_is_heap_object(void *p)