21#include <rte_compat.h>
22#include <rte_config.h>
31#ifndef RTE_TOOLCHAIN_MSVC
33#define typeof __typeof__
43#ifdef RTE_TOOLCHAIN_MSVC
81#ifdef RTE_TOOLCHAIN_MSVC
82#define __rte_constant(e) _Generic((1 ? (void *) ((e) * 0ll) : (int *) 0), int * : 1, void * : 0)
84#define __rte_constant(e) __extension__(__builtin_constant_p(e))
93#define RTE_CC_IS_GNU 0
99#define RTE_CC_IS_GNU 1
102#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + \
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
128#if !defined(RTE_TOOLCHAIN_MSVC) && !defined(__cplusplus)
129#define __rte_ptr_arith_add_zero + 0
131#define __rte_ptr_arith_add_zero
146#ifdef RTE_TOOLCHAIN_MSVC
147#define __rte_aligned(a) __declspec(align(a))
149#define __rte_aligned(a) __attribute__((__aligned__(a)))
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;
172#ifdef RTE_TOOLCHAIN_MSVC
173#define __rte_packed_begin __pragma(pack(push, 1))
174#define __rte_packed_end __pragma(pack(pop))
176#define __rte_packed_begin
177#define __rte_packed_end __attribute__((__packed__))
183#ifdef RTE_TOOLCHAIN_MSVC
184#define __rte_may_alias
186#define __rte_may_alias __attribute__((__may_alias__))
190#ifdef RTE_TOOLCHAIN_MSVC
191#define __rte_deprecated
192#define __rte_deprecated_msg(msg)
194#define __rte_deprecated __attribute__((__deprecated__))
195#define __rte_deprecated_msg(msg) __attribute__((__deprecated__(msg)))
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)
206#define RTE_DEPRECATED(x)
213#if !defined(RTE_TOOLCHAIN_MSVC)
214#define __rte_diagnostic_push _Pragma("GCC diagnostic push")
215#define __rte_diagnostic_pop _Pragma("GCC diagnostic pop")
217#define __rte_diagnostic_push
218#define __rte_diagnostic_pop
225#if !defined(RTE_TOOLCHAIN_MSVC)
226#define __rte_diagnostic_ignored_wcast_qual _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
228#define __rte_diagnostic_ignored_wcast_qual
234#if !defined(RTE_TOOLCHAIN_MSVC)
235#define __rte_diagnostic_ignored_array_bounds \
236 _Pragma("GCC diagnostic ignored \"-Warray-bounds\"")
238#define __rte_diagnostic_ignored_array_bounds
244#ifdef RTE_TOOLCHAIN_MSVC
245#define __rte_weak RTE_DEPRECATED(__rte_weak)
247#define __rte_weak RTE_DEPRECATED(__rte_weak) __attribute__((__weak__))
253#ifdef RTE_TOOLCHAIN_MSVC
256#define __rte_pure __attribute__((pure))
262#ifdef RTE_TOOLCHAIN_MSVC
265#define __rte_used __attribute__((used))
273#ifdef RTE_TOOLCHAIN_MSVC
276#define __rte_unused __attribute__((__unused__))
282#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
283#define __rte_restrict __restrict
285#define __rte_restrict restrict
292#define RTE_SET_USED(x) (void)(x)
301#ifdef RTE_TOOLCHAIN_MSVC
302#define __rte_format_printf(format_index, first_arg)
305#define __rte_format_printf(format_index, first_arg) \
306 __attribute__((format(gnu_printf, format_index, first_arg)))
308#define __rte_format_printf(format_index, first_arg) \
309 __attribute__((format(printf, format_index, first_arg)))
316#ifdef RTE_TOOLCHAIN_MSVC
317#define __rte_section(name) \
318 __pragma(data_seg(name)) __declspec(allocate(name))
320#define __rte_section(name) \
321 __attribute__((section(name)))
329#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
330#define __rte_alloc_size(...) \
331 __attribute__((alloc_size(__VA_ARGS__)))
333#define __rte_alloc_size(...)
342#if defined(RTE_CC_GCC)
343#define __rte_alloc_align(argno) \
344 __attribute__((alloc_align(argno)))
346#define __rte_alloc_align(argno)
353#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
354#define __rte_malloc __attribute__((__malloc__))
363#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 110000)
364#define __rte_dealloc(dealloc, argno) \
365 __attribute__((malloc(dealloc, argno)))
367#define __rte_dealloc(dealloc, argno)
370#define RTE_PRIORITY_LOG 101
371#define RTE_PRIORITY_BUS 110
372#define RTE_PRIORITY_CLASS 120
373#define RTE_PRIORITY_LAST 65535
375#define RTE_PRIO(prio) \
376 RTE_PRIORITY_ ## prio
388#ifndef RTE_TOOLCHAIN_MSVC
389#define RTE_INIT_PRIO(func, prio) \
390static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void)
393typedef int(__cdecl *_PIFV)(void);
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"
400#define CTOR_PRIORITY_TO_SECTION(priority) CTOR_SECTION_ ## priority
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)
421#define RTE_INIT(func) \
422 RTE_INIT_PRIO(func, LAST)
434#ifndef RTE_TOOLCHAIN_MSVC
435#define RTE_FINI_PRIO(func, prio) \
436static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
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"
443#define DTOR_PRIORITY_TO_SECTION(priority) DTOR_SECTION_ ## priority
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)
462#define RTE_FINI(func) \
463 RTE_FINI_PRIO(func, LAST)
468#ifdef RTE_TOOLCHAIN_MSVC
469#define __rte_noreturn
471#define __rte_noreturn __attribute__((noreturn))
477#if defined(RTE_TOOLCHAIN_GCC) || defined(RTE_TOOLCHAIN_CLANG)
478#define __rte_unreachable() __extension__(__builtin_unreachable())
480#define __rte_unreachable() __assume(0)
506#ifdef RTE_TOOLCHAIN_MSVC
507#define __rte_warn_unused_result
509#define __rte_warn_unused_result __attribute__((warn_unused_result))
531#ifdef RTE_TOOLCHAIN_MSVC
532#define __rte_always_inline __forceinline
534#define __rte_always_inline inline __attribute__((always_inline))
544#ifdef RTE_TOOLCHAIN_MSVC
545#define __rte_noinline __declspec(noinline)
547#define __rte_noinline __attribute__((noinline))
559#ifdef RTE_TOOLCHAIN_MSVC
562#define __rte_hot __attribute__((hot))
576#ifdef RTE_TOOLCHAIN_MSVC
579#define __rte_cold __attribute__((cold))
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))
595#define __rte_assume(condition) __assume(condition)
601#ifdef RTE_MALLOC_ASAN
603#define __rte_no_asan __attribute__((no_sanitize("address", "hwaddress")))
605#define __rte_no_asan __attribute__((no_sanitize_address))
627#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
628#define RTE_PTR_ADD(ptr, x) \
631 __rte_auto_type __rte_ptr_add = (ptr) __rte_ptr_arith_add_zero; \
632 __rte_diagnostic_push \
633 __rte_diagnostic_ignored_wcast_qual \
635 __rte_auto_type __rte_ptr_add_res = \
636 (1 ? (void *)((char *)__rte_ptr_add + (x)) : __rte_ptr_add); \
637 __rte_diagnostic_pop \
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))
662#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
663#define RTE_PTR_SUB(ptr, x) \
666 __rte_auto_type __rte_ptr_sub = (ptr) __rte_ptr_arith_add_zero; \
667 __rte_diagnostic_push \
668 __rte_diagnostic_ignored_wcast_qual \
670 __rte_auto_type __rte_ptr_sub_res = \
671 (1 ? (void *)((char *)__rte_ptr_sub - (x)) : __rte_ptr_sub); \
672 __rte_diagnostic_pop \
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))
688#define RTE_PTR_DIFF(ptr1, ptr2) ((uintptr_t)(ptr1) - (uintptr_t)(ptr2))
696#define RTE_PTR_UNQUAL(X) ((void *)(uintptr_t)(X))
715#define RTE_CAST_PTR(type, ptr) ((type)(uintptr_t)(ptr))
720#define RTE_CAST_FIELD(var, field, type) \
721 (*(type *)((uintptr_t)(var) + offsetof(typeof(*(var)), field)))
742#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
743#define RTE_PTR_ALIGN_FLOOR(ptr, align) \
746 __rte_auto_type __rte_ptr_floor = (ptr) __rte_ptr_arith_add_zero; \
748 size_t __rte_ptr_floor_misalign = (uintptr_t)__rte_ptr_floor & ((align) - 1); \
749 __rte_diagnostic_push \
750 __rte_diagnostic_ignored_wcast_qual \
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; \
759#define RTE_PTR_ALIGN_FLOOR(ptr, align) \
760 ((typeof(ptr))RTE_ALIGN_FLOOR((uintptr_t) ((ptr) __rte_ptr_arith_add_zero), align))
769#define RTE_ALIGN_FLOOR(val, align) \
770 (typeof(val))((val) & (~((typeof(val))((align) - 1))))
788#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
789#define RTE_PTR_ALIGN_CEIL(ptr, align) \
792 __rte_auto_type __rte_ptr_ceil = (ptr) __rte_ptr_arith_add_zero; \
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 \
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; \
808#define RTE_PTR_ALIGN_CEIL(ptr, align) \
809 RTE_PTR_ALIGN_FLOOR((typeof(ptr))RTE_PTR_ADD(ptr, (align) - 1), align)
818#define RTE_ALIGN_CEIL(val, align) \
819 RTE_ALIGN_FLOOR(((val) + ((typeof(val)) (align) - 1)), align)
828#define RTE_PTR_ALIGN(ptr, align) RTE_PTR_ALIGN_CEIL(ptr, align)
837#define RTE_ALIGN(val, align) RTE_ALIGN_CEIL(val, align)
844#define RTE_ALIGN_MUL_CEIL(v, mul) \
845 ((((v) + (typeof(v))(mul) - 1) / ((typeof(v))(mul))) * (typeof(v))(mul))
852#define RTE_ALIGN_MUL_FLOOR(v, mul) \
853 (((v) / ((typeof(v))(mul))) * (typeof(v))(mul))
860#define RTE_ALIGN_MUL_NEAR(v, mul) \
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; \
884#define RTE_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
900 return ((uintptr_t)ptr & (align - 1)) == 0;
906#if !defined(static_assert) && !defined(__cplusplus)
907#define static_assert _Static_assert
916#define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0)
921#define RTE_CACHE_LINE_MASK (RTE_CACHE_LINE_SIZE-1)
924#define RTE_CACHE_LINE_ROUNDUP(size) RTE_ALIGN_CEIL(size, RTE_CACHE_LINE_SIZE)
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
932#error "Unsupported cache line size"
936#define RTE_CACHE_LINE_MIN_SIZE 64
939#define __rte_cache_aligned __rte_aligned(RTE_CACHE_LINE_SIZE)
942#define __rte_cache_min_aligned __rte_aligned(RTE_CACHE_LINE_MIN_SIZE)
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__)
965#define RTE_BAD_PHYS_ADDR ((phys_addr_t)-1)
975#define RTE_BAD_IOVA ((rte_iova_t)-1)
979#ifndef RTE_TOOLCHAIN_MSVC
999#define RTE_MIN(a, b) \
1001 typeof (a) _a_min = (a); \
1002 typeof (b) _b_min = (b); \
1003 _a_min < _b_min ? _a_min : _b_min; \
1009#define RTE_MIN3(a, b, c) \
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); \
1026#define RTE_MIN_T(a, b, t) \
1027 ((t)(a) < (t)(b) ? (t)(a) : (t)(b))
1032#define RTE_MAX(a, b) \
1034 typeof (a) _a_max = (a); \
1035 typeof (b) _b_max = (b); \
1036 _a_max > _b_max ? _a_max : _b_max; \
1042#define RTE_MAX3(a, b, c) \
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); \
1059#define RTE_MAX_T(a, b, t) \
1060 ((t)(a) > (t)(b) ? (t)(a) : (t)(b))
1066#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
1084#ifdef RTE_TOOLCHAIN_MSVC
1085#define container_of(ptr, type, member) \
1086 ((type *)((uintptr_t)(ptr) - offsetof(type, member)))
1088#define container_of(ptr, type, member) __extension__ ({ \
1089 const typeof(((type *)0)->member) *_ptr = (ptr); \
1090 __rte_unused type *_target_ptr = \
1092 (type *)(((uintptr_t)_ptr) - offsetof(type, member)); \
1098#define RTE_SWAP(a, b) \
1100 typeof (a) _a = a; \
1115#define RTE_SIZEOF_FIELD(type, field) (sizeof(((type *)0)->field))
1117#define _RTE_STR(x) #x
1119#define RTE_STR(x) _RTE_STR(x)
1122#define _RTE_CONCAT2(a, b) a ## b
1123#define RTE_CONCAT(a, b) _RTE_CONCAT2(a, b)
1130#define RTE_FMT(fmt, ...) fmt "%.0s", __VA_ARGS__ ""
1131#define RTE_FMT_HEAD(fmt, ...) fmt
1132#define RTE_FMT_TAIL(fmt, ...) __VA_ARGS__
1135#define RTE_LEN2MASK(ln, tp) \
1136 ((tp)((uint64_t)-1 >> (sizeof(uint64_t) * CHAR_BIT - (ln))))
1139#define RTE_DIM(a) (sizeof (a) / sizeof ((a)[0]))
uint64_t rte_str_to_size(const char *str)
__extension__ typedef uint64_t RTE_MARKER64[0]
__extension__ typedef uint8_t RTE_MARKER8[0]
__extension__ typedef uint32_t RTE_MARKER32[0]
__extension__ typedef uint16_t RTE_MARKER16[0]
#define __rte_format_printf(format_index, first_arg)
__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)
__rte_noreturn void rte_exit(int exit_code, const char *format,...) __rte_format_printf(2
__extension__ typedef void * RTE_MARKER[0]