FD.io VPP  v19.04.2-12-g66b1689
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  data_bytes = clib_mem_size (new);
62  clib_memset (new, 0, data_bytes);
63  v = new + header_bytes;
64  _vec_len (v) = length_increment;
65  return v;
66  }
67 
68  vh->len += length_increment;
69  old = v - header_bytes;
70 
71  /* Vector header must start heap object. */
73 
74  old_alloc_bytes = clib_mem_size (old);
75 
76  /* Need to resize? */
77  if (data_bytes <= old_alloc_bytes)
78  return v;
79 
80  new_alloc_bytes = (old_alloc_bytes * 3) / 2;
81  if (new_alloc_bytes < data_bytes)
82  new_alloc_bytes = data_bytes;
83 
84  new =
85  clib_mem_alloc_aligned_at_offset (new_alloc_bytes, data_align,
86  header_bytes,
87  1 /* yes, call os_out_of_memory */ );
88 
89  /* FIXME fail gracefully. */
90  if (!new)
92  ("vec_resize fails, length increment %d, data bytes %d, alignment %d",
93  length_increment, data_bytes, data_align);
94 
95  clib_memcpy_fast (new, old, old_alloc_bytes);
96  clib_mem_free (old);
97 
98  /* Allocator may give a bit of extra room. */
99  new_alloc_bytes = clib_mem_size (new);
100  v = new;
101 
102  /* Zero new memory. */
103  memset (v + old_alloc_bytes, 0, new_alloc_bytes - old_alloc_bytes);
104 
105  return v + header_bytes;
106 }
107 
108 uword
109 clib_mem_is_vec_h (void *v, uword header_bytes)
110 {
111  return clib_mem_is_heap_object (vec_header (v, header_bytes));
112 }
113 
114 /** \cond */
115 
116 #ifdef TEST
117 
118 #include <stdio.h>
119 
120 void
121 main (int argc, char *argv[])
122 {
123  word n = atoi (argv[1]);
124  word i, *x = 0;
125 
126  typedef struct
127  {
128  word x, y, z;
129  } FOO;
130 
131  FOO *foos = vec_init (FOO, 10), *f;
132 
133  vec_validate (foos, 100);
134  foos[100].x = 99;
135 
136  _vec_len (foos) = 0;
137  for (i = 0; i < n; i++)
138  {
139  vec_add1 (x, i);
140  vec_add2 (foos, f, 1);
141  f->x = 2 * i;
142  f->y = 3 * i;
143  f->z = 4 * i;
144  }
145 
146  {
147  word n = 2;
148  word m = 42;
149  vec_delete (foos, n, m);
150  }
151 
152  {
153  word n = 2;
154  word m = 42;
155  vec_insert (foos, n, m);
156  }
157 
158  vec_free (x);
159  vec_free (foos);
160  exit (0);
161 }
162 #endif
163 /** \endcond */
164 
165 /*
166  * fd.io coding-style-patch-verification: ON
167  *
168  * Local Variables:
169  * eval: (c-set-style "gnu")
170  * End:
171  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
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:81
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:560
int i
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
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:109
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:685
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
static uword clib_mem_size(void *p)
Definition: mem.h:242
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:784
static void clib_mem_free(void *p)
Definition: mem.h:205
vector header structure
Definition: vec_bootstrap.h:55
static uword clib_mem_is_heap_object(void *p)
Definition: mem.h:182
int main(int argc, char **argv)
Definition: persist.c:215
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".