blob: 6961d100a753cccc979d22f7c787d572f2057e55 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
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
Damjan Marion5f21e1b2018-08-01 14:38:36 +020041#include <vppinfra/config.h>
42
Damjan Marion68e5fd52020-04-23 13:41:47 +020043#ifdef __x86_64__
44#include <x86intrin.h>
45#endif
46
Ed Warnickecb9cada2015-12-08 15:45:58 -070047/* Standalone means to not assume we are running on a Unix box. */
48#if ! defined (CLIB_STANDALONE) && ! defined (CLIB_LINUX_KERNEL)
49#define CLIB_UNIX
50#endif
51
52#include <vppinfra/types.h>
Sirshak Das2f6d7bb2018-10-03 22:53:51 +000053#include <vppinfra/atomics.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070054
55/* Global DEBUG flag. Setting this to 1 or 0 turns off
56 ASSERT (see vppinfra/error.h) & other debugging code. */
57#ifndef CLIB_DEBUG
58#define CLIB_DEBUG 0
59#endif
60
61#ifndef NULL
62#define NULL ((void *) 0)
63#endif
64
65#define BITS(x) (8*sizeof(x))
66#define ARRAY_LEN(x) (sizeof (x)/sizeof (x[0]))
67
68#define _STRUCT_FIELD(t,f) (((t *) 0)->f)
69#define STRUCT_OFFSET_OF(t,f) ((uword) & _STRUCT_FIELD (t, f))
70#define STRUCT_BIT_OFFSET_OF(t,f) (BITS(u8) * (uword) & _STRUCT_FIELD (t, f))
71#define STRUCT_SIZE_OF(t,f) (sizeof (_STRUCT_FIELD (t, f)))
72#define STRUCT_BITS_OF(t,f) (BITS (_STRUCT_FIELD (t, f)))
73#define STRUCT_ARRAY_LEN(t,f) ARRAY_LEN (_STRUCT_FIELD (t, f))
Dave Barachdbf19ca2016-03-15 10:21:54 +010074#define STRUCT_MARK(mark) u8 mark[0]
75#define STRUCT_MARK_PTR(v, f) &(v)->f
Ed Warnickecb9cada2015-12-08 15:45:58 -070076
77/* Stride in bytes between struct array elements. */
78#define STRUCT_STRIDE_OF(t,f) \
79 ( ((uword) & (((t *) 0)[1].f)) \
80 - ((uword) & (((t *) 0)[0].f)))
81
82#define STRUCT_OFFSET_OF_VAR(v,f) ((uword) (&(v)->f) - (uword) (v))
83
84/* Used to pack structure elements. */
85#define CLIB_PACKED(x) x __attribute__ ((packed))
Dave Barachc3799992016-08-15 11:12:27 -040086#define CLIB_UNUSED(x) x __attribute__ ((unused))
Ed Warnickecb9cada2015-12-08 15:45:58 -070087
David Johnsond9818dd2018-12-14 14:53:41 -050088/* similar to CLIB_CACHE_LINE_ALIGN_MARK() but with arbitrary alignment */
89#define CLIB_ALIGN_MARK(name, alignment) u8 name[0] __attribute__((aligned(alignment)))
90
Dave Barachcabbee72017-11-18 08:43:06 -050091/* Make a string from the macro's argument */
92#define CLIB_STRING_MACRO(x) #x
93
Damjan Marion04f3db32017-11-10 21:55:45 +010094#define __clib_unused __attribute__ ((unused))
95#define __clib_weak __attribute__ ((weak))
96#define __clib_packed __attribute__ ((packed))
97#define __clib_constructor __attribute__ ((constructor))
Damjan Mariona1e03d42020-05-06 23:38:58 +020098#define __clib_noinline __attribute__ ((noinline))
99#define __clib_aligned(x) __attribute__ ((aligned(x)))
100#define __clib_section(s) __attribute__ ((section(s)))
Damjan Mariona2185122020-04-08 00:52:53 +0200101#define __clib_warn_unused_result __attribute__ ((warn_unused_result))
Damjan Marion04f3db32017-11-10 21:55:45 +0100102
Ed Warnickecb9cada2015-12-08 15:45:58 -0700103#define never_inline __attribute__ ((__noinline__))
104
105#if CLIB_DEBUG > 0
106#define always_inline static inline
107#define static_always_inline static inline
108#else
109#define always_inline static inline __attribute__ ((__always_inline__))
110#define static_always_inline static inline __attribute__ ((__always_inline__))
111#endif
112
113
114/* Reserved (unused) structure element with address offset between
115 from and to. */
116#define CLIB_PAD_FROM_TO(from,to) u8 pad_##from[(to) - (from)]
117
118/* Hints to compiler about hot/cold code. */
119#define PREDICT_FALSE(x) __builtin_expect((x),0)
120#define PREDICT_TRUE(x) __builtin_expect((x),1)
121
BenoƮt Gannedc812d92019-12-16 10:42:25 +0100122/*
123 * Compiler barrier
124 * prevent compiler to reorder memory access accross this boundary
125 * prevent compiler to cache values in register (force reload)
126 * Not to be confused with CPU memory barrier below
127 */
128#define CLIB_COMPILER_BARRIER() asm volatile ("":::"memory")
129
Ed Warnickecb9cada2015-12-08 15:45:58 -0700130/* Full memory barrier (read and write). */
131#define CLIB_MEMORY_BARRIER() __sync_synchronize ()
132
Damjan Marioneaabe072017-03-22 10:18:13 +0100133#if __x86_64__
134#define CLIB_MEMORY_STORE_BARRIER() __builtin_ia32_sfence ()
135#else
136#define CLIB_MEMORY_STORE_BARRIER() __sync_synchronize ()
137#endif
138
Ed Warnickecb9cada2015-12-08 15:45:58 -0700139/* Arranges for function to be called before main. */
140#define INIT_FUNCTION(decl) \
141 decl __attribute ((constructor)); \
142 decl
143
144/* Arranges for function to be called before exit. */
145#define EXIT_FUNCTION(decl) \
146 decl __attribute ((destructor)); \
147 decl
148
149/* Use __builtin_clz if available. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700150#if uword_bits == 64
Damjan Marion11056002018-05-10 13:40:44 +0200151#define count_leading_zeros(x) __builtin_clzll (x)
152#define count_trailing_zeros(x) __builtin_ctzll (x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700153#else
Damjan Marion11056002018-05-10 13:40:44 +0200154#define count_leading_zeros(x) __builtin_clzl (x)
155#define count_trailing_zeros(x) __builtin_ctzl (x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700156#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700157
158#if defined (count_leading_zeros)
Dave Barachc3799992016-08-15 11:12:27 -0400159always_inline uword
160min_log2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700161{
162 uword n;
Damjan Marion11056002018-05-10 13:40:44 +0200163 n = count_leading_zeros (x);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700164 return BITS (uword) - n - 1;
165}
166#else
Dave Barachc3799992016-08-15 11:12:27 -0400167always_inline uword
168min_log2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700169{
Dave Barachc3799992016-08-15 11:12:27 -0400170 uword a = x, b = BITS (uword) / 2, c = 0, r = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700171
172 /* Reduce x to 4 bit result. */
173#define _ \
174{ \
175 c = a >> b; \
176 if (c) a = c; \
177 if (c) r += b; \
178 b /= 2; \
179}
180
Dave Barachc3799992016-08-15 11:12:27 -0400181 if (BITS (uword) > 32)
182 _;
183 _;
184 _;
185 _;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700186#undef _
187
188 /* Do table lookup on 4 bit partial. */
189 if (BITS (uword) > 32)
190 {
191 const u64 table = 0x3333333322221104LL;
Dave Barachc3799992016-08-15 11:12:27 -0400192 uword t = (table >> (4 * a)) & 0xf;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700193 r = t < 4 ? r + t : ~0;
194 }
195 else
196 {
197 const u32 table = 0x22221104;
Dave Barachc3799992016-08-15 11:12:27 -0400198 uword t = (a & 8) ? 3 : ((table >> (4 * a)) & 0xf);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700199 r = t < 4 ? r + t : ~0;
Dave Barachc3799992016-08-15 11:12:27 -0400200 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700201
202 return r;
203}
204#endif
205
Dave Barachc3799992016-08-15 11:12:27 -0400206always_inline uword
207max_log2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208{
209 uword l = min_log2 (x);
210 if (x > ((uword) 1 << l))
211 l++;
212 return l;
213}
214
Dave Barachc3799992016-08-15 11:12:27 -0400215always_inline u64
216min_log2_u64 (u64 x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700217{
218 if (BITS (uword) == 64)
219 return min_log2 (x);
220 else
221 {
222 uword l, y;
223 y = x;
224 l = 0;
Dave Barachc3799992016-08-15 11:12:27 -0400225 if (y == 0)
226 {
227 l += 32;
228 x >>= 32;
229 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700230 l += min_log2 (x);
231 return l;
232 }
233}
234
Dave Barachc3799992016-08-15 11:12:27 -0400235always_inline uword
236pow2_mask (uword x)
237{
238 return ((uword) 1 << x) - (uword) 1;
239}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240
Dave Barachc3799992016-08-15 11:12:27 -0400241always_inline uword
242max_pow2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700243{
244 word y = (word) 1 << min_log2 (x);
Dave Barachc3799992016-08-15 11:12:27 -0400245 if (x > y)
246 y *= 2;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700247 return y;
248}
249
Dave Barachc3799992016-08-15 11:12:27 -0400250always_inline uword
251is_pow2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700252{
Dave Barachc3799992016-08-15 11:12:27 -0400253 return 0 == (x & (x - 1));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700254}
255
Dave Barachc3799992016-08-15 11:12:27 -0400256always_inline uword
257round_pow2 (uword x, uword pow2)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258{
Dave Barachc3799992016-08-15 11:12:27 -0400259 return (x + pow2 - 1) & ~(pow2 - 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700260}
261
Dave Barachc3799992016-08-15 11:12:27 -0400262always_inline u64
263round_pow2_u64 (u64 x, u64 pow2)
264{
265 return (x + pow2 - 1) & ~(pow2 - 1);
266}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700267
Dave Barachc3799992016-08-15 11:12:27 -0400268always_inline uword
269first_set (uword x)
270{
271 return x & -x;
272}
273
274always_inline uword
275log2_first_set (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700276{
277 uword result;
278#ifdef count_trailing_zeros
Damjan Marion11056002018-05-10 13:40:44 +0200279 result = count_trailing_zeros (x);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700280#else
281 result = min_log2 (first_set (x));
282#endif
283 return result;
284}
285
Dave Barachc3799992016-08-15 11:12:27 -0400286always_inline f64
287flt_round_down (f64 x)
288{
289 return (int) x;
290}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700291
Dave Barachc3799992016-08-15 11:12:27 -0400292always_inline word
293flt_round_nearest (f64 x)
294{
295 return (word) (x + .5);
296}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700297
Dave Barachc3799992016-08-15 11:12:27 -0400298always_inline f64
299flt_round_to_multiple (f64 x, f64 f)
300{
301 return f * flt_round_nearest (x / f);
302}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700303
Damjan Marion68e5fd52020-04-23 13:41:47 +0200304always_inline uword
305extract_bits (uword x, int start, int count)
306{
307#ifdef __BMI__
308 return _bextr_u64 (x, start, count);
309#endif
310 return (x >> start) & pow2_mask (count);
311}
312
Ed Warnickecb9cada2015-12-08 15:45:58 -0700313#define clib_max(x,y) \
314({ \
315 __typeof__ (x) _x = (x); \
316 __typeof__ (y) _y = (y); \
317 _x > _y ? _x : _y; \
318})
319
320#define clib_min(x,y) \
321({ \
322 __typeof__ (x) _x = (x); \
323 __typeof__ (y) _y = (y); \
324 _x < _y ? _x : _y; \
325})
326
327#define clib_abs(x) \
328({ \
329 __typeof__ (x) _x = (x); \
330 _x < 0 ? -_x : _x; \
331})
332
333/* Standard standalone-only function declarations. */
334#ifndef CLIB_UNIX
Dave Barachc3799992016-08-15 11:12:27 -0400335void clib_standalone_init (void *memory, uword memory_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700336
Dave Barachc3799992016-08-15 11:12:27 -0400337void qsort (void *base, uword n, uword size,
338 int (*)(const void *, const void *));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700339#endif
340
341/* Stack backtrace. */
342uword
Dave Barachc3799992016-08-15 11:12:27 -0400343clib_backtrace (uword * callers, uword max_callers, uword n_frames_to_skip);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700344
345#endif /* included_clib_h */
Dave Barachc3799992016-08-15 11:12:27 -0400346
347/*
348 * fd.io coding-style-patch-verification: ON
349 *
350 * Local Variables:
351 * eval: (c-set-style "gnu")
352 * End:
353 */