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 : * counter.c: simple and packet/byte counters
17 : *
18 : * Copyright (c) 2008 Eliot Dresselhaus
19 : *
20 : * Permission is hereby granted, free of charge, to any person obtaining
21 : * a copy of this software and associated documentation files (the
22 : * "Software"), to deal in the Software without restriction, including
23 : * without limitation the rights to use, copy, modify, merge, publish,
24 : * distribute, sublicense, and/or sell copies of the Software, and to
25 : * permit persons to whom the Software is furnished to do so, subject to
26 : * the following conditions:
27 : *
28 : * The above copyright notice and this permission notice shall be
29 : * included in all copies or substantial portions of the Software.
30 : *
31 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 : * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 : * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 : * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 : * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 : */
39 :
40 : #include <vlib/vlib.h>
41 : #include <vlib/stats/stats.h>
42 :
43 : void
44 9695 : vlib_clear_simple_counters (vlib_simple_counter_main_t * cm)
45 : {
46 : counter_t *my_counters;
47 : uword i, j;
48 :
49 19390 : for (i = 0; i < vec_len (cm->counters); i++)
50 : {
51 9695 : my_counters = cm->counters[i];
52 :
53 114052 : for (j = 0; j < vec_len (my_counters); j++)
54 : {
55 104357 : my_counters[j] = 0;
56 : }
57 : }
58 9695 : }
59 :
60 : void
61 3839 : vlib_clear_combined_counters (vlib_combined_counter_main_t * cm)
62 : {
63 : vlib_counter_t *my_counters;
64 : uword i, j;
65 :
66 7540 : for (i = 0; i < vec_len (cm->counters); i++)
67 : {
68 3701 : my_counters = cm->counters[i];
69 :
70 55432 : for (j = 0; j < vec_len (my_counters); j++)
71 : {
72 51731 : my_counters[j].packets = 0;
73 51731 : my_counters[j].bytes = 0;
74 : }
75 : }
76 3839 : }
77 :
78 : void
79 314148 : vlib_validate_simple_counter (vlib_simple_counter_main_t * cm, u32 index)
80 : {
81 314148 : vlib_thread_main_t *tm = vlib_get_thread_main ();
82 314148 : char *name = cm->stat_segment_name ? cm->stat_segment_name : cm->name;
83 :
84 314148 : if (name == 0)
85 : {
86 559 : if (cm->counters == 0)
87 559 : cm->stats_entry_index = ~0;
88 559 : vec_validate (cm->counters, tm->n_vlib_mains - 1);
89 1172 : for (int i = 0; i < tm->n_vlib_mains; i++)
90 613 : vec_validate_aligned (cm->counters[i], index, CLIB_CACHE_LINE_BYTES);
91 559 : return;
92 : }
93 :
94 313589 : if (cm->counters == 0)
95 52285 : cm->stats_entry_index = vlib_stats_add_counter_vector ("%s", name);
96 :
97 313589 : vlib_stats_validate (cm->stats_entry_index, tm->n_vlib_mains - 1, index);
98 313589 : cm->counters = vlib_stats_get_entry_data_pointer (cm->stats_entry_index);
99 : }
100 :
101 : void
102 1 : vlib_free_simple_counter (vlib_simple_counter_main_t * cm)
103 : {
104 1 : if (cm->stats_entry_index == ~0)
105 : {
106 0 : for (int i = 0; i < vec_len (cm->counters); i++)
107 0 : vec_free (cm->counters[i]);
108 0 : vec_free (cm->counters);
109 : }
110 : else
111 : {
112 1 : vlib_stats_remove_entry (cm->stats_entry_index);
113 1 : cm->counters = NULL;
114 : }
115 1 : }
116 :
117 : void
118 221630 : vlib_validate_combined_counter (vlib_combined_counter_main_t * cm, u32 index)
119 : {
120 221630 : vlib_thread_main_t *tm = vlib_get_thread_main ();
121 221630 : char *name = cm->stat_segment_name ? cm->stat_segment_name : cm->name;
122 :
123 221630 : if (name == 0)
124 : {
125 165 : if (cm->counters == 0)
126 34 : cm->stats_entry_index = ~0;
127 165 : vec_validate (cm->counters, tm->n_vlib_mains - 1);
128 330 : for (int i = 0; i < tm->n_vlib_mains; i++)
129 165 : vec_validate_aligned (cm->counters[i], index, CLIB_CACHE_LINE_BYTES);
130 165 : return;
131 : }
132 :
133 221465 : if (cm->counters == 0)
134 7721 : cm->stats_entry_index = vlib_stats_add_counter_pair_vector ("%s", name);
135 :
136 221465 : vlib_stats_validate (cm->stats_entry_index, tm->n_vlib_mains - 1, index);
137 221465 : cm->counters = vlib_stats_get_entry_data_pointer (cm->stats_entry_index);
138 : }
139 :
140 : int
141 100488 : vlib_validate_combined_counter_will_expand
142 : (vlib_combined_counter_main_t * cm, u32 index)
143 : {
144 100488 : vlib_thread_main_t *tm = vlib_get_thread_main ();
145 : int i;
146 100488 : void *oldheap = vlib_stats_set_heap ();
147 :
148 : /* Possibly once in recorded history */
149 100488 : if (PREDICT_FALSE (vec_len (cm->counters) == 0))
150 : {
151 0 : clib_mem_set_heap (oldheap);
152 0 : return 1;
153 : }
154 :
155 201211 : for (i = 0; i < tm->n_vlib_mains; i++)
156 : {
157 : /* Trivially OK, and proves that index >= vec_len(...) */
158 106944 : if (index < vec_len (cm->counters[i]))
159 50481 : continue;
160 56463 : if (vec_resize_will_expand (cm->counters[i],
161 : index - vec_len (cm->counters[i]) +
162 : 1 /* length_increment */))
163 : {
164 6221 : clib_mem_set_heap (oldheap);
165 6221 : return 1;
166 : }
167 : }
168 94267 : clib_mem_set_heap (oldheap);
169 94267 : return 0;
170 : }
171 :
172 : void
173 1 : vlib_free_combined_counter (vlib_combined_counter_main_t * cm)
174 : {
175 1 : if (cm->stats_entry_index == ~0)
176 : {
177 0 : for (int i = 0; i < vec_len (cm->counters); i++)
178 0 : vec_free (cm->counters[i]);
179 0 : vec_free (cm->counters);
180 : }
181 : else
182 : {
183 1 : vlib_stats_remove_entry (cm->stats_entry_index);
184 1 : cm->counters = NULL;
185 : }
186 1 : }
187 :
188 : u32
189 26 : vlib_combined_counter_n_counters (const vlib_combined_counter_main_t * cm)
190 : {
191 26 : ASSERT (cm->counters);
192 26 : return (vec_len (cm->counters[0]));
193 : }
194 :
195 : u32
196 772835 : vlib_simple_counter_n_counters (const vlib_simple_counter_main_t * cm)
197 : {
198 772835 : ASSERT (cm->counters);
199 772835 : return (vec_len (cm->counters[0]));
200 : }
201 :
202 : /*
203 : * fd.io coding-style-patch-verification: ON
204 : *
205 : * Local Variables:
206 : * eval: (c-set-style "gnu")
207 : * End:
208 : */
|