rdma: introduce direct verb for Cx4/5 tx
[vpp.git] / src / vppinfra / clib.h
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 <vppinfra/config.h>
42
43 /* 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 #include <vppinfra/atomics.h>
50
51 /* Global DEBUG flag.  Setting this to 1 or 0 turns off
52    ASSERT (see vppinfra/error.h) & other debugging code. */
53 #ifndef CLIB_DEBUG
54 #define CLIB_DEBUG 0
55 #endif
56
57 #ifndef NULL
58 #define NULL ((void *) 0)
59 #endif
60
61 #define BITS(x)         (8*sizeof(x))
62 #define ARRAY_LEN(x)    (sizeof (x)/sizeof (x[0]))
63
64 #define _STRUCT_FIELD(t,f) (((t *) 0)->f)
65 #define STRUCT_OFFSET_OF(t,f) ((uword) & _STRUCT_FIELD (t, f))
66 #define STRUCT_BIT_OFFSET_OF(t,f) (BITS(u8) * (uword) & _STRUCT_FIELD (t, f))
67 #define STRUCT_SIZE_OF(t,f)   (sizeof (_STRUCT_FIELD (t, f)))
68 #define STRUCT_BITS_OF(t,f)   (BITS (_STRUCT_FIELD (t, f)))
69 #define STRUCT_ARRAY_LEN(t,f) ARRAY_LEN (_STRUCT_FIELD (t, f))
70 #define STRUCT_MARK(mark)     u8 mark[0]
71 #define STRUCT_MARK_PTR(v, f) &(v)->f
72
73 /* Stride in bytes between struct array elements. */
74 #define STRUCT_STRIDE_OF(t,f)                   \
75   (  ((uword) & (((t *) 0)[1].f))               \
76    - ((uword) & (((t *) 0)[0].f)))
77
78 #define STRUCT_OFFSET_OF_VAR(v,f) ((uword) (&(v)->f) - (uword) (v))
79
80 /* Used to pack structure elements. */
81 #define CLIB_PACKED(x)  x __attribute__ ((packed))
82 #define CLIB_UNUSED(x)  x __attribute__ ((unused))
83
84 /* similar to CLIB_CACHE_LINE_ALIGN_MARK() but with arbitrary alignment */
85 #define CLIB_ALIGN_MARK(name, alignment) u8 name[0] __attribute__((aligned(alignment)))
86
87 /* Make a string from the macro's argument */
88 #define CLIB_STRING_MACRO(x) #x
89
90 #define __clib_unused __attribute__ ((unused))
91 #define __clib_weak __attribute__ ((weak))
92 #define __clib_packed __attribute__ ((packed))
93 #define __clib_constructor __attribute__ ((constructor))
94
95 #define never_inline __attribute__ ((__noinline__))
96
97 #if CLIB_DEBUG > 0
98 #define always_inline static inline
99 #define static_always_inline static inline
100 #else
101 #define always_inline static inline __attribute__ ((__always_inline__))
102 #define static_always_inline static inline __attribute__ ((__always_inline__))
103 #endif
104
105
106 /* Reserved (unused) structure element with address offset between
107    from and to. */
108 #define CLIB_PAD_FROM_TO(from,to) u8 pad_##from[(to) - (from)]
109
110 /* Hints to compiler about hot/cold code. */
111 #define PREDICT_FALSE(x) __builtin_expect((x),0)
112 #define PREDICT_TRUE(x) __builtin_expect((x),1)
113
114 /*
115  * Compiler barrier
116  *   prevent compiler to reorder memory access accross this boundary
117  *   prevent compiler to cache values in register (force reload)
118  * Not to be confused with CPU memory barrier below
119  */
120 #define CLIB_COMPILER_BARRIER() asm volatile ("":::"memory")
121
122 /* Full memory barrier (read and write). */
123 #define CLIB_MEMORY_BARRIER() __sync_synchronize ()
124
125 #if __x86_64__
126 #define CLIB_MEMORY_STORE_BARRIER() __builtin_ia32_sfence ()
127 #else
128 #define CLIB_MEMORY_STORE_BARRIER() __sync_synchronize ()
129 #endif
130
131 /* Arranges for function to be called before main. */
132 #define INIT_FUNCTION(decl)                     \
133   decl __attribute ((constructor));             \
134   decl
135
136 /* Arranges for function to be called before exit. */
137 #define EXIT_FUNCTION(decl)                     \
138   decl __attribute ((destructor));              \
139   decl
140
141 /* Use __builtin_clz if available. */
142 #if uword_bits == 64
143 #define count_leading_zeros(x) __builtin_clzll (x)
144 #define count_trailing_zeros(x) __builtin_ctzll (x)
145 #else
146 #define count_leading_zeros(x) __builtin_clzl (x)
147 #define count_trailing_zeros(x) __builtin_ctzl (x)
148 #endif
149
150 #if defined (count_leading_zeros)
151 always_inline uword
152 min_log2 (uword x)
153 {
154   uword n;
155   n = count_leading_zeros (x);
156   return BITS (uword) - n - 1;
157 }
158 #else
159 always_inline uword
160 min_log2 (uword x)
161 {
162   uword a = x, b = BITS (uword) / 2, c = 0, r = 0;
163
164   /* Reduce x to 4 bit result. */
165 #define _                                       \
166 {                                               \
167   c = a >> b;                                   \
168   if (c) a = c;                                 \
169   if (c) r += b;                                \
170   b /= 2;                                       \
171 }
172
173   if (BITS (uword) > 32)
174     _;
175   _;
176   _;
177   _;
178 #undef _
179
180   /* Do table lookup on 4 bit partial. */
181   if (BITS (uword) > 32)
182     {
183       const u64 table = 0x3333333322221104LL;
184       uword t = (table >> (4 * a)) & 0xf;
185       r = t < 4 ? r + t : ~0;
186     }
187   else
188     {
189       const u32 table = 0x22221104;
190       uword t = (a & 8) ? 3 : ((table >> (4 * a)) & 0xf);
191       r = t < 4 ? r + t : ~0;
192     }
193
194   return r;
195 }
196 #endif
197
198 always_inline uword
199 max_log2 (uword x)
200 {
201   uword l = min_log2 (x);
202   if (x > ((uword) 1 << l))
203     l++;
204   return l;
205 }
206
207 always_inline u64
208 min_log2_u64 (u64 x)
209 {
210   if (BITS (uword) == 64)
211     return min_log2 (x);
212   else
213     {
214       uword l, y;
215       y = x;
216       l = 0;
217       if (y == 0)
218         {
219           l += 32;
220           x >>= 32;
221         }
222       l += min_log2 (x);
223       return l;
224     }
225 }
226
227 always_inline uword
228 pow2_mask (uword x)
229 {
230   return ((uword) 1 << x) - (uword) 1;
231 }
232
233 always_inline uword
234 max_pow2 (uword x)
235 {
236   word y = (word) 1 << min_log2 (x);
237   if (x > y)
238     y *= 2;
239   return y;
240 }
241
242 always_inline uword
243 is_pow2 (uword x)
244 {
245   return 0 == (x & (x - 1));
246 }
247
248 always_inline uword
249 round_pow2 (uword x, uword pow2)
250 {
251   return (x + pow2 - 1) & ~(pow2 - 1);
252 }
253
254 always_inline u64
255 round_pow2_u64 (u64 x, u64 pow2)
256 {
257   return (x + pow2 - 1) & ~(pow2 - 1);
258 }
259
260 always_inline uword
261 first_set (uword x)
262 {
263   return x & -x;
264 }
265
266 always_inline uword
267 log2_first_set (uword x)
268 {
269   uword result;
270 #ifdef count_trailing_zeros
271   result = count_trailing_zeros (x);
272 #else
273   result = min_log2 (first_set (x));
274 #endif
275   return result;
276 }
277
278 always_inline f64
279 flt_round_down (f64 x)
280 {
281   return (int) x;
282 }
283
284 always_inline word
285 flt_round_nearest (f64 x)
286 {
287   return (word) (x + .5);
288 }
289
290 always_inline f64
291 flt_round_to_multiple (f64 x, f64 f)
292 {
293   return f * flt_round_nearest (x / f);
294 }
295
296 #define clib_max(x,y)                           \
297 ({                                              \
298   __typeof__ (x) _x = (x);                      \
299   __typeof__ (y) _y = (y);                      \
300   _x > _y ? _x : _y;                            \
301 })
302
303 #define clib_min(x,y)                           \
304 ({                                              \
305   __typeof__ (x) _x = (x);                      \
306   __typeof__ (y) _y = (y);                      \
307   _x < _y ? _x : _y;                            \
308 })
309
310 #define clib_abs(x)                             \
311 ({                                              \
312   __typeof__ (x) _x = (x);                      \
313   _x < 0 ? -_x : _x;                            \
314 })
315
316 /* Standard standalone-only function declarations. */
317 #ifndef CLIB_UNIX
318 void clib_standalone_init (void *memory, uword memory_bytes);
319
320 void qsort (void *base, uword n, uword size,
321             int (*)(const void *, const void *));
322 #endif
323
324 /* Stack backtrace. */
325 uword
326 clib_backtrace (uword * callers, uword max_callers, uword n_frames_to_skip);
327
328 #endif /* included_clib_h */
329
330 /*
331  * fd.io coding-style-patch-verification: ON
332  *
333  * Local Variables:
334  * eval: (c-set-style "gnu")
335  * End:
336  */