LCOV - code coverage report
Current view: top level - vppinfra - vec.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 63 68 92.6 %
Date: 2023-10-26 01:39:38 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: Apache-2.0
       2             :  * Copyright(c) 2022 Cisco Systems, Inc.
       3             :  */
       4             : 
       5             : #include <vppinfra/vec.h>
       6             : #include <vppinfra/mem.h>
       7             : 
       8             : #ifndef CLIB_VECTOR_GROW_BY_ONE
       9             : #define CLIB_VECTOR_GROW_BY_ONE 0
      10             : #endif
      11             : 
      12             : __clib_export uword
      13  1485740000 : vec_mem_size (void *v)
      14             : {
      15  1485740000 :   return v ? clib_mem_size (v - vec_get_header_size (v)) : 0;
      16             : }
      17             : 
      18             : __clib_export void *
      19    51168800 : _vec_alloc_internal (uword n_elts, const vec_attr_t *const attr)
      20             : {
      21             :   uword req_size, alloc_size, data_offset, align;
      22    51168800 :   uword elt_sz = attr->elt_sz;
      23    51168800 :   void *p, *v, *heap = attr->heap;
      24             : 
      25             :   /* alignment must be power of 2 */
      26    51168800 :   align = clib_max (attr->align, VEC_MIN_ALIGN);
      27    51168800 :   ASSERT (count_set_bits (align) == 1);
      28             : 
      29             :   /* calc offset where vector data starts */
      30    51168800 :   data_offset = attr->hdr_sz + sizeof (vec_header_t);
      31    51168800 :   data_offset += heap ? sizeof (void *) : 0;
      32    51168800 :   data_offset = round_pow2 (data_offset, align);
      33             : 
      34    51168800 :   req_size = data_offset + n_elts * elt_sz;
      35    51168800 :   p = clib_mem_heap_alloc_aligned (heap, req_size, align);
      36             : 
      37             :   /* zero out whole alocation */
      38    51169700 :   alloc_size = clib_mem_size (p);
      39    51169600 :   clib_mem_unpoison (p, alloc_size);
      40    51169600 :   clib_memset_u8 (p, 0, alloc_size);
      41             : 
      42             :   /* fill vector header */
      43    51169600 :   v = p + data_offset;
      44    51169600 :   _vec_find (v)->len = n_elts;
      45    51169600 :   _vec_find (v)->hdr_size = data_offset / VEC_MIN_ALIGN;
      46    51169600 :   _vec_find (v)->log2_align = min_log2 (align);
      47    51169600 :   if (heap)
      48             :     {
      49        5840 :       _vec_find (v)->default_heap = 0;
      50        5840 :       _vec_heap (v) = heap;
      51             :     }
      52             :   else
      53    51163800 :     _vec_find (v)->default_heap = 1;
      54             : 
      55             :   /* poison extra space given by allocator */
      56    51169600 :   clib_mem_poison (p + req_size, alloc_size - req_size);
      57    51169600 :   _vec_set_grow_elts (v, (alloc_size - req_size) / elt_sz);
      58    51169500 :   return v;
      59             : }
      60             : 
      61             : static inline void
      62    88443800 : _vec_update_len (void *v, uword n_elts, uword elt_sz, uword n_data_bytes,
      63             :                  uword unused_bytes)
      64             : {
      65    88443800 :   _vec_find (v)->len = n_elts;
      66    88443800 :   _vec_set_grow_elts (v, unused_bytes / elt_sz);
      67    88443400 :   clib_mem_unpoison (v, n_data_bytes);
      68    88443200 :   clib_mem_poison (v + n_data_bytes, unused_bytes);
      69    88443000 : }
      70             : 
      71             : __clib_export void *
      72    26712500 : _vec_realloc_internal (void *v, uword n_elts, const vec_attr_t *const attr)
      73             : {
      74             :   uword old_alloc_sz, new_alloc_sz, new_data_size, n_data_bytes, data_offset;
      75             :   uword elt_sz;
      76             : 
      77    26712500 :   if (PREDICT_FALSE (v == 0))
      78      985236 :     return _vec_alloc_internal (n_elts, attr);
      79             : 
      80    25727200 :   elt_sz = attr->elt_sz;
      81    25727200 :   n_data_bytes = n_elts * elt_sz;
      82    25727200 :   data_offset = vec_get_header_size (v);
      83    25727100 :   new_data_size = data_offset + n_data_bytes;
      84    25727100 :   new_alloc_sz = old_alloc_sz = clib_mem_size (vec_header (v));
      85             : 
      86             :   /* realloc if new size cannot fit into existing allocation */
      87    25726600 :   if (old_alloc_sz < new_data_size)
      88             :     {
      89    17754800 :       uword n_bytes, req_size = new_data_size;
      90    17754800 :       void *p = v - data_offset;
      91             : 
      92    17754800 :       req_size += CLIB_VECTOR_GROW_BY_ONE ? 0 : n_data_bytes / 2;
      93             : 
      94    17754800 :       p = clib_mem_heap_realloc_aligned (vec_get_heap (v), p, req_size,
      95             :                                          vec_get_align (v));
      96    17756200 :       new_alloc_sz = clib_mem_size (p);
      97    17756100 :       v = p + data_offset;
      98             : 
      99             :       /* zero out new allocation */
     100    17756100 :       n_bytes = new_alloc_sz - old_alloc_sz;
     101    17756100 :       clib_mem_unpoison (p + old_alloc_sz, n_bytes);
     102    17756000 :       clib_memset_u8 (p + old_alloc_sz, 0, n_bytes);
     103             :     }
     104             : 
     105    25727800 :   _vec_update_len (v, n_elts, elt_sz, n_data_bytes,
     106             :                    new_alloc_sz - new_data_size);
     107    25727300 :   return v;
     108             : }
     109             : 
     110             : __clib_export void *
     111    80322500 : _vec_resize_internal (void *v, uword n_elts, const vec_attr_t *const attr)
     112             : {
     113    80322500 :   uword elt_sz = attr->elt_sz;
     114    80322500 :   if (PREDICT_TRUE (v != 0))
     115             :     {
     116    80303300 :       uword hs = _vec_find (v)->hdr_size * VEC_MIN_ALIGN;
     117    80303300 :       uword alloc_sz = clib_mem_size (v - hs);
     118    80303200 :       uword n_data_bytes = elt_sz * n_elts;
     119    80303200 :       word unused_bytes = alloc_sz - (n_data_bytes + hs);
     120             : 
     121    80303200 :       if (PREDICT_TRUE (unused_bytes >= 0))
     122             :         {
     123    62715700 :           _vec_update_len (v, n_elts, elt_sz, n_data_bytes, unused_bytes);
     124    62715700 :           return v;
     125             :         }
     126             :     }
     127             : 
     128             :   /* this shouled emit tail jump and likely avoid stack usasge inside this
     129             :    * function */
     130    17606700 :   return _vec_realloc_internal (v, n_elts, attr);
     131             : }
     132             : 
     133             : __clib_export u32
     134           0 : vec_len_not_inline (void *v)
     135             : {
     136           0 :   return vec_len (v);
     137             : }
     138             : 
     139             : __clib_export void
     140           0 : vec_free_not_inline (void *v)
     141             : {
     142           0 :   vec_free (v);
     143           0 : }

Generated by: LCOV version 1.14