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 10664 : vlib_clear_simple_counters (vlib_simple_counter_main_t * cm)
45 : {
46 : counter_t *my_counters;
47 : uword i, j;
48 :
49 21337 : for (i = 0; i < vec_len (cm->counters); i++)
50 : {
51 10673 : my_counters = cm->counters[i];
52 :
53 122764 : for (j = 0; j < vec_len (my_counters); j++)
54 : {
55 112091 : my_counters[j] = 0;
56 : }
57 : }
58 10664 : }
59 :
60 : void
61 3969 : vlib_clear_combined_counters (vlib_combined_counter_main_t * cm)
62 : {
63 : vlib_counter_t *my_counters;
64 : uword i, j;
65 :
66 7806 : for (i = 0; i < vec_len (cm->counters); i++)
67 : {
68 3837 : my_counters = cm->counters[i];
69 :
70 57296 : for (j = 0; j < vec_len (my_counters); j++)
71 : {
72 53459 : my_counters[j].packets = 0;
73 53459 : my_counters[j].bytes = 0;
74 : }
75 : }
76 3969 : }
77 :
78 : void
79 324881 : vlib_validate_simple_counter (vlib_simple_counter_main_t * cm, u32 index)
80 : {
81 324881 : vlib_thread_main_t *tm = vlib_get_thread_main ();
82 324881 : char *name = cm->stat_segment_name ? cm->stat_segment_name : cm->name;
83 :
84 324881 : if (name == 0)
85 : {
86 575 : if (cm->counters == 0)
87 575 : cm->stats_entry_index = ~0;
88 575 : vec_validate (cm->counters, tm->n_vlib_mains - 1);
89 1205 : for (int i = 0; i < tm->n_vlib_mains; i++)
90 630 : vec_validate_aligned (cm->counters[i], index, CLIB_CACHE_LINE_BYTES);
91 575 : return;
92 : }
93 :
94 324306 : if (cm->counters == 0)
95 53885 : cm->stats_entry_index = vlib_stats_add_counter_vector ("%s", name);
96 :
97 324306 : vlib_stats_validate (cm->stats_entry_index, tm->n_vlib_mains - 1, index);
98 324306 : 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 224840 : vlib_validate_combined_counter (vlib_combined_counter_main_t * cm, u32 index)
119 : {
120 224840 : vlib_thread_main_t *tm = vlib_get_thread_main ();
121 224840 : char *name = cm->stat_segment_name ? cm->stat_segment_name : cm->name;
122 :
123 224840 : 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 224675 : if (cm->counters == 0)
134 7953 : cm->stats_entry_index = vlib_stats_add_counter_pair_vector ("%s", name);
135 :
136 224675 : vlib_stats_validate (cm->stats_entry_index, tm->n_vlib_mains - 1, index);
137 224675 : cm->counters = vlib_stats_get_entry_data_pointer (cm->stats_entry_index);
138 : }
139 :
140 : int
141 100811 : vlib_validate_combined_counter_will_expand
142 : (vlib_combined_counter_main_t * cm, u32 index)
143 : {
144 100811 : vlib_thread_main_t *tm = vlib_get_thread_main ();
145 : int i;
146 100811 : void *oldheap = vlib_stats_set_heap ();
147 :
148 : /* Possibly once in recorded history */
149 100811 : if (PREDICT_FALSE (vec_len (cm->counters) == 0))
150 : {
151 0 : clib_mem_set_heap (oldheap);
152 0 : return 1;
153 : }
154 :
155 203375 : for (i = 0; i < tm->n_vlib_mains; i++)
156 : {
157 : /* Trivially OK, and proves that index >= vec_len(...) */
158 106989 : if (index < vec_len (cm->counters[i]))
159 50804 : continue;
160 56185 : if (vec_resize_will_expand (cm->counters[i],
161 : index - vec_len (cm->counters[i]) +
162 : 1 /* length_increment */))
163 : {
164 4425 : clib_mem_set_heap (oldheap);
165 4425 : return 1;
166 : }
167 : }
168 96386 : clib_mem_set_heap (oldheap);
169 96386 : 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 27 : vlib_combined_counter_n_counters (const vlib_combined_counter_main_t * cm)
190 : {
191 27 : ASSERT (cm->counters);
192 27 : return (vec_len (cm->counters[0]));
193 : }
194 :
195 : u32
196 819532 : vlib_simple_counter_n_counters (const vlib_simple_counter_main_t * cm)
197 : {
198 819532 : ASSERT (cm->counters);
199 819532 : 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 : */
|