DPDK 26.11.0-rc1
rte_common.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2019 Intel Corporation
3 */
4
5#ifndef _RTE_COMMON_H_
6#define _RTE_COMMON_H_
7
15#include <assert.h>
16#include <limits.h>
17#include <stdbool.h>
18#include <stdint.h>
19#include <stdalign.h>
20
21#include <rte_compat.h>
22#include <rte_config.h>
23
24/* OS specific include */
25#include <rte_os.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#ifndef RTE_TOOLCHAIN_MSVC
32#ifndef typeof
33#define typeof __typeof__
34#endif
35#endif
36
37#ifndef __cplusplus
38#ifndef asm
39#define asm __asm__
40#endif
41#endif
42
43#ifdef RTE_TOOLCHAIN_MSVC
44#ifdef __cplusplus
45#define __extension__
46#endif
47#endif
48
49/*
50 * Macro __rte_constant checks if an expression's value can be determined at
51 * compile time. It takes a single argument, the expression to test, and
52 * returns 1 if the expression is a compile-time constant, and 0 otherwise.
53 * For most compilers it uses built-in function __builtin_constant_p, but for
54 * MSVC it uses a different method because MSVC does not have an equivalent
55 * to __builtin_constant_p.
56 *
57 * The trick used with MSVC relies on the way null pointer constants interact
58 * with the type of a ?: expression:
59 * An integer constant expression with the value 0, or such an expression cast
60 * to type void *, is called a null pointer constant.
61 * If both the second and third operands (of the ?: expression) are pointers or
62 * one is a null pointer constant and the other is a pointer, the result type
63 * is a pointer to a type qualified with all the type qualifiers of the types
64 * referenced by both operands. Furthermore, if both operands are pointers to
65 * compatible types or to differently qualified versions of compatible types,
66 * the result type is a pointer to an appropriately qualified version of the
67 * composite type; if one operand is a null pointer constant, the result has
68 * the type of the other operand; otherwise, one operand is a pointer to void
69 * or a qualified version of void, in which case the result type is a pointer
70 * to an appropriately qualified version of void.
71 *
72 * The _Generic keyword then checks the type of the expression
73 * (void *) ((e) * 0ll). It matches this type against the types listed in the
74 * _Generic construct:
75 * - If the type is int *, the result is 1.
76 * - If the type is void *, the result is 0.
77 *
78 * This explanation with some more details can be found at:
79 * https://stackoverflow.com/questions/49480442/detecting-integer-constant-expressions-in-macros
80 */
81#ifdef RTE_TOOLCHAIN_MSVC
82#define __rte_constant(e) _Generic((1 ? (void *) ((e) * 0ll) : (int *) 0), int * : 1, void * : 0)
83#else
84#define __rte_constant(e) __extension__(__builtin_constant_p(e))
85#endif
86
87/*
88 * RTE_TOOLCHAIN_GCC is defined if the target is built with GCC,
89 * while a host application (like pmdinfogen) may have another compiler.
90 * RTE_CC_IS_GNU is true if the file is compiled with GCC,
91 * no matter it is a target or host application.
92 */
93#define RTE_CC_IS_GNU 0
94#if defined __clang__
95#define RTE_CC_CLANG
96#elif defined __GNUC__
97#define RTE_CC_GCC
98#undef RTE_CC_IS_GNU
99#define RTE_CC_IS_GNU 1
100#endif
101#if RTE_CC_IS_GNU
102#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + \
103 __GNUC_PATCHLEVEL__)
104#endif
105
106/*
107 * Type inference for use in macros.
108 */
109#if (defined(__cplusplus) && __cplusplus >= 201103L) || \
110 (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
111#define __rte_auto_type auto
112#elif defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
113#define __rte_auto_type __auto_type
114#endif
115
116/*
117 * Helper macro for array decay in pointer arithmetic macros.
118 * Example: char arr[10]; RTE_PTR_ADD(arr, 5) needs arr to decay to char*.
119 *
120 * GCC/Clang in C mode need "+ 0" to force arrays to decay to pointers.
121 * Not needed for C++ (automatic decay) or MSVC (ternary checks both branches).
122 *
123 * Note: This must be an object-like macro (not function-like) because it gets
124 * used with nested macro expansion (e.g., RTE_PTR_ALIGN_FLOOR(RTE_PTR_ADD(...))).
125 * A function-like macro would wrap the argument in parentheses, causing _Pragma
126 * directives from nested statement expressions to appear in invalid contexts.
127 */
128#if !defined(RTE_TOOLCHAIN_MSVC) && !defined(__cplusplus)
129#define __rte_ptr_arith_add_zero + 0
130#else
131#define __rte_ptr_arith_add_zero
132#endif
133
146#ifdef RTE_TOOLCHAIN_MSVC
147#define __rte_aligned(a) __declspec(align(a))
148#else
149#define __rte_aligned(a) __attribute__((__aligned__(a)))
150#endif
151
155#ifdef RTE_TOOLCHAIN_MSVC
156typedef __unaligned uint64_t unaligned_uint64_t;
157typedef __unaligned uint32_t unaligned_uint32_t;
158typedef __unaligned uint16_t unaligned_uint16_t;
159#else
160typedef uint64_t unaligned_uint64_t __rte_aligned(1);
161typedef uint32_t unaligned_uint32_t __rte_aligned(1);
162typedef uint16_t unaligned_uint16_t __rte_aligned(1);
163#endif
164
172#ifdef RTE_TOOLCHAIN_MSVC
173#define __rte_packed_begin __pragma(pack(push, 1))
174#define __rte_packed_end __pragma(pack(pop))
175#else
176#define __rte_packed_begin
177#define __rte_packed_end __attribute__((__packed__))
178#endif
179
183#ifdef RTE_TOOLCHAIN_MSVC
184#define __rte_may_alias
185#else
186#define __rte_may_alias __attribute__((__may_alias__))
187#endif
188
189/******* Macro to mark functions and fields scheduled for removal *****/
190#ifdef RTE_TOOLCHAIN_MSVC
191#define __rte_deprecated
192#define __rte_deprecated_msg(msg)
193#else
194#define __rte_deprecated __attribute__((__deprecated__))
195#define __rte_deprecated_msg(msg) __attribute__((__deprecated__(msg)))
196#endif
197
201#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
202#define RTE_PRAGMA(x) _Pragma(#x)
203#define RTE_PRAGMA_WARNING(w) RTE_PRAGMA(GCC warning #w)
204#define RTE_DEPRECATED(x) RTE_PRAGMA_WARNING(#x is deprecated)
205#else
206#define RTE_DEPRECATED(x)
207#endif
208
213#if !defined(RTE_TOOLCHAIN_MSVC)
214#define __rte_diagnostic_push _Pragma("GCC diagnostic push")
215#define __rte_diagnostic_pop _Pragma("GCC diagnostic pop")
216#else
217#define __rte_diagnostic_push
218#define __rte_diagnostic_pop
219#endif
220
225#if !defined(RTE_TOOLCHAIN_MSVC)
226#define __rte_diagnostic_ignored_wcast_qual _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
227#else
228#define __rte_diagnostic_ignored_wcast_qual
229#endif
230
234#if !defined(RTE_TOOLCHAIN_MSVC)
235#define __rte_diagnostic_ignored_array_bounds \
236 _Pragma("GCC diagnostic ignored \"-Warray-bounds\"")
237#else
238#define __rte_diagnostic_ignored_array_bounds
239#endif
240
244#ifdef RTE_TOOLCHAIN_MSVC
245#define __rte_weak RTE_DEPRECATED(__rte_weak)
246#else
247#define __rte_weak RTE_DEPRECATED(__rte_weak) __attribute__((__weak__))
248#endif
249
253#ifdef RTE_TOOLCHAIN_MSVC
254#define __rte_pure
255#else
256#define __rte_pure __attribute__((pure))
257#endif
258
262#ifdef RTE_TOOLCHAIN_MSVC
263#define __rte_used
264#else
265#define __rte_used __attribute__((used))
266#endif
267
268/*********** Macros to eliminate unused variable warnings ********/
269
273#ifdef RTE_TOOLCHAIN_MSVC
274#define __rte_unused
275#else
276#define __rte_unused __attribute__((__unused__))
277#endif
278
282#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
283#define __rte_restrict __restrict
284#else
285#define __rte_restrict restrict
286#endif
287
292#define RTE_SET_USED(x) (void)(x)
293
301#ifdef RTE_TOOLCHAIN_MSVC
302#define __rte_format_printf(format_index, first_arg)
303#else
304#if RTE_CC_IS_GNU
305#define __rte_format_printf(format_index, first_arg) \
306 __attribute__((format(gnu_printf, format_index, first_arg)))
307#else
308#define __rte_format_printf(format_index, first_arg) \
309 __attribute__((format(printf, format_index, first_arg)))
310#endif
311#endif
312
316#ifdef RTE_TOOLCHAIN_MSVC
317#define __rte_section(name) \
318 __pragma(data_seg(name)) __declspec(allocate(name))
319#else
320#define __rte_section(name) \
321 __attribute__((section(name)))
322#endif
323
329#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
330#define __rte_alloc_size(...) \
331 __attribute__((alloc_size(__VA_ARGS__)))
332#else
333#define __rte_alloc_size(...)
334#endif
335
342#if defined(RTE_CC_GCC)
343#define __rte_alloc_align(argno) \
344 __attribute__((alloc_align(argno)))
345#else
346#define __rte_alloc_align(argno)
347#endif
348
353#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
354#define __rte_malloc __attribute__((__malloc__))
355#else
356#define __rte_malloc
357#endif
358
363#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 110000)
364#define __rte_dealloc(dealloc, argno) \
365 __attribute__((malloc(dealloc, argno)))
366#else
367#define __rte_dealloc(dealloc, argno)
368#endif
369
370#define RTE_PRIORITY_LOG 101
371#define RTE_PRIORITY_BUS 110
372#define RTE_PRIORITY_CLASS 120
373#define RTE_PRIORITY_LAST 65535
374
375#define RTE_PRIO(prio) \
376 RTE_PRIORITY_ ## prio
377
387#ifndef RTE_INIT_PRIO /* Allow overriding from EAL */
388#ifndef RTE_TOOLCHAIN_MSVC
389#define RTE_INIT_PRIO(func, prio) \
390static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void)
391#else
392/* definition from the Microsoft CRT */
393typedef int(__cdecl *_PIFV)(void);
394
395#define CTOR_SECTION_LOG ".CRT$XIB"
396#define CTOR_SECTION_BUS ".CRT$XIC"
397#define CTOR_SECTION_CLASS ".CRT$XID"
398#define CTOR_SECTION_LAST ".CRT$XIY"
399
400#define CTOR_PRIORITY_TO_SECTION(priority) CTOR_SECTION_ ## priority
401
402#define RTE_INIT_PRIO(name, priority) \
403 static void name(void); \
404 static int __cdecl name ## _thunk(void) { name(); return 0; } \
405 __pragma(const_seg(CTOR_PRIORITY_TO_SECTION(priority))) \
406 __declspec(allocate(CTOR_PRIORITY_TO_SECTION(priority))) \
407 _PIFV name ## _pointer = &name ## _thunk; \
408 __pragma(const_seg()) \
409 static void name(void)
410#endif
411#endif
412
421#define RTE_INIT(func) \
422 RTE_INIT_PRIO(func, LAST)
423
433#ifndef RTE_FINI_PRIO /* Allow overriding from EAL */
434#ifndef RTE_TOOLCHAIN_MSVC
435#define RTE_FINI_PRIO(func, prio) \
436static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
437#else
438#define DTOR_SECTION_LOG "mydtor$B"
439#define DTOR_SECTION_BUS "mydtor$C"
440#define DTOR_SECTION_CLASS "mydtor$D"
441#define DTOR_SECTION_LAST "mydtor$Y"
442
443#define DTOR_PRIORITY_TO_SECTION(priority) DTOR_SECTION_ ## priority
444
445#define RTE_FINI_PRIO(name, priority) \
446 static void name(void); \
447 __pragma(const_seg(DTOR_PRIORITY_TO_SECTION(priority))) \
448 __declspec(allocate(DTOR_PRIORITY_TO_SECTION(priority))) void *name ## _pointer = &name; \
449 __pragma(const_seg()) \
450 static void name(void)
451#endif
452#endif
453
462#define RTE_FINI(func) \
463 RTE_FINI_PRIO(func, LAST)
464
468#ifdef RTE_TOOLCHAIN_MSVC
469#define __rte_noreturn
470#else
471#define __rte_noreturn __attribute__((noreturn))
472#endif
473
477#if defined(RTE_TOOLCHAIN_GCC) || defined(RTE_TOOLCHAIN_CLANG)
478#define __rte_unreachable() __extension__(__builtin_unreachable())
479#else
480#define __rte_unreachable() __assume(0)
481#endif
482
506#ifdef RTE_TOOLCHAIN_MSVC
507#define __rte_warn_unused_result
508#else
509#define __rte_warn_unused_result __attribute__((warn_unused_result))
510#endif
511
531#ifdef RTE_TOOLCHAIN_MSVC
532#define __rte_always_inline __forceinline
533#else
534#define __rte_always_inline inline __attribute__((always_inline))
535#endif
536
544#ifdef RTE_TOOLCHAIN_MSVC
545#define __rte_noinline __declspec(noinline)
546#else
547#define __rte_noinline __attribute__((noinline))
548#endif
549
559#ifdef RTE_TOOLCHAIN_MSVC
560#define __rte_hot
561#else
562#define __rte_hot __attribute__((hot))
563#endif
564
576#ifdef RTE_TOOLCHAIN_MSVC
577#define __rte_cold
578#else
579#define __rte_cold __attribute__((cold))
580#endif
581
588#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 130000)
589#define __rte_assume(condition) __attribute__((assume(condition)))
590#elif defined(RTE_TOOLCHAIN_GCC)
591#define __rte_assume(condition) do { if (!(condition)) __rte_unreachable(); } while (0)
592#elif defined(RTE_TOOLCHAIN_CLANG)
593#define __rte_assume(condition) __extension__(__builtin_assume(condition))
594#else
595#define __rte_assume(condition) __assume(condition)
596#endif
597
601#ifdef RTE_MALLOC_ASAN
602#ifdef RTE_CC_CLANG
603#define __rte_no_asan __attribute__((no_sanitize("address", "hwaddress")))
604#else
605#define __rte_no_asan __attribute__((no_sanitize_address))
606#endif
607#else /* ! RTE_MALLOC_ASAN */
608#define __rte_no_asan
609#endif
610
611/*********** Macros for pointer arithmetic ********/
612
627#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
628#define RTE_PTR_ADD(ptr, x) \
629(__extension__ ({ \
630 /* (1) Force array decay and ensure single evaluation */ \
631 __rte_auto_type __rte_ptr_add = (ptr) __rte_ptr_arith_add_zero; \
632 __rte_diagnostic_push \
633 __rte_diagnostic_ignored_wcast_qual \
634 /* (2) Calculate result, preserving const/volatile via ternary */ \
635 __rte_auto_type __rte_ptr_add_res = \
636 (1 ? (void *)((char *)__rte_ptr_add + (x)) : __rte_ptr_add); \
637 __rte_diagnostic_pop \
638 /* (3) Return the result */ \
639 __rte_ptr_add_res; \
640}))
641#else
642/* MSVC fallback (ternary preserves const, no statement exprs) */
643#define RTE_PTR_ADD(ptr, x) \
644 (1 ? (void *)((char *)((ptr) __rte_ptr_arith_add_zero) + (x)) : \
645 ((ptr) __rte_ptr_arith_add_zero))
646#endif
647
662#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
663#define RTE_PTR_SUB(ptr, x) \
664(__extension__ ({ \
665 /* (1) Force array decay and ensure single evaluation */ \
666 __rte_auto_type __rte_ptr_sub = (ptr) __rte_ptr_arith_add_zero; \
667 __rte_diagnostic_push \
668 __rte_diagnostic_ignored_wcast_qual \
669 /* (2) Calculate result, preserving const/volatile via ternary */ \
670 __rte_auto_type __rte_ptr_sub_res = \
671 (1 ? (void *)((char *)__rte_ptr_sub - (x)) : __rte_ptr_sub); \
672 __rte_diagnostic_pop \
673 /* (3) Return the result */ \
674 __rte_ptr_sub_res; \
675}))
676#else
677/* MSVC fallback (ternary preserves const, no statement exprs) */
678#define RTE_PTR_SUB(ptr, x) \
679 (1 ? (void *)((char *)((ptr) __rte_ptr_arith_add_zero) - (x)) : \
680 ((ptr) __rte_ptr_arith_add_zero))
681#endif
682
688#define RTE_PTR_DIFF(ptr1, ptr2) ((uintptr_t)(ptr1) - (uintptr_t)(ptr2))
689
690/*********** Macros for casting pointers ********/
691
696#define RTE_PTR_UNQUAL(X) ((void *)(uintptr_t)(X))
697
715#define RTE_CAST_PTR(type, ptr) ((type)(uintptr_t)(ptr))
716
720#define RTE_CAST_FIELD(var, field, type) \
721 (*(type *)((uintptr_t)(var) + offsetof(typeof(*(var)), field)))
722
723/*********** Macros/static functions for doing alignment ********/
724
725
742#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
743#define RTE_PTR_ALIGN_FLOOR(ptr, align) \
744(__extension__ ({ \
745 /* (1) Force array decay and ensure single evaluation */ \
746 __rte_auto_type __rte_ptr_floor = (ptr) __rte_ptr_arith_add_zero; \
747 /* (2) Compute misalignment as integer, but adjust pointer using pointer arithmetic */ \
748 size_t __rte_ptr_floor_misalign = (uintptr_t)__rte_ptr_floor & ((align) - 1); \
749 __rte_diagnostic_push \
750 __rte_diagnostic_ignored_wcast_qual \
751 /* (3) Return the aligned result, cast to preserve input type. We avoid RTE_PTR_SUB */ \
752 /* to skip the void* cast which may defeat compiler alignment optimizations. */ \
753 __rte_auto_type __rte_ptr_floor_res = \
754 (typeof(__rte_ptr_floor))((char *)__rte_ptr_floor - __rte_ptr_floor_misalign); \
755 __rte_diagnostic_pop \
756 __rte_ptr_floor_res; \
757}))
758#else
759#define RTE_PTR_ALIGN_FLOOR(ptr, align) \
760 ((typeof(ptr))RTE_ALIGN_FLOOR((uintptr_t) ((ptr) __rte_ptr_arith_add_zero), align))
761#endif
762
769#define RTE_ALIGN_FLOOR(val, align) \
770 (typeof(val))((val) & (~((typeof(val))((align) - 1))))
771
788#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
789#define RTE_PTR_ALIGN_CEIL(ptr, align) \
790(__extension__ ({ \
791 /* (1) Force array decay and ensure single evaluation */ \
792 __rte_auto_type __rte_ptr_ceil = (ptr) __rte_ptr_arith_add_zero; \
793 /* (2) Compute alignment as integer, but adjust pointer using pointer arithmetic */ \
794 size_t __rte_ptr_ceil_align_m1 = (align) - 1; \
795 uintptr_t __rte_ptr_ceil_aligned = ((uintptr_t)__rte_ptr_ceil + __rte_ptr_ceil_align_m1) \
796 & ~__rte_ptr_ceil_align_m1; \
797 size_t __rte_ptr_ceil_offset = __rte_ptr_ceil_aligned - (uintptr_t)__rte_ptr_ceil; \
798 __rte_diagnostic_push \
799 __rte_diagnostic_ignored_wcast_qual \
800 /* (3) Return the aligned result, cast to preserve input type. We avoid RTE_PTR_SUB */ \
801 /* to skip the void* cast which may defeat compiler alignment optimizations. */ \
802 __rte_auto_type __rte_ptr_ceil_res = \
803 (typeof(__rte_ptr_ceil))((char *)__rte_ptr_ceil + __rte_ptr_ceil_offset); \
804 __rte_diagnostic_pop \
805 __rte_ptr_ceil_res; \
806}))
807#else
808#define RTE_PTR_ALIGN_CEIL(ptr, align) \
809 RTE_PTR_ALIGN_FLOOR((typeof(ptr))RTE_PTR_ADD(ptr, (align) - 1), align)
810#endif
811
818#define RTE_ALIGN_CEIL(val, align) \
819 RTE_ALIGN_FLOOR(((val) + ((typeof(val)) (align) - 1)), align)
820
828#define RTE_PTR_ALIGN(ptr, align) RTE_PTR_ALIGN_CEIL(ptr, align)
829
837#define RTE_ALIGN(val, align) RTE_ALIGN_CEIL(val, align)
838
844#define RTE_ALIGN_MUL_CEIL(v, mul) \
845 ((((v) + (typeof(v))(mul) - 1) / ((typeof(v))(mul))) * (typeof(v))(mul))
846
852#define RTE_ALIGN_MUL_FLOOR(v, mul) \
853 (((v) / ((typeof(v))(mul))) * (typeof(v))(mul))
854
860#define RTE_ALIGN_MUL_NEAR(v, mul) \
861 __extension__ ({ \
862 typeof(v) ceil = RTE_ALIGN_MUL_CEIL(v, mul); \
863 typeof(v) floor = RTE_ALIGN_MUL_FLOOR(v, mul); \
864 (ceil - (v)) > ((v) - floor) ? floor : ceil; \
865 })
866
884#define RTE_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
885
897static inline int
898rte_is_aligned(const void * const __rte_restrict ptr, const unsigned int align)
899{
900 return ((uintptr_t)ptr & (align - 1)) == 0;
901}
902
903/*********** Macros for compile type checks ********/
904
905/* Workaround for toolchain issues with missing C11 macro in FreeBSD */
906#if !defined(static_assert) && !defined(__cplusplus)
907#define static_assert _Static_assert
908#endif
909
916#define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0)
917
918/*********** Cache line related macros ********/
919
921#define RTE_CACHE_LINE_MASK (RTE_CACHE_LINE_SIZE-1)
922
924#define RTE_CACHE_LINE_ROUNDUP(size) RTE_ALIGN_CEIL(size, RTE_CACHE_LINE_SIZE)
925
927#if RTE_CACHE_LINE_SIZE == 64
928#define RTE_CACHE_LINE_SIZE_LOG2 6
929#elif RTE_CACHE_LINE_SIZE == 128
930#define RTE_CACHE_LINE_SIZE_LOG2 7
931#else
932#error "Unsupported cache line size"
933#endif
934
936#define RTE_CACHE_LINE_MIN_SIZE 64
937
939#define __rte_cache_aligned __rte_aligned(RTE_CACHE_LINE_SIZE)
940
942#define __rte_cache_min_aligned __rte_aligned(RTE_CACHE_LINE_MIN_SIZE)
943
944#define _RTE_CACHE_GUARD_HELPER2(unique) \
945 alignas(RTE_CACHE_LINE_SIZE) \
946 char cache_guard_ ## unique[RTE_CACHE_LINE_SIZE * RTE_CACHE_GUARD_LINES]
947#define _RTE_CACHE_GUARD_HELPER1(unique) _RTE_CACHE_GUARD_HELPER2(unique)
959#define RTE_CACHE_GUARD _RTE_CACHE_GUARD_HELPER1(__LINE__)
960
961/*********** PA/IOVA type definitions ********/
962
964typedef uint64_t phys_addr_t;
965#define RTE_BAD_PHYS_ADDR ((phys_addr_t)-1)
966
974typedef uint64_t rte_iova_t;
975#define RTE_BAD_IOVA ((rte_iova_t)-1)
976
977/*********** Structure alignment markers ********/
978
979#ifndef RTE_TOOLCHAIN_MSVC
980
982__extension__ typedef void *RTE_MARKER[0];
984__extension__ typedef uint8_t RTE_MARKER8[0];
986__extension__ typedef uint16_t RTE_MARKER16[0];
988__extension__ typedef uint32_t RTE_MARKER32[0];
990__extension__ typedef uint64_t RTE_MARKER64[0];
991
992#endif
993
994/*********** Macros for calculating min and max **********/
995
999#define RTE_MIN(a, b) \
1000 __extension__ ({ \
1001 typeof (a) _a_min = (a); \
1002 typeof (b) _b_min = (b); \
1003 _a_min < _b_min ? _a_min : _b_min; \
1004 })
1005
1009#define RTE_MIN3(a, b, c) \
1010 __extension__ ({ \
1011 typeof (a) _a_min3 = (a); \
1012 typeof (b) _b_min3 = (b); \
1013 typeof (c) _c_min3 = (c); \
1014 _a_min3 < _b_min3 ? \
1015 (_a_min3 < _c_min3 ? _a_min3 : _c_min3) : \
1016 (_b_min3 < _c_min3 ? _b_min3 : _c_min3); \
1017 })
1018
1026#define RTE_MIN_T(a, b, t) \
1027 ((t)(a) < (t)(b) ? (t)(a) : (t)(b))
1028
1032#define RTE_MAX(a, b) \
1033 __extension__ ({ \
1034 typeof (a) _a_max = (a); \
1035 typeof (b) _b_max = (b); \
1036 _a_max > _b_max ? _a_max : _b_max; \
1037 })
1038
1042#define RTE_MAX3(a, b, c) \
1043 __extension__ ({ \
1044 typeof (a) _a_max3 = (a); \
1045 typeof (b) _b_max3 = (b); \
1046 typeof (c) _c_max3 = (c); \
1047 _a_max3 > _b_max3 ? \
1048 (_a_max3 > _c_max3 ? _a_max3 : _c_max3) : \
1049 (_b_max3 > _c_max3 ? _b_max3 : _c_max3); \
1050 })
1051
1059#define RTE_MAX_T(a, b, t) \
1060 ((t)(a) > (t)(b) ? (t)(a) : (t)(b))
1061
1062/*********** Other general functions / macros ********/
1063
1064#ifndef offsetof
1066#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
1067#endif
1068
1083#ifndef container_of
1084#ifdef RTE_TOOLCHAIN_MSVC
1085#define container_of(ptr, type, member) \
1086 ((type *)((uintptr_t)(ptr) - offsetof(type, member)))
1087#else
1088#define container_of(ptr, type, member) __extension__ ({ \
1089 const typeof(((type *)0)->member) *_ptr = (ptr); \
1090 __rte_unused type *_target_ptr = \
1091 (type *)(ptr); \
1092 (type *)(((uintptr_t)_ptr) - offsetof(type, member)); \
1093 })
1094#endif
1095#endif
1096
1098#define RTE_SWAP(a, b) \
1099 __extension__ ({ \
1100 typeof (a) _a = a; \
1101 a = b; \
1102 b = _a; \
1103 })
1104
1115#define RTE_SIZEOF_FIELD(type, field) (sizeof(((type *)0)->field))
1116
1117#define _RTE_STR(x) #x
1119#define RTE_STR(x) _RTE_STR(x)
1120
1122#define _RTE_CONCAT2(a, b) a ## b
1123#define RTE_CONCAT(a, b) _RTE_CONCAT2(a, b)
1124
1130#define RTE_FMT(fmt, ...) fmt "%.0s", __VA_ARGS__ ""
1131#define RTE_FMT_HEAD(fmt, ...) fmt
1132#define RTE_FMT_TAIL(fmt, ...) __VA_ARGS__
1133
1135#define RTE_LEN2MASK(ln, tp) \
1136 ((tp)((uint64_t)-1 >> (sizeof(uint64_t) * CHAR_BIT - (ln))))
1137
1139#define RTE_DIM(a) (sizeof (a) / sizeof ((a)[0]))
1140
1155uint64_t
1156rte_str_to_size(const char *str);
1157
1189__rte_experimental
1190char *
1191rte_size_to_str(char *buf, int buf_size, uint64_t count, bool use_iec, const char *unit);
1192
1206__rte_noreturn void
1207rte_exit(int exit_code, const char *format, ...)
1208 __rte_format_printf(2, 3);
1209
1210#ifdef __cplusplus
1211}
1212#endif
1213
1214#endif
uint64_t rte_str_to_size(const char *str)
__extension__ typedef uint64_t RTE_MARKER64[0]
Definition: rte_common.h:990
__extension__ typedef uint8_t RTE_MARKER8[0]
Definition: rte_common.h:984
__extension__ typedef uint32_t RTE_MARKER32[0]
Definition: rte_common.h:988
__extension__ typedef uint16_t RTE_MARKER16[0]
Definition: rte_common.h:986
#define __rte_format_printf(format_index, first_arg)
Definition: rte_common.h:308
uint64_t rte_iova_t
Definition: rte_common.h:974
#define __rte_aligned(a)
Definition: rte_common.h:149
__rte_experimental char * rte_size_to_str(char *buf, int buf_size, uint64_t count, bool use_iec, const char *unit)
static int rte_is_aligned(const void *const __rte_restrict ptr, const unsigned int align)
Definition: rte_common.h:898
__rte_noreturn void rte_exit(int exit_code, const char *format,...) __rte_format_printf(2
#define __rte_noreturn
Definition: rte_common.h:471
uint64_t phys_addr_t
Definition: rte_common.h:964
__extension__ typedef void * RTE_MARKER[0]
Definition: rte_common.h:982
#define __rte_restrict
Definition: rte_common.h:283