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(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;
235 #define _v(var) _vec_##var 250 #define vec_resize_has(V,N,H,A,S) \ 253 word _v(l) = vec_len (V); \ 254 V = _vec_resize_numa ((V), _v(n), \ 255 (_v(l) + _v(n)) * sizeof ((V)[0]), \ 270 #define vec_resize_ha(V,N,H,A) vec_resize_has(V,N,H,A,VEC_NUMA_UNSPECIFIED) 281 #define vec_resize(V,N) vec_resize_ha(V,N,0,0) 294 #define vec_resize_aligned(V,N,A) vec_resize_ha(V,N,0,A) 305 #define vec_alloc_ha(V,N,H,A) \ 307 uword _v(l) = vec_len (V); \ 308 vec_resize_ha (V, N, H, A); \ 309 _vec_len (V) = _v(l); \ 319 #define vec_alloc(V,N) vec_alloc_ha(V,N,0,0) 328 #define vec_alloc_aligned(V,N,A) vec_alloc_ha(V,N,0,A) 337 #define vec_new_ha(T,N,H,A) \ 340 (T *)_vec_resize ((T *) 0, _v(n), _v(n) * sizeof (T), (H), (A)); \ 350 #define vec_new(T,N) vec_new_ha(T,N,0,0) 359 #define vec_new_aligned(T,N,A) vec_new_ha(T,N,0,A) 367 #define vec_free_h(V,H) \ 371 clib_mem_free (vec_header ((V), (H))); \ 380 #define vec_free(V) vec_free_h(V,0) 386 #define vec_free_header(h) clib_mem_free (h) 398 #define vec_dup_ha_numa(V,H,A,S) \ 400 __typeof__ ((V)[0]) * _v(v) = 0; \ 401 uword _v(l) = vec_len (V); \ 404 vec_resize_has (_v(v), _v(l), (H), (A), (S)); \ 405 clib_memcpy_fast (_v(v), (V), _v(l) * sizeof ((V)[0]));\ 418 #define vec_dup_ha(V,H,A) \ 419 vec_dup_ha_numa(V,H,A,VEC_NUMA_UNSPECIFIED) 427 #define vec_dup(V) vec_dup_ha(V,0,0) 436 #define vec_dup_aligned(V,A) vec_dup_ha(V,0,A) 444 #define vec_copy(DST,SRC) clib_memcpy_fast (DST, SRC, vec_len (DST) * \ 453 #define vec_clone(NEW_V,OLD_V) \ 456 (NEW_V) = _vec_resize ((NEW_V), vec_len (OLD_V), \ 457 vec_len (OLD_V) * sizeof ((NEW_V)[0]), (0), (0)); \ 470 #define vec_validate_han(V,I,H,A,N) \ 473 STATIC_ASSERT(A==0 || ((A % sizeof(V[0]))==0) \ 474 || ((sizeof(V[0]) % A) == 0), \ 475 "vector validate aligned on incorrectly sized object"); \ 477 word _v(l) = vec_len (V); \ 478 if (_v(i) >= _v(l)) \ 481 if (PREDICT_FALSE(N != VEC_NUMA_UNSPECIFIED)) \ 483 oldheap = clib_mem_get_per_cpu_heap(); \ 484 clib_mem_set_per_cpu_heap (clib_mem_get_per_numa_heap(N)); \ 487 vec_resize_ha ((V), 1 + (_v(i) - _v(l)), (H), (A)); \ 490 clib_memset ((V) + _v(l), 0, \ 491 (1 + (_v(i) - _v(l))) * sizeof ((V)[0])); \ 493 if (PREDICT_FALSE (N != VEC_NUMA_UNSPECIFIED)) \ 494 clib_mem_set_per_cpu_heap (oldheap); \ 498 #define vec_validate_ha(V,I,H,A) vec_validate_han(V,I,H,A,VEC_NUMA_UNSPECIFIED) 507 #define vec_validate(V,I) vec_validate_ha(V,I,0,0) 518 #define vec_validate_aligned(V,I,A) vec_validate_ha(V,I,0,A) 530 #define vec_validate_init_empty_ha(V,I,INIT,H,A) \ 533 word _v(l) = vec_len (V); \ 534 if (_v(i) >= _v(l)) \ 536 vec_resize_ha ((V), 1 + (_v(i) - _v(l)), (H), (A)); \ 537 while (_v(l) <= _v(i)) \ 539 (V)[_v(l)] = (INIT); \ 554 #define vec_validate_init_empty(V,I,INIT) \ 555 vec_validate_init_empty_ha(V,I,INIT,0,0) 566 #define vec_validate_init_empty_aligned(V,I,INIT,A) \ 567 vec_validate_init_empty_ha(V,I,INIT,0,A) 577 #define vec_add1_ha(V,E,H,A) \ 579 word _v(l) = vec_len (V); \ 580 V = _vec_resize ((V), 1, (_v(l) + 1) * sizeof ((V)[0]), (H), (A)); \ 590 #define vec_add1(V,E) vec_add1_ha(V,E,0,0) 599 #define vec_add1_aligned(V,E,A) vec_add1_ha(V,E,0,A) 611 #define vec_add2_ha(V,P,N,H,A) \ 614 word _v(l) = vec_len (V); \ 615 V = _vec_resize ((V), _v(n), (_v(l) + _v(n)) * sizeof ((V)[0]), (H), (A)); \ 628 #define vec_add2(V,P,N) vec_add2_ha(V,P,N,0,0) 640 #define vec_add2_aligned(V,P,N,A) vec_add2_ha(V,P,N,0,A) 651 #define vec_add_ha(V,E,N,H,A) \ 654 word _v(l) = vec_len (V); \ 655 V = _vec_resize ((V), _v(n), (_v(l) + _v(n)) * sizeof ((V)[0]), (H), (A)); \ 656 clib_memcpy_fast ((V) + _v(l), (E), _v(n) * sizeof ((V)[0])); \ 666 #define vec_add(V,E,N) vec_add_ha(V,E,N,0,0) 676 #define vec_add_aligned(V,E,N,A) vec_add_ha(V,E,N,0,A) 685 uword _v(l) = vec_len (V); \ 686 ASSERT (_v(l) > 0); \ 688 _vec_len (V) = _v (l); \ 699 #define vec_pop2(V,E) \ 701 uword _v(l) = vec_len (V); \ 702 if (_v(l) > 0) (E) = vec_pop (V); \ 717 #define vec_insert_init_empty_ha(V,N,M,INIT,H,A) \ 719 word _v(l) = vec_len (V); \ 722 V = _vec_resize ((V), \ 724 (_v(l) + _v(n))*sizeof((V)[0]), \ 726 ASSERT (_v(m) <= _v(l)); \ 727 memmove ((V) + _v(m) + _v(n), \ 729 (_v(l) - _v(m)) * sizeof ((V)[0])); \ 730 clib_memset ((V) + _v(m), INIT, _v(n) * sizeof ((V)[0])); \ 743 #define vec_insert_ha(V,N,M,H,A) vec_insert_init_empty_ha(V,N,M,0,H,A) 753 #define vec_insert(V,N,M) vec_insert_ha(V,N,M,0,0) 764 #define vec_insert_aligned(V,N,M,A) vec_insert_ha(V,N,M,0,A) 776 #define vec_insert_init_empty(V,N,M,INIT) \ 777 vec_insert_init_empty_ha(V,N,M,INIT,0,0) 790 #define vec_insert_init_empty_aligned(V,N,M,INIT,A) \ 791 vec_insert_init_empty_ha(V,N,M,INIT,0,A) 805 #define vec_insert_elts_ha(V,E,N,M,H,A) \ 807 word _v(l) = vec_len (V); \ 810 V = _vec_resize ((V), \ 812 (_v(l) + _v(n))*sizeof((V)[0]), \ 814 ASSERT (_v(m) <= _v(l)); \ 815 memmove ((V) + _v(m) + _v(n), \ 817 (_v(l) - _v(m)) * sizeof ((V)[0])); \ 818 clib_memcpy_fast ((V) + _v(m), (E), \ 819 _v(n) * sizeof ((V)[0])); \ 831 #define vec_insert_elts(V,E,N,M) vec_insert_elts_ha(V,E,N,M,0,0) 843 #define vec_insert_elts_aligned(V,E,N,M,A) vec_insert_elts_ha(V,E,N,M,0,A) 852 #define vec_delete(V,N,M) \ 854 word _v(l) = vec_len (V); \ 858 if (_v(l) - _v(n) - _v(m) > 0) \ 859 memmove ((V) + _v(m), (V) + _v(m) + _v(n), \ 860 (_v(l) - _v(n) - _v(m)) * sizeof ((V)[0])); \ 863 clib_memset ((V) + _v(l) - _v(n), 0, _v(n) * sizeof ((V)[0])); \ 864 _vec_len (V) -= _v(n); \ 865 CLIB_MEM_POISON(vec_end(V), _v(n) * sizeof ((V)[0])); \ 873 #define vec_del1(v,i) \ 875 uword _vec_del_l = _vec_len (v) - 1; \ 876 uword _vec_del_i = (i); \ 877 if (_vec_del_i < _vec_del_l) \ 878 (v)[_vec_del_i] = (v)[_vec_del_l]; \ 879 _vec_len (v) = _vec_del_l; \ 880 CLIB_MEM_POISON(vec_end(v), sizeof ((v)[0])); \ 888 #define vec_append(v1,v2) \ 890 uword _v(l1) = vec_len (v1); \ 891 uword _v(l2) = vec_len (v2); \ 893 v1 = _vec_resize ((v1), _v(l2), \ 894 (_v(l1) + _v(l2)) * sizeof ((v1)[0]), 0, 0); \ 895 clib_memcpy_fast ((v1) + _v(l1), (v2), _v(l2) * sizeof ((v2)[0])); \ 904 #define vec_append_aligned(v1,v2,align) \ 906 uword _v(l1) = vec_len (v1); \ 907 uword _v(l2) = vec_len (v2); \ 909 v1 = _vec_resize ((v1), _v(l2), \ 910 (_v(l1) + _v(l2)) * sizeof ((v1)[0]), 0, align); \ 911 clib_memcpy_fast ((v1) + _v(l1), (v2), _v(l2) * sizeof ((v2)[0])); \ 919 #define vec_prepend(v1,v2) \ 921 uword _v(l1) = vec_len (v1); \ 922 uword _v(l2) = vec_len (v2); \ 924 v1 = _vec_resize ((v1), _v(l2), \ 925 (_v(l1) + _v(l2)) * sizeof ((v1)[0]), 0, 0); \ 926 memmove ((v1) + _v(l2), (v1), _v(l1) * sizeof ((v1)[0])); \ 927 clib_memcpy_fast ((v1), (v2), _v(l2) * sizeof ((v2)[0])); \ 936 #define vec_prepend_aligned(v1,v2,align) \ 938 uword _v(l1) = vec_len (v1); \ 939 uword _v(l2) = vec_len (v2); \ 941 v1 = _vec_resize ((v1), _v(l2), \ 942 (_v(l1) + _v(l2)) * sizeof ((v1)[0]), 0, align); \ 943 memmove ((v1) + _v(l2), (v1), _v(l1) * sizeof ((v1)[0])); \ 944 clib_memcpy_fast ((v1), (v2), _v(l2) * sizeof ((v2)[0])); \ 951 #define vec_zero(var) \ 954 clib_memset ((var), 0, vec_len (var) * sizeof ((var)[0])); \ 961 #define vec_set(v,val) \ 964 __typeof__ ((v)[0]) _val = (val); \ 965 for (_v(i) = 0; _v(i) < vec_len (v); _v(i)++) \ 979 #define vec_is_equal(v1,v2) \ 980 (vec_len (v1) == vec_len (v2) && ! memcmp ((v1), (v2), vec_len (v1) * sizeof ((v1)[0]))) 989 #define vec_cmp(v1,v2) \ 991 word _v(i), _v(cmp), _v(l); \ 992 _v(l) = clib_min (vec_len (v1), vec_len (v2)); \ 994 for (_v(i) = 0; _v(i) < _v(l); _v(i)++) { \ 995 _v(cmp) = (v1)[_v(i)] - (v2)[_v(i)]; \ 999 if (_v(cmp) == 0 && _v(l) > 0) \ 1000 _v(cmp) = vec_len(v1) - vec_len(v2); \ 1001 (_v(cmp) < 0 ? -1 : (_v(cmp) > 0 ? +1 : 0)); \ 1010 #define vec_search(v,E) \ 1013 while (_v(i) < vec_len(v)) \ 1015 if ((v)[_v(i)] == E) \ 1019 if (_v(i) == vec_len(v)) \ 1031 #define vec_search_with_function(v,E,fn) \ 1034 while (_v(i) < vec_len(v)) \ 1036 if (0 != fn(&(v)[_v(i)], (E))) \ 1040 if (_v(i) == vec_len(v)) \ 1053 #define vec_sort_with_function(vec,f) \ 1055 if (vec_len (vec) > 1) \ 1056 qsort (vec, vec_len (vec), sizeof (vec[0]), (void *) (f)); \ 1065 #define vec_validate_init_c_string(V, S, L) \ 1067 vec_reset_length (V); \ 1068 vec_validate ((V), (L)); \ 1070 clib_memcpy_fast ((V), (S), (L)); \ 1080 #define vec_c_string_is_terminated(V) \ 1081 (((V) != 0) && (vec_len (V) != 0) && ((V)[vec_len ((V)) - 1] == 0)) 1088 #define vec_terminate_c_string(V) \ 1090 u32 vl = vec_len ((V)); \ 1091 if (!vec_c_string_is_terminated(V)) \ 1093 vec_validate ((V), vl); \ 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)...
#define CLIB_MEM_UNPOISON(a, s)
Optimized string handling code, including c11-compliant "safe C library" variants.
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.
#define VEC_NUMA_UNSPECIFIED
static uword vec_header_bytes(uword header_bytes)
static void * clib_mem_get_per_cpu_heap(void)
static uword clib_mem_size(void *p)
static uword clib_mem_is_heap_object(void *p)
static void * clib_mem_get_per_numa_heap(u32 numa_id)
static void * clib_mem_set_per_cpu_heap(u8 *new_heap)
static uword clib_mem_is_vec(void *v)
Predicate function, says whether the supplied vector is a clib heap object.
Vector bootstrap header file.