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 : #ifndef included_clib_h
39 : #define included_clib_h
40 :
41 : #include <stddef.h>
42 :
43 : #if __has_include(<vppinfra/config.h>)
44 : #include <vppinfra/config.h>
45 : #endif
46 :
47 : #ifdef __x86_64__
48 : #include <x86intrin.h>
49 : #endif
50 :
51 : /* Standalone means to not assume we are running on a Unix box. */
52 : #if ! defined (CLIB_STANDALONE) && ! defined (CLIB_LINUX_KERNEL)
53 : #define CLIB_UNIX
54 : #endif
55 :
56 : #ifdef __linux__
57 : #define CLIB_LINUX 1
58 : #else
59 : #define CLIB_LINUX 0
60 : #endif
61 :
62 : #include <vppinfra/types.h>
63 : #include <vppinfra/atomics.h>
64 :
65 : /* Global DEBUG flag. Setting this to 1 or 0 turns off
66 : ASSERT (see vppinfra/error.h) & other debugging code. */
67 : #ifndef CLIB_DEBUG
68 : #define CLIB_DEBUG 0
69 : #endif
70 :
71 : #ifndef NULL
72 : #define NULL ((void *) 0)
73 : #endif
74 :
75 : #define BITS(x) (8*sizeof(x))
76 : #define ARRAY_LEN(x) (sizeof (x)/sizeof (x[0]))
77 : #define FOREACH_ARRAY_ELT(a, b) \
78 : for (typeof ((b)[0]) *(a) = (b); (a) - (b) < ARRAY_LEN (b); (a)++)
79 :
80 : #define _STRUCT_FIELD(t,f) (((t *) 0)->f)
81 : #define STRUCT_OFFSET_OF(t,f) offsetof(t, f)
82 : #define STRUCT_BIT_OFFSET_OF(t,f) (BITS(u8) * STRUCT_OFFSET_OF (t, f))
83 : #define STRUCT_SIZE_OF(t,f) (sizeof (_STRUCT_FIELD (t, f)))
84 : #define STRUCT_BITS_OF(t,f) (BITS (_STRUCT_FIELD (t, f)))
85 : #define STRUCT_ARRAY_LEN(t,f) ARRAY_LEN (_STRUCT_FIELD (t, f))
86 : #define STRUCT_MARK(mark) u8 mark[0]
87 : #define STRUCT_MARK_PTR(v, f) &(v)->f
88 :
89 : /* Stride in bytes between struct array elements. */
90 : #define STRUCT_STRIDE_OF(t,f) \
91 : ( ((uword) & (((t *) 0)[1].f)) \
92 : - ((uword) & (((t *) 0)[0].f)))
93 :
94 : #define STRUCT_OFFSET_OF_VAR(v,f) ((uword) (&(v)->f) - (uword) (v))
95 :
96 : /* Used to pack structure elements. */
97 : #define CLIB_PACKED(x) x __attribute__ ((packed))
98 : #define CLIB_UNUSED(x) x __attribute__ ((unused))
99 :
100 : /* similar to CLIB_CACHE_LINE_ALIGN_MARK() but with arbitrary alignment */
101 : #define CLIB_ALIGN_MARK(name, alignment) u8 name[0] __attribute__((aligned(alignment)))
102 :
103 : /* Make a string from the macro's argument */
104 : #define CLIB_STRING_MACRO(x) #x
105 :
106 : #define CLIB_STRING_ARRAY(...) \
107 : (char *[]) { __VA_ARGS__, 0 }
108 :
109 : /* sanitizers */
110 : #ifdef __has_feature
111 : #if __has_feature(address_sanitizer)
112 : #define CLIB_SANITIZE_ADDR 1
113 : #endif
114 : #elif defined(__SANITIZE_ADDRESS__)
115 : #define CLIB_SANITIZE_ADDR 1
116 : #endif
117 :
118 : #define __clib_unused __attribute__ ((unused))
119 : #define __clib_weak __attribute__ ((weak))
120 : #define __clib_packed __attribute__ ((packed))
121 : #define __clib_flatten __attribute__ ((flatten))
122 : #define __clib_constructor __attribute__ ((constructor))
123 : #define __clib_noinline __attribute__ ((noinline))
124 : #ifdef __clang__
125 : #define __clib_noclone
126 : #else
127 : #define __clib_noclone __attribute__ ((noclone))
128 : #endif
129 : #define __clib_aligned(x) __attribute__ ((aligned(x)))
130 : #define __clib_section(s) __attribute__ ((section(s)))
131 : #define __clib_warn_unused_result __attribute__ ((warn_unused_result))
132 : #define __clib_export __attribute__ ((visibility("default")))
133 : #ifdef __clang__
134 : #define __clib_no_tail_calls __attribute__ ((disable_tail_calls))
135 : #else
136 : #define __clib_no_tail_calls \
137 : __attribute__ ((optimize ("no-optimize-sibling-calls")))
138 : #endif
139 :
140 : #ifdef CLIB_SANITIZE_ADDR
141 : #define __clib_nosanitize_addr __attribute__ ((no_sanitize_address))
142 : #else
143 : #define __clib_nosanitize_addr
144 : #endif
145 :
146 : #define never_inline __attribute__ ((__noinline__))
147 :
148 : #if CLIB_DEBUG > 0
149 : #define always_inline static inline
150 : #define static_always_inline static inline
151 : #else
152 : #define always_inline static inline __attribute__ ((__always_inline__))
153 : #define static_always_inline static inline __attribute__ ((__always_inline__))
154 : #endif
155 :
156 :
157 : /* Reserved (unused) structure element with address offset between
158 : from and to. */
159 : #define CLIB_PAD_FROM_TO(from,to) u8 pad_##from[(to) - (from)]
160 :
161 : /* Hints to compiler about hot/cold code. */
162 : #define PREDICT_FALSE(x) __builtin_expect((x),0)
163 : #define PREDICT_TRUE(x) __builtin_expect((x),1)
164 : #define COMPILE_TIME_CONST(x) __builtin_constant_p (x)
165 : #define CLIB_ASSUME(x) \
166 : do \
167 : { \
168 : if (!(x)) \
169 : __builtin_unreachable (); \
170 : } \
171 : while (0)
172 :
173 : /*
174 : * Compiler barrier
175 : * prevent compiler to reorder memory access across this boundary
176 : * prevent compiler to cache values in register (force reload)
177 : * Not to be confused with CPU memory barrier below
178 : */
179 : #define CLIB_COMPILER_BARRIER() asm volatile ("":::"memory")
180 :
181 : /* Full memory barrier (read and write). */
182 : #define CLIB_MEMORY_BARRIER() __sync_synchronize ()
183 :
184 : #if __SSE__
185 : #define CLIB_MEMORY_STORE_BARRIER() __builtin_ia32_sfence ()
186 : #else
187 : #define CLIB_MEMORY_STORE_BARRIER() __sync_synchronize ()
188 : #endif
189 :
190 : /* Arranges for function to be called before main. */
191 : #define INIT_FUNCTION(decl) \
192 : decl __attribute ((constructor)); \
193 : decl
194 :
195 : /* Arranges for function to be called before exit. */
196 : #define EXIT_FUNCTION(decl) \
197 : decl __attribute ((destructor)); \
198 : decl
199 :
200 : always_inline uword
201 1853182804 : pow2_mask (uword x)
202 : {
203 : #ifdef __BMI2__
204 293914027 : return _bzhi_u64 (-1ULL, x);
205 : #endif
206 1559268777 : return ((uword) 1 << x) - (uword) 1;
207 : }
208 :
209 : #include <vppinfra/bitops.h>
210 :
211 : always_inline uword
212 54319166 : min_log2 (uword x)
213 : {
214 : uword n;
215 54319166 : n = count_leading_zeros (x);
216 54319166 : return BITS (uword) - n - 1;
217 : }
218 :
219 : always_inline uword
220 3093555 : max_log2 (uword x)
221 : {
222 3093555 : uword l = min_log2 (x);
223 3093556 : if (x > ((uword) 1 << l))
224 388217 : l++;
225 3093556 : return l;
226 : }
227 :
228 : always_inline u64
229 1889 : min_log2_u64 (u64 x)
230 : {
231 : if (BITS (uword) == 64)
232 1889 : return min_log2 (x);
233 : else
234 : {
235 : uword l, y;
236 : y = x;
237 : l = 0;
238 : if (y == 0)
239 : {
240 : l += 32;
241 : x >>= 32;
242 : }
243 : l += min_log2 (x);
244 : return l;
245 : }
246 : }
247 :
248 : always_inline uword
249 12037 : max_pow2 (uword x)
250 : {
251 12037 : word y = (word) 1 << min_log2 (x);
252 12037 : if (x > y)
253 11411 : y *= 2;
254 12037 : return y;
255 : }
256 :
257 : always_inline uword
258 822996045 : is_pow2 (uword x)
259 : {
260 822996045 : return 0 == (x & (x - 1));
261 : }
262 :
263 : always_inline uword
264 116667 : round_down_pow2 (uword x, uword pow2)
265 : {
266 116667 : return (x) & ~(pow2 - 1);
267 : }
268 :
269 : always_inline uword
270 296295386 : round_pow2 (uword x, uword pow2)
271 : {
272 296295386 : return (x + pow2 - 1) & ~(pow2 - 1);
273 : }
274 :
275 : always_inline u64
276 3480 : round_pow2_u64 (u64 x, u64 pow2)
277 : {
278 3480 : return (x + pow2 - 1) & ~(pow2 - 1);
279 : }
280 :
281 : always_inline uword
282 0 : first_set (uword x)
283 : {
284 0 : return x & -x;
285 : }
286 :
287 : always_inline f64
288 : flt_round_down (f64 x)
289 : {
290 : return (int) x;
291 : }
292 :
293 : always_inline word
294 290959 : flt_round_nearest (f64 x)
295 : {
296 290959 : return (word) (x + .5);
297 : }
298 :
299 : always_inline f64
300 : flt_round_to_multiple (f64 x, f64 f)
301 : {
302 : return f * flt_round_nearest (x / f);
303 : }
304 :
305 : always_inline uword
306 1154 : extract_bits (uword x, int start, int count)
307 : {
308 : #ifdef __BMI__
309 0 : return _bextr_u64 (x, start, count);
310 : #endif
311 1154 : return (x >> start) & pow2_mask (count);
312 : }
313 :
314 : #define clib_max(x,y) \
315 : ({ \
316 : __typeof__ (x) _x = (x); \
317 : __typeof__ (y) _y = (y); \
318 : _x > _y ? _x : _y; \
319 : })
320 :
321 : #define clib_min(x,y) \
322 : ({ \
323 : __typeof__ (x) _x = (x); \
324 : __typeof__ (y) _y = (y); \
325 : _x < _y ? _x : _y; \
326 : })
327 :
328 : #define clib_clamp(x,lo,hi) \
329 : ({ \
330 : __typeof__ (x) _x = (x); \
331 : __typeof__ (lo) _lo = (lo); \
332 : __typeof__ (hi) _hi = (hi); \
333 : _x < _lo ? _lo : (_x > _hi ? _hi : _x); \
334 : })
335 :
336 : #define clib_abs(x) \
337 : ({ \
338 : __typeof__ (x) _x = (x); \
339 : _x < 0 ? -_x : _x; \
340 : })
341 :
342 : static_always_inline u64
343 : u64_add_with_carry (u64 *carry, u64 a, u64 b)
344 : {
345 : #if defined(__x86_64__)
346 : unsigned long long v;
347 : *carry = _addcarry_u64 (*carry, a, b, &v);
348 : return (u64) v;
349 : #elif defined(__clang__)
350 : unsigned long long c;
351 : u64 rv = __builtin_addcll (a, b, *carry, &c);
352 : *carry = c;
353 : return rv;
354 : #else
355 : u64 rv = a + b + *carry;
356 : *carry = rv < a;
357 : return rv;
358 : #endif
359 : }
360 :
361 : static_always_inline u64
362 : u64_sub_with_borrow (u64 *borrow, u64 x, u64 y)
363 : {
364 : #if defined(__x86_64__)
365 : unsigned long long v;
366 : *borrow = _subborrow_u64 (*borrow, x, y, &v);
367 : return (u64) v;
368 : #elif defined(__clang__)
369 : unsigned long long b;
370 : u64 rv = __builtin_subcll (x, y, *borrow, &b);
371 : *borrow = b;
372 : return rv;
373 : #else
374 : unsigned long long rv = x - (y + *borrow);
375 : *borrow = rv >= x;
376 : return rv;
377 : #endif
378 : }
379 :
380 : /* Standard standalone-only function declarations. */
381 : #ifndef CLIB_UNIX
382 : void clib_standalone_init (void *memory, uword memory_bytes);
383 :
384 : void qsort (void *base, uword n, uword size,
385 : int (*)(const void *, const void *));
386 : #endif
387 :
388 : /* Stack backtrace. */
389 : uword
390 : clib_backtrace (uword * callers, uword max_callers, uword n_frames_to_skip);
391 :
392 : #include <vppinfra/byte_order.h>
393 : #endif /* included_clib_h */
394 :
395 : /*
396 : * fd.io coding-style-patch-verification: ON
397 : *
398 : * Local Variables:
399 : * eval: (c-set-style "gnu")
400 : * End:
401 : */
|