FD.io VPP  v20.01-9-g24064d02a
Vector Packet Processing
vec.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
17 
18  Permission is hereby granted, free of charge, to any person obtaining
19  a copy of this software and associated documentation files (the
20  "Software"), to deal in the Software without restriction, including
21  without limitation the rights to use, copy, modify, merge, publish,
22  distribute, sublicense, and/or sell copies of the Software, and to
23  permit persons to whom the Software is furnished to do so, subject to
24  the following conditions:
25 
26  The above copyright notice and this permission notice shall be
27  included in all copies or substantial portions of the Software.
28 
29  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 */
37 
38 #include <vppinfra/vec.h>
39 #include <vppinfra/mem.h>
40 
41 /* Vector resize operator. Called as needed by various macros such as
42  vec_add1() when we need to allocate memory. */
43 void *
45  word length_increment,
46  uword data_bytes,
47  uword header_bytes, uword data_align)
48 {
49  vec_header_t *vh = _vec_find (v);
50  uword old_alloc_bytes, new_alloc_bytes;
51  void *old, *new;
52 
53  header_bytes = vec_header_bytes (header_bytes);
54 
55  data_bytes += header_bytes;
56 
57  if (!v)
58  {
59  new = clib_mem_alloc_aligned_at_offset (data_bytes, data_align, header_bytes, 1 /* yes, call os_out_of_memory */
60  );
61  new_alloc_bytes = clib_mem_size (new);
62  CLIB_MEM_UNPOISON (new + data_bytes, new_alloc_bytes - data_bytes);
63  clib_memset (new, 0, new_alloc_bytes);
64  CLIB_MEM_POISON (new + data_bytes, new_alloc_bytes - data_bytes);
65  v = new + header_bytes;
66  _vec_len (v) = length_increment;
67  return v;
68  }
69 
70  vh->len += length_increment;
71  old = v - header_bytes;
72 
73  /* Vector header must start heap object. */
75 
76  old_alloc_bytes = clib_mem_size (old);
77 
78  /* Need to resize? */
79  if (data_bytes <= old_alloc_bytes)
80  {
81  CLIB_MEM_UNPOISON (v, data_bytes);
82  return v;
83  }
84 
85  new_alloc_bytes = (old_alloc_bytes * 3) / 2;
86  if (new_alloc_bytes < data_bytes)
87  new_alloc_bytes = data_bytes;
88 
89  new =
90  clib_mem_alloc_aligned_at_offset (new_alloc_bytes, data_align,
91  header_bytes,
92  1 /* yes, call os_out_of_memory */ );
93 
94  /* FIXME fail gracefully. */
95  if (!new)
97  ("vec_resize fails, length increment %d, data bytes %d, alignment %d",
98  length_increment, data_bytes, data_align);
99 
100  CLIB_MEM_UNPOISON (old, old_alloc_bytes);
101  clib_memcpy_fast (new, old, old_alloc_bytes);
102  clib_mem_free (old);
103 
104  /* Allocator may give a bit of extra room. */
105  new_alloc_bytes = clib_mem_size (new);
106  v = new;
107 
108  /* Zero new memory. */
109  CLIB_MEM_UNPOISON (new + data_bytes, new_alloc_bytes - data_bytes);
110  memset (v + old_alloc_bytes, 0, new_alloc_bytes - old_alloc_bytes);
111  CLIB_MEM_POISON (new + data_bytes, new_alloc_bytes - data_bytes);
112 
113  return v + header_bytes;
114 }
115 
116 uword
117 clib_mem_is_vec_h (void *v, uword header_bytes)
118 {
119  return clib_mem_is_heap_object (vec_header (v, header_bytes));
120 }
121 
122 /** \cond */
123 
124 #ifdef TEST
125 
126 #include <stdio.h>
127 
128 void
129 main (int argc, char *argv[])
130 {
131  word n = atoi (argv[1]);
132  word i, *x = 0;
133 
134  typedef struct
135  {
136  word x, y, z;
137  } FOO;
138 
139  FOO *foos = vec_init (FOO, 10), *f;
140 
141  vec_validate (foos, 100);
142  foos[100].x = 99;
143 
144  _vec_len (foos) = 0;
145  for (i = 0; i < n; i++)
146  {
147  vec_add1 (x, i);
148  vec_add2 (foos, f, 1);
149  f->x = 2 * i;
150  f->y = 3 * i;
151  f->z = 4 * i;
152  }
153 
154  {
155  word n = 2;
156  word m = 42;
157  vec_delete (foos, n, m);
158  }
159 
160  {
161  word n = 2;
162  word m = 42;
163  vec_insert (foos, n, m);
164  }
165 
166  vec_free (x);
167  vec_free (foos);
168  exit (0);
169 }
170 #endif
171 /** \endcond */
172 
173 /*
174  * fd.io coding-style-patch-verification: ON
175  *
176  * Local Variables:
177  * eval: (c-set-style "gnu")
178  * End:
179  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:440
#define CLIB_MEM_UNPOISON(a, s)
Definition: sanitizer.h:47
void * vec_resize_allocate_memory(void *v, word length_increment, uword data_bytes, uword header_bytes, uword data_align)
Low-level resize allocation function, usually not called directly.
Definition: vec.c:44
static void * clib_mem_alloc_aligned_at_offset(uword size, uword align, uword align_offset, int os_out_of_memory_on_failure)
Definition: mem.h:113
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:561
int i
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)...
Definition: vec.c:117
i64 word
Definition: types.h:111
static uword vec_header_bytes(uword header_bytes)
Definition: vec_bootstrap.h:80
#define vec_insert(V, N, M)
Insert N vector elements starting at element M, initialize new elements to zero (no header...
Definition: vec.h:686
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
static uword clib_mem_size(void *p)
Definition: mem.h:261
u32 len
Number of elements in vector (NOT its allocated length).
Definition: vec_bootstrap.h:60
#define ASSERT(truth)
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:785
static void clib_mem_free(void *p)
Definition: mem.h:226
vector header structure
Definition: vec_bootstrap.h:55
static uword clib_mem_is_heap_object(void *p)
Definition: mem.h:203
int main(int argc, char **argv)
Definition: health_check.c:24
u64 uword
Definition: types.h:112
static void * vec_header(void *v, uword header_bytes)
Find a user vector header.
Definition: vec_bootstrap.h:93
#define clib_panic(format, args...)
Definition: error.h:72
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
#define CLIB_MEM_POISON(a, s)
Definition: sanitizer.h:46