blob: a6f88245d7956c011832970adc111409b95bfc17 [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
Ed Warnickecb9cada2015-12-08 15:45:58 -070043/* Standalone means to not assume we are running on a Unix box. */
44#if ! defined (CLIB_STANDALONE) && ! defined (CLIB_LINUX_KERNEL)
45#define CLIB_UNIX
46#endif
47
48#include <vppinfra/types.h>
49
50/* Global DEBUG flag. Setting this to 1 or 0 turns off
51 ASSERT (see vppinfra/error.h) & other debugging code. */
52#ifndef CLIB_DEBUG
53#define CLIB_DEBUG 0
54#endif
55
56#ifndef NULL
57#define NULL ((void *) 0)
58#endif
59
60#define BITS(x) (8*sizeof(x))
61#define ARRAY_LEN(x) (sizeof (x)/sizeof (x[0]))
62
63#define _STRUCT_FIELD(t,f) (((t *) 0)->f)
64#define STRUCT_OFFSET_OF(t,f) ((uword) & _STRUCT_FIELD (t, f))
65#define STRUCT_BIT_OFFSET_OF(t,f) (BITS(u8) * (uword) & _STRUCT_FIELD (t, f))
66#define STRUCT_SIZE_OF(t,f) (sizeof (_STRUCT_FIELD (t, f)))
67#define STRUCT_BITS_OF(t,f) (BITS (_STRUCT_FIELD (t, f)))
68#define STRUCT_ARRAY_LEN(t,f) ARRAY_LEN (_STRUCT_FIELD (t, f))
Dave Barachdbf19ca2016-03-15 10:21:54 +010069#define STRUCT_MARK(mark) u8 mark[0]
70#define STRUCT_MARK_PTR(v, f) &(v)->f
Ed Warnickecb9cada2015-12-08 15:45:58 -070071
72/* Stride in bytes between struct array elements. */
73#define STRUCT_STRIDE_OF(t,f) \
74 ( ((uword) & (((t *) 0)[1].f)) \
75 - ((uword) & (((t *) 0)[0].f)))
76
77#define STRUCT_OFFSET_OF_VAR(v,f) ((uword) (&(v)->f) - (uword) (v))
78
79/* Used to pack structure elements. */
80#define CLIB_PACKED(x) x __attribute__ ((packed))
Dave Barachc3799992016-08-15 11:12:27 -040081#define CLIB_UNUSED(x) x __attribute__ ((unused))
Ed Warnickecb9cada2015-12-08 15:45:58 -070082
Dave Barachcabbee72017-11-18 08:43:06 -050083/* Make a string from the macro's argument */
84#define CLIB_STRING_MACRO(x) #x
85
Damjan Marion04f3db32017-11-10 21:55:45 +010086#define __clib_unused __attribute__ ((unused))
87#define __clib_weak __attribute__ ((weak))
88#define __clib_packed __attribute__ ((packed))
89#define __clib_constructor __attribute__ ((constructor))
90
Ed Warnickecb9cada2015-12-08 15:45:58 -070091#define never_inline __attribute__ ((__noinline__))
92
93#if CLIB_DEBUG > 0
94#define always_inline static inline
95#define static_always_inline static inline
96#else
97#define always_inline static inline __attribute__ ((__always_inline__))
98#define static_always_inline static inline __attribute__ ((__always_inline__))
99#endif
100
101
102/* Reserved (unused) structure element with address offset between
103 from and to. */
104#define CLIB_PAD_FROM_TO(from,to) u8 pad_##from[(to) - (from)]
105
106/* Hints to compiler about hot/cold code. */
107#define PREDICT_FALSE(x) __builtin_expect((x),0)
108#define PREDICT_TRUE(x) __builtin_expect((x),1)
109
110/* Full memory barrier (read and write). */
111#define CLIB_MEMORY_BARRIER() __sync_synchronize ()
112
Damjan Marioneaabe072017-03-22 10:18:13 +0100113#if __x86_64__
114#define CLIB_MEMORY_STORE_BARRIER() __builtin_ia32_sfence ()
115#else
116#define CLIB_MEMORY_STORE_BARRIER() __sync_synchronize ()
117#endif
118
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119/* Arranges for function to be called before main. */
120#define INIT_FUNCTION(decl) \
121 decl __attribute ((constructor)); \
122 decl
123
124/* Arranges for function to be called before exit. */
125#define EXIT_FUNCTION(decl) \
126 decl __attribute ((destructor)); \
127 decl
128
129/* Use __builtin_clz if available. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700130#if uword_bits == 64
Damjan Marion11056002018-05-10 13:40:44 +0200131#define count_leading_zeros(x) __builtin_clzll (x)
132#define count_trailing_zeros(x) __builtin_ctzll (x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700133#else
Damjan Marion11056002018-05-10 13:40:44 +0200134#define count_leading_zeros(x) __builtin_clzl (x)
135#define count_trailing_zeros(x) __builtin_ctzl (x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700136#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700137
138#if defined (count_leading_zeros)
Dave Barachc3799992016-08-15 11:12:27 -0400139always_inline uword
140min_log2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700141{
142 uword n;
Damjan Marion11056002018-05-10 13:40:44 +0200143 n = count_leading_zeros (x);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700144 return BITS (uword) - n - 1;
145}
146#else
Dave Barachc3799992016-08-15 11:12:27 -0400147always_inline uword
148min_log2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700149{
Dave Barachc3799992016-08-15 11:12:27 -0400150 uword a = x, b = BITS (uword) / 2, c = 0, r = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700151
152 /* Reduce x to 4 bit result. */
153#define _ \
154{ \
155 c = a >> b; \
156 if (c) a = c; \
157 if (c) r += b; \
158 b /= 2; \
159}
160
Dave Barachc3799992016-08-15 11:12:27 -0400161 if (BITS (uword) > 32)
162 _;
163 _;
164 _;
165 _;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700166#undef _
167
168 /* Do table lookup on 4 bit partial. */
169 if (BITS (uword) > 32)
170 {
171 const u64 table = 0x3333333322221104LL;
Dave Barachc3799992016-08-15 11:12:27 -0400172 uword t = (table >> (4 * a)) & 0xf;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700173 r = t < 4 ? r + t : ~0;
174 }
175 else
176 {
177 const u32 table = 0x22221104;
Dave Barachc3799992016-08-15 11:12:27 -0400178 uword t = (a & 8) ? 3 : ((table >> (4 * a)) & 0xf);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179 r = t < 4 ? r + t : ~0;
Dave Barachc3799992016-08-15 11:12:27 -0400180 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181
182 return r;
183}
184#endif
185
Dave Barachc3799992016-08-15 11:12:27 -0400186always_inline uword
187max_log2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700188{
189 uword l = min_log2 (x);
190 if (x > ((uword) 1 << l))
191 l++;
192 return l;
193}
194
Dave Barachc3799992016-08-15 11:12:27 -0400195always_inline u64
196min_log2_u64 (u64 x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700197{
198 if (BITS (uword) == 64)
199 return min_log2 (x);
200 else
201 {
202 uword l, y;
203 y = x;
204 l = 0;
Dave Barachc3799992016-08-15 11:12:27 -0400205 if (y == 0)
206 {
207 l += 32;
208 x >>= 32;
209 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210 l += min_log2 (x);
211 return l;
212 }
213}
214
Dave Barachc3799992016-08-15 11:12:27 -0400215always_inline uword
216pow2_mask (uword x)
217{
218 return ((uword) 1 << x) - (uword) 1;
219}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700220
Dave Barachc3799992016-08-15 11:12:27 -0400221always_inline uword
222max_pow2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700223{
224 word y = (word) 1 << min_log2 (x);
Dave Barachc3799992016-08-15 11:12:27 -0400225 if (x > y)
226 y *= 2;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700227 return y;
228}
229
Dave Barachc3799992016-08-15 11:12:27 -0400230always_inline uword
231is_pow2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700232{
Dave Barachc3799992016-08-15 11:12:27 -0400233 return 0 == (x & (x - 1));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700234}
235
Dave Barachc3799992016-08-15 11:12:27 -0400236always_inline uword
237round_pow2 (uword x, uword pow2)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700238{
Dave Barachc3799992016-08-15 11:12:27 -0400239 return (x + pow2 - 1) & ~(pow2 - 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240}
241
Dave Barachc3799992016-08-15 11:12:27 -0400242always_inline u64
243round_pow2_u64 (u64 x, u64 pow2)
244{
245 return (x + pow2 - 1) & ~(pow2 - 1);
246}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700247
Dave Barachc3799992016-08-15 11:12:27 -0400248always_inline uword
249first_set (uword x)
250{
251 return x & -x;
252}
253
254always_inline uword
255log2_first_set (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700256{
257 uword result;
258#ifdef count_trailing_zeros
Damjan Marion11056002018-05-10 13:40:44 +0200259 result = count_trailing_zeros (x);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700260#else
261 result = min_log2 (first_set (x));
262#endif
263 return result;
264}
265
Dave Barachc3799992016-08-15 11:12:27 -0400266always_inline f64
267flt_round_down (f64 x)
268{
269 return (int) x;
270}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700271
Dave Barachc3799992016-08-15 11:12:27 -0400272always_inline word
273flt_round_nearest (f64 x)
274{
275 return (word) (x + .5);
276}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700277
Dave Barachc3799992016-08-15 11:12:27 -0400278always_inline f64
279flt_round_to_multiple (f64 x, f64 f)
280{
281 return f * flt_round_nearest (x / f);
282}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700283
284#define clib_max(x,y) \
285({ \
286 __typeof__ (x) _x = (x); \
287 __typeof__ (y) _y = (y); \
288 _x > _y ? _x : _y; \
289})
290
291#define clib_min(x,y) \
292({ \
293 __typeof__ (x) _x = (x); \
294 __typeof__ (y) _y = (y); \
295 _x < _y ? _x : _y; \
296})
297
298#define clib_abs(x) \
299({ \
300 __typeof__ (x) _x = (x); \
301 _x < 0 ? -_x : _x; \
302})
303
304/* Standard standalone-only function declarations. */
305#ifndef CLIB_UNIX
Dave Barachc3799992016-08-15 11:12:27 -0400306void clib_standalone_init (void *memory, uword memory_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700307
Dave Barachc3799992016-08-15 11:12:27 -0400308void qsort (void *base, uword n, uword size,
309 int (*)(const void *, const void *));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700310#endif
311
312/* Stack backtrace. */
313uword
Dave Barachc3799992016-08-15 11:12:27 -0400314clib_backtrace (uword * callers, uword max_callers, uword n_frames_to_skip);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700315
316#endif /* included_clib_h */
Dave Barachc3799992016-08-15 11:12:27 -0400317
318/*
319 * fd.io coding-style-patch-verification: ON
320 *
321 * Local Variables:
322 * eval: (c-set-style "gnu")
323 * End:
324 */