CNDP  22.08.0
cne_vec.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2016-2022 Intel Corporation
3  */
4 
5 #ifndef __CNE_VEC_H
6 #define __CNE_VEC_H
7 
8 #include <stdint.h> // for uint16_t, uint32_t, uint64_t
9 #include <stdio.h> // for NULL, FILE
10 #include <stdlib.h> // for free
11 
12 #include <cne_common.h> // for __cne_always_inline, CNDP_API
13 #include <cne_prefetch.h>
14 #include <cne_stdio.h>
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 #define VEC_REALLOC_SIZE 8
22 typedef struct vec_hdr {
23  uint32_t len;
24  uint32_t alen;
25  uint16_t esize;
26  uint16_t rsvd[3];
27  uint8_t data[0];
28 } vec_hdr_t;
29 
33 #define _V(_x) _v_##_x
34 
43 static inline vec_hdr_t *
44 vec_header(void *vec)
45 {
46  return (vec_hdr_t *)((vec) ? CNE_PTR_SUB(vec, sizeof(vec_hdr_t)) : NULL);
47 }
48 
57 #define vec_end(vec) &(vec)[vec_header(vec)->len]
58 
71 #define vec_init(hv, al, es) \
72  ({ \
73  vec_hdr_t *_V(hx); \
74  _V(hx) = (vec_hdr_t *)(hv); \
75  _V(hx)->len = 0; \
76  _V(hx)->alen = al; \
77  _V(hx)->esize = es; \
78  _V(hx)->rsvd[0] = 0; \
79  _V(hx)->rsvd[1] = 0; \
80  _V(hx)->rsvd[2] = 0; \
81  (void *)_V(hx)->data; \
82  })
83 
94 static __cne_always_inline void *
95 _vec_realloc_data(void *vec, uint32_t nelem, uint32_t esize)
96 {
97  vec_hdr_t *h;
98  uint32_t sz = (nelem * esize) + sizeof(vec_hdr_t);
99 
100  h = (vec) ? vec_header(vec) : NULL;
101  h = realloc(h, sz);
102  if (!h)
103  return NULL;
104  if (!vec)
105  memset(h, 0, sz);
106  h->alen = nelem;
107  h->esize = esize;
108  return (void *)h->data;
109 }
110 
123 #define _vec_realloc(vec, nelem, esize) _vec_realloc_data((vec), nelem, esize)
124 
131 #define vec_free(v) \
132  ({ \
133  if (v) \
134  free(vec_header(v)); \
135  NULL; \
136  })
137 
148 #define vec_alloc(vec, nelem) \
149  ({ \
150  if ((vec)) \
151  CNE_ERR("Vector all ready allocated\n"); \
152  else \
153  (vec) = _vec_realloc((vec), nelem, sizeof((vec)[0])); \
154  (vec); \
155  })
156 
165 #define vec_foreach(var, vec) for ((var) = (vec); (vec) && (var < vec_end(vec)); var++)
166 
167 #define vec_foreach_ptr(var, vec) \
168  for (uint32_t _V(_i) = 0; (vec) && (var = (vec)[_V(_i)], _V(_i) < vec_len(vec)); _V(_i)++)
169 
180 #define vec_calc_size(n, _t) \
181  CNE_ALIGN_CEIL((n * sizeof(_t)) + sizeof(vec_hdr_t), CNE_CACHE_LINE_SIZE)
182 
191 #define vec_len(v) ((v) ? vec_header(v)->len : 0)
192 
201 static inline void
202 vec_set_len(void *v, int len)
203 {
204  vec_hdr_t *hdr = (vec_hdr_t *)vec_header(v);
205 
206  if (hdr)
207  hdr->len = len;
208 }
209 
218 #define vec_max_len(v) ((v) ? vec_header(v)->alen : 0)
219 
226 #define vec_dec_len(v) ((v) ? vec_header(v)->len-- : 0)
227 
238 #define vec_at_index(vec, n) (vec)[(n)]
239 
250 #define vec_addr_at_index(vec, n) &(vec)[(n)]
251 
262 #define vec_pop(vec) ((vec) ? (vec)[--vec_header(vec)->len] : 0)
263 
270 #define vec_inc_len(v) ((v) ? vec_header(v)->len++ : 0)
271 
272 static inline int
273 _vec_find_index(void **vec, void *v)
274 {
275  for (uint32_t i = 0; i < vec_len(vec); i++) {
276  if (v == vec_at_index(vec, i))
277  return i;
278  }
279  return -1;
280 }
281 
282 #define vec_find_index(vec, v) _vec_find_index((void **)vec, (void *)v)
283 
294 #define vec_add(vec, v) \
295  ({ \
296  if ((vec) == NULL) { \
297  (vec) = _vec_realloc(NULL, VEC_REALLOC_SIZE, sizeof((vec)[0])); \
298  (vec) = vec_init(vec_header((vec)), VEC_REALLOC_SIZE, sizeof((vec)[0])); \
299  } \
300  vec_hdr_t *_V(h) = vec_header((vec)); \
301  int _V(l) = _V(h)->len; \
302  if (_V(h)->len >= _V(h)->alen) { \
303  _V(h)->alen += VEC_REALLOC_SIZE; \
304  (vec) = _vec_realloc((vec), _V(h)->alen, _V(h)->esize); \
305  _V(h) = vec_header((vec)); \
306  } \
307  (vec)[_V(h)->len++] = (v); \
308  _V(l); \
309  })
310 
311 #define vec_full(vec) \
312  ({ \
313  vec_hdr_t *_V(h) = vec_header(vec); \
314  (_V(h)->len >= _V(h)->alen) ? true : false; \
315  })
316 
329 #define vec_move_at_index(t, f, n) \
330  do { \
331  vec_add(t, vec_at_index(f, n)); \
332  vec_at_index(f, n) = 0; \
333  } while (0)
334 
345 #define vec_copy_at_index(to, from, idx) \
346  do { \
347  typeof(from) v = vec_at_index(from, idx); \
348  vec_add(to, v); \
349  } while (0)
350 
359 static inline void
360 vec_remove(void *v, uint32_t nb)
361 {
362  vec_hdr_t *h = vec_header(v);
363 
364  if (h && h->len && nb <= h->len) {
365  int n = h->len - nb;
366 
367  if (n > 0)
368  memmove(v, CNE_PTR_ADD(v, (nb * h->esize)), n * h->esize);
369  h->len = n;
370  }
371 }
372 
381 static inline void
382 vec_dump(const char *msg, void *vec)
383 {
384  vec_hdr_t *h;
385 
386  cne_printf(" [orange]%-8s[] ", msg ? msg : "");
387  if (!vec) {
388  cne_printf(" *** Vector is NULL ***\n");
389  return;
390  }
391 
392  h = vec_header(vec);
393 
394  cne_printf(" @ %p, ", vec);
395  cne_printf("len %5d, ", h->len);
396  cne_printf("alen %5d, ", h->alen);
397  cne_printf("esize %5d\n", h->esize);
398 }
399 
400 #ifdef __cplusplus
401 }
402 #endif
403 
404 #endif /* __CNE_VEC_H */
#define CNE_PTR_ADD(ptr, x)
Definition: cne_common.h:235
#define CNE_PTR_SUB(ptr, x)
Definition: cne_common.h:240
#define __cne_always_inline
Definition: cne_common.h:218
CNDP_API int cne_printf(const char *fmt,...)