From 8bea589cfe0fca1a6f560e16ca66a4cf199041a2 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Mon, 4 Apr 2022 22:40:45 +0200 Subject: vppinfra: make _vec_len() read-only Use of _vec_len() to set vector length breaks address sanitizer. Users should use vec_set_len(), vec_inc_len(), vec_dec_len () instead. Type: improvement Change-Id: I441ae948771eb21c23a61f3ff9163bdad74a2cb8 Signed-off-by: Damjan Marion --- src/vppinfra/bitmap.h | 51 ++++++++++++++++++++----------------- src/vppinfra/elf.c | 2 +- src/vppinfra/elog.c | 2 +- src/vppinfra/fifo.h | 2 +- src/vppinfra/format.c | 2 +- src/vppinfra/hash.c | 2 +- src/vppinfra/heap.c | 8 +++--- src/vppinfra/linux/mem.c | 2 +- src/vppinfra/linux/sysfs.c | 6 ++--- src/vppinfra/macros.c | 5 ++-- src/vppinfra/mem_dlmalloc.c | 2 +- src/vppinfra/mhash.c | 6 ++--- src/vppinfra/pool.h | 8 +++--- src/vppinfra/random_buffer.h | 2 +- src/vppinfra/serialize.c | 10 ++++---- src/vppinfra/socket.c | 4 +-- src/vppinfra/sparse_vec.h | 2 +- src/vppinfra/test_bihash_template.c | 3 +-- src/vppinfra/test_fpool.c | 2 +- src/vppinfra/test_socket.c | 2 +- src/vppinfra/timing_wheel.c | 8 +++--- src/vppinfra/tw_timer_template.c | 4 +-- src/vppinfra/unformat.c | 6 ++--- src/vppinfra/unix-misc.c | 2 +- src/vppinfra/vec.c | 2 +- src/vppinfra/vec_bootstrap.h | 20 ++++++++------- 26 files changed, 84 insertions(+), 81 deletions(-) (limited to 'src/vppinfra') diff --git a/src/vppinfra/bitmap.h b/src/vppinfra/bitmap.h index 096d3f1aa4a..02f9c7e55ab 100644 --- a/src/vppinfra/bitmap.h +++ b/src/vppinfra/bitmap.h @@ -142,7 +142,7 @@ _clib_bitmap_remove_trailing_zeros (uword * a) for (i = _vec_len (a) - 1; i >= 0; i--) if (a[i] != 0) break; - _vec_len (a) = i + 1; + vec_set_len (a, i + 1); } return a; } @@ -518,29 +518,32 @@ always_inline uword *clib_bitmap_or (uword * ai, uword * bi); always_inline uword *clib_bitmap_xor (uword * ai, uword * bi); /* ALU function definition macro for functions taking two bitmaps. */ -#define _(name, body, check_zero) \ -always_inline uword * \ -clib_bitmap_##name (uword * ai, uword * bi) \ -{ \ - uword i, a, b, bi_len, n_trailing_zeros; \ - \ - n_trailing_zeros = 0; \ - bi_len = vec_len (bi); \ - if (bi_len > 0) \ - clib_bitmap_vec_validate (ai, bi_len - 1); \ - for (i = 0; i < vec_len (ai); i++) \ - { \ - a = ai[i]; \ - b = i < bi_len ? bi[i] : 0; \ - do { body; } while (0); \ - ai[i] = a; \ - if (check_zero) \ - n_trailing_zeros = a ? 0 : (n_trailing_zeros + 1); \ - } \ - if (check_zero) \ - _vec_len (ai) -= n_trailing_zeros; \ - return ai; \ -} +#define _(name, body, check_zero) \ + always_inline uword *clib_bitmap_##name (uword *ai, uword *bi) \ + { \ + uword i, a, b, bi_len, n_trailing_zeros; \ + \ + n_trailing_zeros = 0; \ + bi_len = vec_len (bi); \ + if (bi_len > 0) \ + clib_bitmap_vec_validate (ai, bi_len - 1); \ + for (i = 0; i < vec_len (ai); i++) \ + { \ + a = ai[i]; \ + b = i < bi_len ? bi[i] : 0; \ + do \ + { \ + body; \ + } \ + while (0); \ + ai[i] = a; \ + if (check_zero) \ + n_trailing_zeros = a ? 0 : (n_trailing_zeros + 1); \ + } \ + if (check_zero) \ + vec_dec_len (ai, n_trailing_zeros); \ + return ai; \ + } /* ALU functions: */ /* *INDENT-OFF* */ diff --git a/src/vppinfra/elf.c b/src/vppinfra/elf.c index 7a74fad4c4f..d11fd7e99a9 100644 --- a/src/vppinfra/elf.c +++ b/src/vppinfra/elf.c @@ -1975,7 +1975,7 @@ elf_create_section_with_contents (elf_main_t * em, if ((p = hash_get_mem (em->section_by_name, section_name))) { s = vec_elt_at_index (em->sections, p[0]); - _vec_len (s->contents) = 0; + vec_set_len (s->contents, 0); c = s->contents; } else diff --git a/src/vppinfra/elog.c b/src/vppinfra/elog.c index 8ae752eb6af..ddc09a37d72 100644 --- a/src/vppinfra/elog.c +++ b/src/vppinfra/elog.c @@ -494,7 +494,7 @@ elog_alloc_internal (elog_main_t * em, u32 n_events, int free_ring) em->event_ring_size = n_events = max_pow2 (n_events); vec_validate_aligned (em->event_ring, n_events, CLIB_CACHE_LINE_BYTES); - _vec_len (em->event_ring) = n_events; + vec_set_len (em->event_ring, n_events); } __clib_export void diff --git a/src/vppinfra/fifo.h b/src/vppinfra/fifo.h index 611fadb95d7..b6a8b8f5c3b 100644 --- a/src/vppinfra/fifo.h +++ b/src/vppinfra/fifo.h @@ -91,7 +91,7 @@ clib_fifo_reset (void *v) if (v) { f->head_index = f->tail_index = 0; - _vec_len (v) = 0; + vec_set_len (v, 0); } } diff --git a/src/vppinfra/format.c b/src/vppinfra/format.c index ccd999e582f..cf17b8a1acb 100644 --- a/src/vppinfra/format.c +++ b/src/vppinfra/format.c @@ -114,7 +114,7 @@ justify (u8 * s, format_info_t * fi, uword s_len_orig) l0 = l1; if (l1 > l0) - _vec_len (s) = l0; + vec_set_len (s, l0); else if (l0 > l1) { uword n = l0 - l1; diff --git a/src/vppinfra/hash.c b/src/vppinfra/hash.c index df740c5f659..7deff4a5bee 100644 --- a/src/vppinfra/hash.c +++ b/src/vppinfra/hash.c @@ -342,7 +342,7 @@ unset_indirect (void *v, uword i, hash_pair_t * q) else zero_pair (h, q); if (is_vec) - _vec_len (pi->pairs) -= 1; + vec_dec_len (pi->pairs, 1); else indirect_pair_set (pi, indirect_pair_get_log2_bytes (pi), len - 1); } diff --git a/src/vppinfra/heap.c b/src/vppinfra/heap.c index 47b6cf53214..066756b4db9 100644 --- a/src/vppinfra/heap.c +++ b/src/vppinfra/heap.c @@ -139,7 +139,7 @@ elt_delete (heap_header_t * h, heap_elt_t * e) if (e < l) vec_add1 (h->free_elts, e - h->elts); else - _vec_len (h->elts)--; + vec_dec_len (h->elts, 1); } /* @@ -200,7 +200,7 @@ elt_new (heap_header_t * h) if ((l = vec_len (h->free_elts)) > 0) { e = elt_at (h, h->free_elts[l - 1]); - _vec_len (h->free_elts) -= 1; + vec_dec_len (h->free_elts, 1); } else vec_add2 (h->elts, e, 1); @@ -276,7 +276,7 @@ remove_free_block (void *v, uword b, uword i) h->free_lists[b][i] = t; set_free_elt (v, elt_at (h, t), i); } - _vec_len (h->free_lists[b]) = l - 1; + vec_set_len (h->free_lists[b], l - 1); } static heap_elt_t * @@ -425,7 +425,7 @@ _heap_alloc (void *v, v = _vec_realloc (v, offset + align_size, elt_bytes, sizeof (h[0]), HEAP_DATA_ALIGN, 0); else - _vec_len (v) += align_size; + vec_inc_len (v, align_size); if (offset == 0) { diff --git a/src/vppinfra/linux/mem.c b/src/vppinfra/linux/mem.c index 6c3e036d951..9cf598d3c6f 100644 --- a/src/vppinfra/linux/mem.c +++ b/src/vppinfra/linux/mem.c @@ -261,7 +261,7 @@ clib_mem_vm_create_fd (clib_mem_page_sz_t log2_page_size, char *fmt, ...) /* memfd_create maximum string size is 249 chars without trailing zero */ if (vec_len (s) > 249) - _vec_len (s) = 249; + vec_set_len (s, 249); vec_add1 (s, 0); /* memfd_create introduced in kernel 3.17, we don't support older kernels */ diff --git a/src/vppinfra/linux/sysfs.c b/src/vppinfra/linux/sysfs.c index 758eaa1a86c..a3e122cf1e0 100644 --- a/src/vppinfra/linux/sysfs.c +++ b/src/vppinfra/linux/sysfs.c @@ -70,7 +70,7 @@ clib_sysfs_read (char *file_name, char *fmt, ...) return clib_error_return_unix (0, "read `%s'", file_name); } - _vec_len (s) = sz; + vec_set_len (s, sz); unformat_init_vector (&input, s); va_list va; @@ -154,7 +154,7 @@ clib_sysfs_set_nr_hugepages (int numa_node, int log2_page_size, int nr) goto done; } - _vec_len (p) -= 1; + vec_dec_len (p, 1); p = format (p, "/hugepages/hugepages-%ukB/nr_hugepages%c", page_size, 0); clib_sysfs_write ((char *) p, "%d", nr); @@ -207,7 +207,7 @@ clib_sysfs_get_xxx_hugepages (char *type, int numa_node, goto done; } - _vec_len (p) -= 1; + vec_dec_len (p, 1); p = format (p, "/hugepages/hugepages-%ukB/%s_hugepages%c", page_size, type, 0); error = clib_sysfs_read ((char *) p, "%d", val); diff --git a/src/vppinfra/macros.c b/src/vppinfra/macros.c index b8a8e1744aa..27a92a8abe2 100644 --- a/src/vppinfra/macros.c +++ b/src/vppinfra/macros.c @@ -175,7 +175,7 @@ clib_macro_eval (clib_macro_main_t * mm, i8 * s, i32 complain, u16 level, /* add results to answer */ vec_append (rv, ts); /* Remove NULL termination or the results are sad */ - _vec_len (rv) = vec_len (rv) - 1; + vec_set_len (rv, vec_len (rv) - 1); vec_free (ts); } else @@ -183,8 +183,7 @@ clib_macro_eval (clib_macro_main_t * mm, i8 * s, i32 complain, u16 level, if (complain) clib_warning ("Undefined Variable Reference: %s\n", varname); vec_append (rv, format (0, "UNSET ")); - _vec_len (rv) = vec_len (rv) - 1; - + vec_set_len (rv, vec_len (rv) - 1); } vec_free (varname); } diff --git a/src/vppinfra/mem_dlmalloc.c b/src/vppinfra/mem_dlmalloc.c index 3829e7c7740..fdde720bc73 100644 --- a/src/vppinfra/mem_dlmalloc.c +++ b/src/vppinfra/mem_dlmalloc.c @@ -101,7 +101,7 @@ mheap_get_trace (uword offset, uword size) if (i > 0) { trace_index = tm->trace_free_list[i - 1]; - _vec_len (tm->trace_free_list) = i - 1; + vec_set_len (tm->trace_free_list, i - 1); } else { diff --git a/src/vppinfra/mhash.c b/src/vppinfra/mhash.c index c556312e64f..f0f1aa470d7 100644 --- a/src/vppinfra/mhash.c +++ b/src/vppinfra/mhash.c @@ -295,7 +295,7 @@ mhash_set_mem (mhash_t * h, void *key, uword * new_value, uword * old_value) { i = h->key_vector_free_indices[l - 1]; k = vec_elt_at_index (h->key_vector_or_heap, i); - _vec_len (h->key_vector_free_indices) = l - 1; + vec_set_len (h->key_vector_free_indices, l - 1); } else { @@ -332,10 +332,10 @@ mhash_set_mem (mhash_t * h, void *key, uword * new_value, uword * old_value) if (key_alloc_from_free_list) { h->key_vector_free_indices[l] = i; - _vec_len (h->key_vector_free_indices) = l + 1; + vec_set_len (h->key_vector_free_indices, l + 1); } else - _vec_len (h->key_vector_or_heap) -= h->n_key_bytes; + vec_dec_len (h->key_vector_or_heap, h->n_key_bytes); } } diff --git a/src/vppinfra/pool.h b/src/vppinfra/pool.h index 4db1f7b6bdf..9f9194f59e2 100644 --- a/src/vppinfra/pool.h +++ b/src/vppinfra/pool.h @@ -184,7 +184,7 @@ _pool_get (void **pp, void **ep, uword align, int zero, uword elt_sz) e = p + index * elt_sz; ph->free_bitmap = clib_bitmap_andnoti_notrim (ph->free_bitmap, index); - _vec_len (ph->free_indices) = n_free - 1; + vec_set_len (ph->free_indices, n_free - 1); CLIB_MEM_UNPOISON (e, elt_sz); goto done; } @@ -294,7 +294,7 @@ _pool_put_index (void *p, uword index, uword elt_sz) if (ph->max_elts) { ph->free_indices[_vec_len (ph->free_indices)] = index; - _vec_len (ph->free_indices) += 1; + vec_inc_len (ph->free_indices, 1); } else vec_add1 (ph->free_indices, index); @@ -321,12 +321,12 @@ _pool_alloc (void **pp, uword n_elts, uword align, void *heap, uword elt_sz) pp[0] = _vec_realloc_inline (pp[0], len + n_elts, elt_sz, sizeof (pool_header_t), align, heap); - _vec_len (pp[0]) = len; + _vec_set_len (pp[0], len, elt_sz); CLIB_MEM_POISON (pp[0] + len * elt_sz, n_elts * elt_sz); ph = pool_header (pp[0]); vec_resize (ph->free_indices, n_elts); - _vec_len (ph->free_indices) -= n_elts; + vec_dec_len (ph->free_indices, n_elts); clib_bitmap_vec_validate (ph->free_bitmap, len + n_elts - 1); } diff --git a/src/vppinfra/random_buffer.h b/src/vppinfra/random_buffer.h index dded53163fc..078e9607caa 100644 --- a/src/vppinfra/random_buffer.h +++ b/src/vppinfra/random_buffer.h @@ -100,7 +100,7 @@ clib_random_buffer_get_data (clib_random_buffer_t * b, uword n_bytes) clib_random_buffer_fill (b, n_words); i = vec_len (b->buffer) - n_words; - _vec_len (b->buffer) = i; + vec_set_len (b->buffer, i); if (n_bytes < sizeof (uword)) { diff --git a/src/vppinfra/serialize.c b/src/vppinfra/serialize.c index 95eca96758a..d84d7ca06c5 100644 --- a/src/vppinfra/serialize.c +++ b/src/vppinfra/serialize.c @@ -714,7 +714,7 @@ serialize_write_not_inline (serialize_main_header_t * m, n_left_b -= n; n_left_o -= n; if (n_left_o == 0) - _vec_len (s->overflow_buffer) = 0; + vec_set_len (s->overflow_buffer, 0); else vec_delete (s->overflow_buffer, n, 0); } @@ -771,7 +771,7 @@ serialize_read_not_inline (serialize_main_header_t * m, if (n_left_o == 0 && s->overflow_buffer) { s->current_overflow_index = 0; - _vec_len (s->overflow_buffer) = 0; + vec_set_len (s->overflow_buffer, 0); } n_left_to_read = n_bytes_to_read; @@ -923,7 +923,7 @@ serialize_close_vector (serialize_main_t * m) serialize_close (m); /* frees overflow buffer */ if (s->buffer) - _vec_len (s->buffer) = s->current_buffer_index; + vec_set_len (s->buffer, s->current_buffer_index); result = s->buffer; clib_memset (m, 0, sizeof (m[0])); return result; @@ -1161,7 +1161,7 @@ clib_file_write (serialize_main_header_t * m, serialize_stream_t * s) serialize_error (m, clib_error_return_unix (0, "write")); } if (n == s->current_buffer_index) - _vec_len (s->buffer) = 0; + vec_set_len (s->buffer, 0); else vec_delete (s->buffer, n, 0); s->current_buffer_index = vec_len (s->buffer); @@ -1197,7 +1197,7 @@ serialize_open_clib_file_descriptor_helper (serialize_main_t * m, int fd, if (!is_read) { m->stream.n_buffer_bytes = vec_len (m->stream.buffer); - _vec_len (m->stream.buffer) = 0; + vec_set_len (m->stream.buffer, 0); } m->header.data_function = is_read ? clib_file_read : clib_file_write; diff --git a/src/vppinfra/socket.c b/src/vppinfra/socket.c index a09a390dab3..a3024ae7a8c 100644 --- a/src/vppinfra/socket.c +++ b/src/vppinfra/socket.c @@ -230,7 +230,7 @@ default_socket_write (clib_socket_t * s) else if (written > 0) { if (written == tx_len) - _vec_len (s->tx_buffer) = 0; + vec_set_len (s->tx_buffer, 0); else vec_delete (s->tx_buffer, written, 0); } @@ -278,7 +278,7 @@ default_socket_read (clib_socket_t * sock, int n_bytes) sock->flags |= CLIB_SOCKET_F_RX_END_OF_FILE; non_fatal: - _vec_len (sock->rx_buffer) += n_read - n_bytes; + vec_inc_len (sock->rx_buffer, n_read - n_bytes); return 0; } diff --git a/src/vppinfra/sparse_vec.h b/src/vppinfra/sparse_vec.h index 6cab868a8b2..dc9cb00380a 100644 --- a/src/vppinfra/sparse_vec.h +++ b/src/vppinfra/sparse_vec.h @@ -81,7 +81,7 @@ sparse_vec_new (uword elt_bytes, uword sparse_index_bits) /* heap */ 0); /* Make space for invalid entry (entry 0). */ - _vec_len (v) = 1; + _vec_find (v)->len = 1; h = sparse_vec_header (v); diff --git a/src/vppinfra/test_bihash_template.c b/src/vppinfra/test_bihash_template.c index ffed5c73287..155b8bd408d 100644 --- a/src/vppinfra/test_bihash_template.c +++ b/src/vppinfra/test_bihash_template.c @@ -522,8 +522,7 @@ test_bihash_main (test_main_t * tm) /* Preallocate hash table, key vector */ tm->key_hash = hash_create (tm->nitems, sizeof (uword)); vec_validate (tm->keys, tm->nitems - 1); - _vec_len (tm->keys) = 0; - + vec_set_len (tm->keys, 0); switch (which) { diff --git a/src/vppinfra/test_fpool.c b/src/vppinfra/test_fpool.c index e2d67f16907..02d9d219717 100644 --- a/src/vppinfra/test_fpool.c +++ b/src/vppinfra/test_fpool.c @@ -30,7 +30,7 @@ main (int argc, char *argv[]) clib_mem_init (0, 3ULL << 30); vec_validate (indices, NELTS - 1); - _vec_len (indices) = 0; + vec_set_len (indices, 0); pool_init_fixed (tp, NELTS); diff --git a/src/vppinfra/test_socket.c b/src/vppinfra/test_socket.c index ea0ae658943..3a0e6b29ce6 100644 --- a/src/vppinfra/test_socket.c +++ b/src/vppinfra/test_socket.c @@ -99,7 +99,7 @@ test_socket_main (unformat_input_t * input) break; if_verbose ("%v", s->rx_buffer); - _vec_len (s->rx_buffer) = 0; + vec_set_len (s->rx_buffer, 0); } error = clib_socket_close (s); diff --git a/src/vppinfra/timing_wheel.c b/src/vppinfra/timing_wheel.c index 2c46d72a2fe..edd878239cf 100644 --- a/src/vppinfra/timing_wheel.c +++ b/src/vppinfra/timing_wheel.c @@ -185,7 +185,7 @@ free_elt_vector (timing_wheel_t * w, timing_wheel_elt_t * ev) /* Poison free elements so we never use them by mistake. */ if (CLIB_DEBUG > 0) clib_memset (ev, ~0, vec_len (ev) * sizeof (ev[0])); - _vec_len (ev) = 0; + vec_set_len (ev, 0); vec_add1 (w->free_elt_vectors, ev); } @@ -459,7 +459,7 @@ expire_bin (timing_wheel_t * w, /* Adjust for deleted elts. */ if (j < e_len) - _vec_len (expired_user_data) -= e_len - j; + vec_dec_len (expired_user_data, e_len - j); free_elt_vector (w, e); @@ -613,7 +613,7 @@ timing_wheel_advance (timing_wheel_t * w, u64 advance_cpu_time, if (PREDICT_FALSE (current_ti != advance_ti)) { if (w->unexpired_elts_pending_insert) - _vec_len (w->unexpired_elts_pending_insert) = 0; + vec_set_len (w->unexpired_elts_pending_insert, 0); level_index = 0; while (current_ti != advance_ti) @@ -684,7 +684,7 @@ timing_wheel_advance (timing_wheel_t * w, u64 advance_cpu_time, { timing_wheel_elt_t *e; vec_foreach (e, w->unexpired_elts_pending_insert) insert_elt (w, e); - _vec_len (w->unexpired_elts_pending_insert) = 0; + vec_set_len (w->unexpired_elts_pending_insert, 0); } /* Don't advance until necessary. */ diff --git a/src/vppinfra/tw_timer_template.c b/src/vppinfra/tw_timer_template.c index 97c70b223ce..6e8a58dbfaf 100644 --- a/src/vppinfra/tw_timer_template.c +++ b/src/vppinfra/tw_timer_template.c @@ -424,7 +424,7 @@ TW (tw_timer_wheel_init) (TWT (tw_timer_wheel) * tw, tw->ticks_per_second = 1.0 / timer_interval_in_seconds; vec_validate (tw->expired_timer_handles, 0); - _vec_len (tw->expired_timer_handles) = 0; + vec_set_len (tw->expired_timer_handles, 0); for (ring = 0; ring < TW_TIMER_WHEELS; ring++) { @@ -536,7 +536,7 @@ static inline if (callback_vector_arg == 0) { - _vec_len (tw->expired_timer_handles) = 0; + vec_set_len (tw->expired_timer_handles, 0); callback_vector = tw->expired_timer_handles; } else diff --git a/src/vppinfra/unformat.c b/src/vppinfra/unformat.c index 3904b450f48..e8e5c28ea8c 100644 --- a/src/vppinfra/unformat.c +++ b/src/vppinfra/unformat.c @@ -952,7 +952,7 @@ parse_fail: if (!input_matches_format) input->index = input->buffer_marks[l - 1]; - _vec_len (input->buffer_marks) = l - 1; + vec_set_len (input->buffer_marks, l - 1); } return input_matches_format; @@ -987,7 +987,7 @@ unformat_user (unformat_input_t * input, unformat_function_t * func, ...) if (!result && input->index != UNFORMAT_END_OF_INPUT) input->index = input->buffer_marks[l]; - _vec_len (input->buffer_marks) = l; + vec_set_len (input->buffer_marks, l); return result; } @@ -1037,7 +1037,7 @@ clib_file_fill_buffer (unformat_input_t * input) vec_resize (input->buffer, 4096); n = read (fd, input->buffer + l, 4096); if (n > 0) - _vec_len (input->buffer) = l + n; + vec_set_len (input->buffer, l + n); if (n <= 0) return UNFORMAT_END_OF_INPUT; diff --git a/src/vppinfra/unix-misc.c b/src/vppinfra/unix-misc.c index 5559a2392fe..e73d01a15d6 100644 --- a/src/vppinfra/unix-misc.c +++ b/src/vppinfra/unix-misc.c @@ -158,7 +158,7 @@ unix_proc_file_contents (char *file, u8 ** result) if (bytes == 0) { - _vec_len (rv) = pos; + vec_set_len (rv, pos); break; } pos += bytes; diff --git a/src/vppinfra/vec.c b/src/vppinfra/vec.c index 805fdc02b7e..8bd0ec01f42 100644 --- a/src/vppinfra/vec.c +++ b/src/vppinfra/vec.c @@ -83,7 +83,7 @@ _vec_realloc (void *v, uword n_elts, uword elt_sz, uword hdr_sz, uword align, } CLIB_MEM_POISON (p + new_data_size, alloc_size - new_data_size); - _vec_len (v) = n_elts; + _vec_find (v)->len = n_elts; return v; } diff --git a/src/vppinfra/vec_bootstrap.h b/src/vppinfra/vec_bootstrap.h index d6451f3d172..0054802e8c1 100644 --- a/src/vppinfra/vec_bootstrap.h +++ b/src/vppinfra/vec_bootstrap.h @@ -116,21 +116,21 @@ vec_header_end (void *v) return v + vec_get_header_size (v); } -/** \brief Number of elements in vector (lvalue-capable) - - _vec_len (v) does not check for null, but can be used as an lvalue - (e.g. _vec_len (v) = 99). -*/ - -#define _vec_len(v) (_vec_find(v)->len) - /** \brief Number of elements in vector (rvalue-only, NULL tolerant) vec_len (v) checks for NULL, but cannot be used as an lvalue. If in doubt, use vec_len... */ +static_always_inline u32 +__vec_len (void *v) +{ + return _vec_find (v)->len; +} + +#define _vec_len(v) __vec_len ((void *) (v)) #define vec_len(v) ((v) ? _vec_len(v) : 0) + u32 vec_len_not_inline (void *v); /** \brief Number of data bytes in vector. */ @@ -180,10 +180,12 @@ _vec_set_len (void *v, uword len, uword elt_sz) else if (len > old_len) CLIB_MEM_POISON (v + len * elt_sz, (old_len - len) * elt_sz); - _vec_len (v) = len; + _vec_find (v)->len = len; } #define vec_set_len(v, l) _vec_set_len ((void *) v, l, _vec_elt_sz (v)) +#define vec_inc_len(v, l) vec_set_len (v, _vec_len (v) + (l)) +#define vec_dec_len(v, l) vec_set_len (v, _vec_len (v) - (l)) /** \brief Reset vector length to zero NULL-pointer tolerant -- cgit 1.2.3-korg