Line data Source code
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/cache.h>
39 : #include <vppinfra/fifo.h>
40 : #include <vppinfra/error.h>
41 : #include <vppinfra/string.h>
42 :
43 : /*
44 : General first in/first out queues.
45 : FIFOs can have arbitrary size and type.
46 : Let T be any type (i.e. char, int, struct foo, etc.).
47 :
48 : A null fifo is initialized:
49 :
50 : T * f = 0;
51 :
52 : For example, typedef struct { int a, b; } T;
53 :
54 : Elements can be added in 3 ways.
55 :
56 : #1 1 element is added:
57 : T x;
58 : x.a = 10; x.b = 20;
59 : fifo_add1 (f, x);
60 :
61 : #2 n elements are added
62 : T buf[10];
63 : initialize buf[0] .. buf[9];
64 : fifo_add (f, buf, 10);
65 :
66 : #3 1 element is added, pointer is returned
67 : T * x;
68 : fifo_add2 (f, x);
69 : x->a = 10;
70 : x->b = 20;
71 :
72 : Elements are removed 1 at a time:
73 : T x;
74 : fifo_sub1 (f, x);
75 :
76 : fifo_free (f) frees fifo.
77 : */
78 :
79 : __clib_export void *
80 26439 : _clib_fifo_resize (void *v_old, uword n_new_elts, uword align, uword elt_bytes)
81 : {
82 : void *end, *head;
83 26439 : u8 *v_new = 0;
84 : uword n_old_elts;
85 : uword n_copy_bytes, n_zero_bytes;
86 : clib_fifo_header_t *f_new, *f_old;
87 26439 : vec_attr_t va = { .elt_sz = elt_bytes,
88 : .hdr_sz = sizeof (clib_fifo_header_t),
89 : .align = align };
90 :
91 26439 : n_old_elts = clib_fifo_elts (v_old);
92 26439 : n_new_elts += n_old_elts;
93 26439 : if (n_new_elts < 32)
94 15809 : n_new_elts = 32;
95 : else
96 10630 : n_new_elts = max_pow2 (n_new_elts);
97 :
98 26439 : v_new = _vec_alloc_internal (n_new_elts, &va);
99 26439 : f_new = clib_fifo_header (v_new);
100 26439 : f_new->head_index = 0;
101 26439 : f_new->tail_index = n_old_elts;
102 :
103 : /* Copy old -> new. */
104 26439 : n_copy_bytes = n_old_elts * elt_bytes;
105 26439 : if (n_copy_bytes > 0)
106 : {
107 10626 : f_old = clib_fifo_header (v_old);
108 10626 : end = v_old + _vec_len (v_old) * elt_bytes;
109 10626 : head = v_old + f_old->head_index * elt_bytes;
110 :
111 10626 : if (head + n_copy_bytes >= end)
112 : {
113 10626 : uword n = end - head;
114 10626 : clib_memcpy_fast (v_new, head, n);
115 10626 : clib_memcpy_fast (v_new + n, v_old, n_copy_bytes - n);
116 : }
117 : else
118 0 : clib_memcpy_fast (v_new, head, n_copy_bytes);
119 : }
120 :
121 : /* Zero empty space. */
122 26439 : n_zero_bytes = (n_new_elts - n_old_elts) * elt_bytes;
123 26439 : clib_memset (v_new + n_copy_bytes, 0, n_zero_bytes);
124 :
125 26439 : clib_fifo_free (v_old);
126 :
127 26439 : return v_new;
128 : }
129 :
130 : /*
131 : * fd.io coding-style-patch-verification: ON
132 : *
133 : * Local Variables:
134 : * eval: (c-set-style "gnu")
135 : * End:
136 : */
|