xref: /dpdk/lib/eal/include/rte_common.h (revision a1b873f1de53d202ccd905d3b5ff3e561a5381ce)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2010-2019 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #ifndef _RTE_COMMON_H_
699a2dd95SBruce Richardson #define _RTE_COMMON_H_
799a2dd95SBruce Richardson 
899a2dd95SBruce Richardson /**
999a2dd95SBruce Richardson  * @file
1099a2dd95SBruce Richardson  *
1199a2dd95SBruce Richardson  * Generic, commonly-used macro and inline function definitions
1299a2dd95SBruce Richardson  * for DPDK.
1399a2dd95SBruce Richardson  */
1499a2dd95SBruce Richardson 
15537caad2SStephen Hemminger #include <assert.h>
1699a2dd95SBruce Richardson #include <limits.h>
17e9fd1ebfSTyler Retzlaff #include <stdint.h>
18e9fd1ebfSTyler Retzlaff #include <stdalign.h>
1999a2dd95SBruce Richardson 
2099a2dd95SBruce Richardson #include <rte_config.h>
2199a2dd95SBruce Richardson 
2299a2dd95SBruce Richardson /* OS specific include */
2399a2dd95SBruce Richardson #include <rte_os.h>
2499a2dd95SBruce Richardson 
25719834a6SMattias Rönnblom #ifdef __cplusplus
26719834a6SMattias Rönnblom extern "C" {
27719834a6SMattias Rönnblom #endif
28719834a6SMattias Rönnblom 
29e7afce06STyler Retzlaff #ifndef RTE_TOOLCHAIN_MSVC
3099a2dd95SBruce Richardson #ifndef typeof
3199a2dd95SBruce Richardson #define typeof __typeof__
3299a2dd95SBruce Richardson #endif
33e7afce06STyler Retzlaff #endif
3499a2dd95SBruce Richardson 
3599a2dd95SBruce Richardson #ifndef __cplusplus
3699a2dd95SBruce Richardson #ifndef asm
3799a2dd95SBruce Richardson #define asm __asm__
3899a2dd95SBruce Richardson #endif
3999a2dd95SBruce Richardson #endif
4099a2dd95SBruce Richardson 
4151574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
42d065725bSTyler Retzlaff #ifdef __cplusplus
4351574a4fSTyler Retzlaff #define __extension__
4451574a4fSTyler Retzlaff #endif
45d065725bSTyler Retzlaff #endif
4651574a4fSTyler Retzlaff 
47940daaddSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
48940daaddSTyler Retzlaff #define __rte_constant(e) 0
49940daaddSTyler Retzlaff #else
50940daaddSTyler Retzlaff #define __rte_constant(e) __extension__(__builtin_constant_p(e))
51940daaddSTyler Retzlaff #endif
52940daaddSTyler Retzlaff 
5399a2dd95SBruce Richardson /*
5499a2dd95SBruce Richardson  * RTE_TOOLCHAIN_GCC is defined if the target is built with GCC,
5599a2dd95SBruce Richardson  * while a host application (like pmdinfogen) may have another compiler.
5699a2dd95SBruce Richardson  * RTE_CC_IS_GNU is true if the file is compiled with GCC,
5799a2dd95SBruce Richardson  * no matter it is a target or host application.
5899a2dd95SBruce Richardson  */
5999a2dd95SBruce Richardson #define RTE_CC_IS_GNU 0
6099a2dd95SBruce Richardson #if defined __clang__
6199a2dd95SBruce Richardson #define RTE_CC_CLANG
6299a2dd95SBruce Richardson #elif defined __INTEL_COMPILER
6399a2dd95SBruce Richardson #define RTE_CC_ICC
6499a2dd95SBruce Richardson #elif defined __GNUC__
6599a2dd95SBruce Richardson #define RTE_CC_GCC
6699a2dd95SBruce Richardson #undef RTE_CC_IS_GNU
6799a2dd95SBruce Richardson #define RTE_CC_IS_GNU 1
6899a2dd95SBruce Richardson #endif
6999a2dd95SBruce Richardson #if RTE_CC_IS_GNU
7099a2dd95SBruce Richardson #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 +	\
7199a2dd95SBruce Richardson 		__GNUC_PATCHLEVEL__)
7299a2dd95SBruce Richardson #endif
7399a2dd95SBruce Richardson 
7499a2dd95SBruce Richardson /**
75c6552d9aSTyler Retzlaff  * Force type alignment
76c6552d9aSTyler Retzlaff  *
77c6552d9aSTyler Retzlaff  * This macro should be used when alignment of a struct or union type
78c6552d9aSTyler Retzlaff  * is required. For toolchain compatibility it should appear between
79c6552d9aSTyler Retzlaff  * the {struct,union} keyword and tag. e.g.
80c6552d9aSTyler Retzlaff  *
81c6552d9aSTyler Retzlaff  *   struct __rte_aligned(8) tag { ... };
82c6552d9aSTyler Retzlaff  *
83c6552d9aSTyler Retzlaff  * If alignment of an object/variable is required then this macro should
84c6552d9aSTyler Retzlaff  * not be used, instead prefer C11 alignas(a).
8599a2dd95SBruce Richardson  */
8651574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
87c6552d9aSTyler Retzlaff #define __rte_aligned(a) __declspec(align(a))
8851574a4fSTyler Retzlaff #else
8999a2dd95SBruce Richardson #define __rte_aligned(a) __attribute__((__aligned__(a)))
9051574a4fSTyler Retzlaff #endif
9199a2dd95SBruce Richardson 
9299a2dd95SBruce Richardson #ifdef RTE_ARCH_STRICT_ALIGN
9399a2dd95SBruce Richardson typedef uint64_t unaligned_uint64_t __rte_aligned(1);
9499a2dd95SBruce Richardson typedef uint32_t unaligned_uint32_t __rte_aligned(1);
9599a2dd95SBruce Richardson typedef uint16_t unaligned_uint16_t __rte_aligned(1);
9699a2dd95SBruce Richardson #else
9799a2dd95SBruce Richardson typedef uint64_t unaligned_uint64_t;
9899a2dd95SBruce Richardson typedef uint32_t unaligned_uint32_t;
9999a2dd95SBruce Richardson typedef uint16_t unaligned_uint16_t;
10099a2dd95SBruce Richardson #endif
10199a2dd95SBruce Richardson 
10299a2dd95SBruce Richardson /**
103154303b0SAndre Muezerie  * @deprecated
104154303b0SAndre Muezerie  * @see __rte_packed_begin
105154303b0SAndre Muezerie  * @see __rte_packed_end
106154303b0SAndre Muezerie  *
107154303b0SAndre Muezerie  * Force a structure to be packed
108154303b0SAndre Muezerie  */
109154303b0SAndre Muezerie #ifdef RTE_TOOLCHAIN_MSVC
110154303b0SAndre Muezerie #define __rte_packed RTE_DEPRECATED(__rte_packed)
111154303b0SAndre Muezerie #else
112154303b0SAndre Muezerie #define __rte_packed (RTE_DEPRECATED(__rte_packed) __attribute__((__packed__)))
113154303b0SAndre Muezerie #endif
114154303b0SAndre Muezerie 
115154303b0SAndre Muezerie /**
11699a2dd95SBruce Richardson  * Force a structure to be packed
117fac4bc0dSAndre Muezerie  * Usage:
118fac4bc0dSAndre Muezerie  *     struct __rte_packed_begin mystruct { ... } __rte_packed_end;
119fac4bc0dSAndre Muezerie  *     union __rte_packed_begin myunion { ... } __rte_packed_end;
120fac4bc0dSAndre Muezerie  * Note: alignment attributes when present should precede __rte_packed_begin.
12199a2dd95SBruce Richardson  */
12251574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
123fac4bc0dSAndre Muezerie #define __rte_packed_begin __pragma(pack(push, 1))
124fac4bc0dSAndre Muezerie #define __rte_packed_end __pragma(pack(pop))
12551574a4fSTyler Retzlaff #else
126fac4bc0dSAndre Muezerie #define __rte_packed_begin
127fac4bc0dSAndre Muezerie #define __rte_packed_end __attribute__((__packed__))
12851574a4fSTyler Retzlaff #endif
12999a2dd95SBruce Richardson 
13000901e4dSLuc Pelletier /**
13100901e4dSLuc Pelletier  * Macro to mark a type that is not subject to type-based aliasing rules
13200901e4dSLuc Pelletier  */
13351574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
13451574a4fSTyler Retzlaff #define __rte_may_alias
13551574a4fSTyler Retzlaff #else
13600901e4dSLuc Pelletier #define __rte_may_alias __attribute__((__may_alias__))
13751574a4fSTyler Retzlaff #endif
13800901e4dSLuc Pelletier 
13999a2dd95SBruce Richardson /******* Macro to mark functions and fields scheduled for removal *****/
14051574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
14151574a4fSTyler Retzlaff #define __rte_deprecated
14251574a4fSTyler Retzlaff #define __rte_deprecated_msg(msg)
14351574a4fSTyler Retzlaff #else
14499a2dd95SBruce Richardson #define __rte_deprecated	__attribute__((__deprecated__))
14599a2dd95SBruce Richardson #define __rte_deprecated_msg(msg)	__attribute__((__deprecated__(msg)))
14651574a4fSTyler Retzlaff #endif
14799a2dd95SBruce Richardson 
14899a2dd95SBruce Richardson /**
14999a2dd95SBruce Richardson  *  Macro to mark macros and defines scheduled for removal
15099a2dd95SBruce Richardson  */
15199a2dd95SBruce Richardson #if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
15299a2dd95SBruce Richardson #define RTE_PRAGMA(x)  _Pragma(#x)
15399a2dd95SBruce Richardson #define RTE_PRAGMA_WARNING(w) RTE_PRAGMA(GCC warning #w)
15499a2dd95SBruce Richardson #define RTE_DEPRECATED(x)  RTE_PRAGMA_WARNING(#x is deprecated)
15599a2dd95SBruce Richardson #else
15699a2dd95SBruce Richardson #define RTE_DEPRECATED(x)
15799a2dd95SBruce Richardson #endif
15899a2dd95SBruce Richardson 
15999a2dd95SBruce Richardson /**
160*a1b873f1SAndre Muezerie  * Macros to cause the compiler to remember the state of the diagnostics as of
161*a1b873f1SAndre Muezerie  * each push, and restore to that point at each pop.
162*a1b873f1SAndre Muezerie  */
163*a1b873f1SAndre Muezerie #if !defined(__INTEL_COMPILER) && !defined(RTE_TOOLCHAIN_MSVC)
164*a1b873f1SAndre Muezerie #define __rte_diagnostic_push _Pragma("GCC diagnostic push")
165*a1b873f1SAndre Muezerie #define __rte_diagnostic_pop  _Pragma("GCC diagnostic pop")
166*a1b873f1SAndre Muezerie #else
167*a1b873f1SAndre Muezerie #define __rte_diagnostic_push
168*a1b873f1SAndre Muezerie #define __rte_diagnostic_pop
169*a1b873f1SAndre Muezerie #endif
170*a1b873f1SAndre Muezerie 
171*a1b873f1SAndre Muezerie /**
172*a1b873f1SAndre Muezerie  * Macro to disable compiler warnings about removing a type
173*a1b873f1SAndre Muezerie  * qualifier from the target type.
174*a1b873f1SAndre Muezerie  */
175*a1b873f1SAndre Muezerie #if !defined(__INTEL_COMPILER) && !defined(RTE_TOOLCHAIN_MSVC)
176*a1b873f1SAndre Muezerie #define __rte_diagnostic_ignored_wcast_qual _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
177*a1b873f1SAndre Muezerie #else
178*a1b873f1SAndre Muezerie #define __rte_diagnostic_ignored_wcast_qual
179*a1b873f1SAndre Muezerie #endif
180*a1b873f1SAndre Muezerie 
181*a1b873f1SAndre Muezerie /**
18299a2dd95SBruce Richardson  * Mark a function or variable to a weak reference.
18399a2dd95SBruce Richardson  */
18499a2dd95SBruce Richardson #define __rte_weak __attribute__((__weak__))
18599a2dd95SBruce Richardson 
18699a2dd95SBruce Richardson /**
187ff933786STyler Retzlaff  * Mark a function to be pure.
188ff933786STyler Retzlaff  */
189ff933786STyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
190ff933786STyler Retzlaff #define __rte_pure
191ff933786STyler Retzlaff #else
192ff933786STyler Retzlaff #define __rte_pure __attribute__((pure))
193ff933786STyler Retzlaff #endif
194ff933786STyler Retzlaff 
195ff933786STyler Retzlaff /**
19699a2dd95SBruce Richardson  * Force symbol to be generated even if it appears to be unused.
19799a2dd95SBruce Richardson  */
19851574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
19951574a4fSTyler Retzlaff #define __rte_used
20051574a4fSTyler Retzlaff #else
20199a2dd95SBruce Richardson #define __rte_used __attribute__((used))
20251574a4fSTyler Retzlaff #endif
20399a2dd95SBruce Richardson 
20499a2dd95SBruce Richardson /*********** Macros to eliminate unused variable warnings ********/
20599a2dd95SBruce Richardson 
20699a2dd95SBruce Richardson /**
20799a2dd95SBruce Richardson  * short definition to mark a function parameter unused
20899a2dd95SBruce Richardson  */
20951574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
21051574a4fSTyler Retzlaff #define __rte_unused
21151574a4fSTyler Retzlaff #else
21299a2dd95SBruce Richardson #define __rte_unused __attribute__((__unused__))
21351574a4fSTyler Retzlaff #endif
21499a2dd95SBruce Richardson 
21599a2dd95SBruce Richardson /**
21699a2dd95SBruce Richardson  * Mark pointer as restricted with regard to pointer aliasing.
21799a2dd95SBruce Richardson  */
21899a2dd95SBruce Richardson #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
21999a2dd95SBruce Richardson #define __rte_restrict __restrict
22099a2dd95SBruce Richardson #else
22199a2dd95SBruce Richardson #define __rte_restrict restrict
22299a2dd95SBruce Richardson #endif
22399a2dd95SBruce Richardson 
22499a2dd95SBruce Richardson /**
22599a2dd95SBruce Richardson  * definition to mark a variable or function parameter as used so
22699a2dd95SBruce Richardson  * as to avoid a compiler warning
22799a2dd95SBruce Richardson  */
22899a2dd95SBruce Richardson #define RTE_SET_USED(x) (void)(x)
22999a2dd95SBruce Richardson 
23099a2dd95SBruce Richardson /**
23199a2dd95SBruce Richardson  * Check format string and its arguments at compile-time.
23299a2dd95SBruce Richardson  *
23399a2dd95SBruce Richardson  * GCC on Windows assumes MS-specific format string by default,
23499a2dd95SBruce Richardson  * even if the underlying stdio implementation is ANSI-compliant,
23599a2dd95SBruce Richardson  * so this must be overridden.
23699a2dd95SBruce Richardson  */
23751574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
23851574a4fSTyler Retzlaff #define __rte_format_printf(format_index, first_arg)
23951574a4fSTyler Retzlaff #else
24099a2dd95SBruce Richardson #if RTE_CC_IS_GNU
24199a2dd95SBruce Richardson #define __rte_format_printf(format_index, first_arg) \
24299a2dd95SBruce Richardson 	__attribute__((format(gnu_printf, format_index, first_arg)))
24399a2dd95SBruce Richardson #else
24499a2dd95SBruce Richardson #define __rte_format_printf(format_index, first_arg) \
24599a2dd95SBruce Richardson 	__attribute__((format(printf, format_index, first_arg)))
24699a2dd95SBruce Richardson #endif
24751574a4fSTyler Retzlaff #endif
24899a2dd95SBruce Richardson 
24999a2dd95SBruce Richardson /**
25074fff67aSTyler Retzlaff  * Specify data or function section/segment.
25174fff67aSTyler Retzlaff  */
25274fff67aSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
25374fff67aSTyler Retzlaff #define __rte_section(name) \
25474fff67aSTyler Retzlaff 	__pragma(data_seg(name)) __declspec(allocate(name))
25574fff67aSTyler Retzlaff #else
25674fff67aSTyler Retzlaff #define __rte_section(name) \
25774fff67aSTyler Retzlaff 	__attribute__((section(name)))
25874fff67aSTyler Retzlaff #endif
25974fff67aSTyler Retzlaff 
26074fff67aSTyler Retzlaff /**
26199a2dd95SBruce Richardson  * Tells compiler that the function returns a value that points to
26299a2dd95SBruce Richardson  * memory, where the size is given by the one or two arguments.
26399a2dd95SBruce Richardson  * Used by compiler to validate object size.
26499a2dd95SBruce Richardson  */
26599a2dd95SBruce Richardson #if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
26699a2dd95SBruce Richardson #define __rte_alloc_size(...) \
26799a2dd95SBruce Richardson 	__attribute__((alloc_size(__VA_ARGS__)))
26899a2dd95SBruce Richardson #else
26999a2dd95SBruce Richardson #define __rte_alloc_size(...)
27099a2dd95SBruce Richardson #endif
27199a2dd95SBruce Richardson 
27280da7efbSStephen Hemminger /**
27380da7efbSStephen Hemminger  * Tells the compiler that the function returns a value that points to
27480da7efbSStephen Hemminger  * memory aligned by a function argument.
27580da7efbSStephen Hemminger  *
27680da7efbSStephen Hemminger  * Note: not enabled on Clang because it warns if align argument is zero.
27780da7efbSStephen Hemminger  */
27880da7efbSStephen Hemminger #if defined(RTE_CC_GCC)
27980da7efbSStephen Hemminger #define __rte_alloc_align(argno) \
28080da7efbSStephen Hemminger 	__attribute__((alloc_align(argno)))
28180da7efbSStephen Hemminger #else
28280da7efbSStephen Hemminger #define __rte_alloc_align(argno)
28380da7efbSStephen Hemminger #endif
28480da7efbSStephen Hemminger 
28580da7efbSStephen Hemminger /**
28680da7efbSStephen Hemminger  * Tells the compiler this is a function like malloc and that the pointer
28780da7efbSStephen Hemminger  * returned cannot alias any other pointer (ie new memory).
28880da7efbSStephen Hemminger  */
28980da7efbSStephen Hemminger #if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
29080da7efbSStephen Hemminger #define __rte_malloc __attribute__((__malloc__))
29180da7efbSStephen Hemminger #else
29280da7efbSStephen Hemminger #define __rte_malloc
29380da7efbSStephen Hemminger #endif
29480da7efbSStephen Hemminger 
29580da7efbSStephen Hemminger /**
29680da7efbSStephen Hemminger  * With recent GCC versions also able to track that proper
29780da7efbSStephen Hemminger  * deallocator function is used for this pointer.
29880da7efbSStephen Hemminger  */
29980da7efbSStephen Hemminger #if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 110000)
30080da7efbSStephen Hemminger #define __rte_dealloc(dealloc, argno) \
30180da7efbSStephen Hemminger 	__attribute__((malloc(dealloc, argno)))
30280da7efbSStephen Hemminger #else
30380da7efbSStephen Hemminger #define __rte_dealloc(dealloc, argno)
30480da7efbSStephen Hemminger #endif
30580da7efbSStephen Hemminger 
30699a2dd95SBruce Richardson #define RTE_PRIORITY_LOG 101
30799a2dd95SBruce Richardson #define RTE_PRIORITY_BUS 110
30899a2dd95SBruce Richardson #define RTE_PRIORITY_CLASS 120
30999a2dd95SBruce Richardson #define RTE_PRIORITY_LAST 65535
31099a2dd95SBruce Richardson 
31199a2dd95SBruce Richardson #define RTE_PRIO(prio) \
31299a2dd95SBruce Richardson 	RTE_PRIORITY_ ## prio
31399a2dd95SBruce Richardson 
31499a2dd95SBruce Richardson /**
31599a2dd95SBruce Richardson  * Run function before main() with high priority.
31699a2dd95SBruce Richardson  *
31799a2dd95SBruce Richardson  * @param func
31899a2dd95SBruce Richardson  *   Constructor function.
31999a2dd95SBruce Richardson  * @param prio
32099a2dd95SBruce Richardson  *   Priority number must be above 100.
32199a2dd95SBruce Richardson  *   Lowest number is the first to run.
32299a2dd95SBruce Richardson  */
32399a2dd95SBruce Richardson #ifndef RTE_INIT_PRIO /* Allow to override from EAL */
32464eff943STyler Retzlaff #ifndef RTE_TOOLCHAIN_MSVC
32599a2dd95SBruce Richardson #define RTE_INIT_PRIO(func, prio) \
32699a2dd95SBruce Richardson static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void)
32764eff943STyler Retzlaff #else
32864eff943STyler Retzlaff /* definition from the Microsoft CRT */
32964eff943STyler Retzlaff typedef int(__cdecl *_PIFV)(void);
33064eff943STyler Retzlaff 
33164eff943STyler Retzlaff #define CTOR_SECTION_LOG ".CRT$XIB"
33264eff943STyler Retzlaff #define CTOR_SECTION_BUS ".CRT$XIC"
33364eff943STyler Retzlaff #define CTOR_SECTION_CLASS ".CRT$XID"
33464eff943STyler Retzlaff #define CTOR_SECTION_LAST ".CRT$XIY"
33564eff943STyler Retzlaff 
33664eff943STyler Retzlaff #define CTOR_PRIORITY_TO_SECTION(priority) CTOR_SECTION_ ## priority
33764eff943STyler Retzlaff 
33864eff943STyler Retzlaff #define RTE_INIT_PRIO(name, priority) \
33964eff943STyler Retzlaff 	static void name(void); \
34064eff943STyler Retzlaff 	static int __cdecl name ## _thunk(void) { name(); return 0; } \
34164eff943STyler Retzlaff 	__pragma(const_seg(CTOR_PRIORITY_TO_SECTION(priority))) \
34264eff943STyler Retzlaff 	__declspec(allocate(CTOR_PRIORITY_TO_SECTION(priority))) \
34364eff943STyler Retzlaff 	    _PIFV name ## _pointer = &name ## _thunk; \
34464eff943STyler Retzlaff 	__pragma(const_seg()) \
34564eff943STyler Retzlaff 	static void name(void)
34664eff943STyler Retzlaff #endif
34799a2dd95SBruce Richardson #endif
34899a2dd95SBruce Richardson 
34999a2dd95SBruce Richardson /**
35099a2dd95SBruce Richardson  * Run function before main() with low priority.
35199a2dd95SBruce Richardson  *
35299a2dd95SBruce Richardson  * The constructor will be run after prioritized constructors.
35399a2dd95SBruce Richardson  *
35499a2dd95SBruce Richardson  * @param func
35599a2dd95SBruce Richardson  *   Constructor function.
35699a2dd95SBruce Richardson  */
35799a2dd95SBruce Richardson #define RTE_INIT(func) \
35899a2dd95SBruce Richardson 	RTE_INIT_PRIO(func, LAST)
35999a2dd95SBruce Richardson 
36099a2dd95SBruce Richardson /**
36199a2dd95SBruce Richardson  * Run after main() with low priority.
36299a2dd95SBruce Richardson  *
36399a2dd95SBruce Richardson  * @param func
36499a2dd95SBruce Richardson  *   Destructor function name.
36599a2dd95SBruce Richardson  * @param prio
36699a2dd95SBruce Richardson  *   Priority number must be above 100.
36799a2dd95SBruce Richardson  *   Lowest number is the last to run.
36899a2dd95SBruce Richardson  */
36999a2dd95SBruce Richardson #ifndef RTE_FINI_PRIO /* Allow to override from EAL */
37064eff943STyler Retzlaff #ifndef RTE_TOOLCHAIN_MSVC
37199a2dd95SBruce Richardson #define RTE_FINI_PRIO(func, prio) \
37299a2dd95SBruce Richardson static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
37364eff943STyler Retzlaff #else
37464eff943STyler Retzlaff #define DTOR_SECTION_LOG "mydtor$B"
37564eff943STyler Retzlaff #define DTOR_SECTION_BUS "mydtor$C"
37664eff943STyler Retzlaff #define DTOR_SECTION_CLASS "mydtor$D"
37764eff943STyler Retzlaff #define DTOR_SECTION_LAST "mydtor$Y"
37864eff943STyler Retzlaff 
37964eff943STyler Retzlaff #define DTOR_PRIORITY_TO_SECTION(priority) DTOR_SECTION_ ## priority
38064eff943STyler Retzlaff 
38164eff943STyler Retzlaff #define RTE_FINI_PRIO(name, priority) \
38264eff943STyler Retzlaff 	static void name(void); \
38364eff943STyler Retzlaff 	__pragma(const_seg(DTOR_PRIORITY_TO_SECTION(priority))) \
384e5bf3e39STyler Retzlaff 	__declspec(allocate(DTOR_PRIORITY_TO_SECTION(priority))) void *name ## _pointer = &name; \
38564eff943STyler Retzlaff 	__pragma(const_seg()) \
38664eff943STyler Retzlaff 	static void name(void)
38764eff943STyler Retzlaff #endif
38899a2dd95SBruce Richardson #endif
38999a2dd95SBruce Richardson 
39099a2dd95SBruce Richardson /**
39199a2dd95SBruce Richardson  * Run after main() with high priority.
39299a2dd95SBruce Richardson  *
39399a2dd95SBruce Richardson  * The destructor will be run *before* prioritized destructors.
39499a2dd95SBruce Richardson  *
39599a2dd95SBruce Richardson  * @param func
39699a2dd95SBruce Richardson  *   Destructor function name.
39799a2dd95SBruce Richardson  */
39899a2dd95SBruce Richardson #define RTE_FINI(func) \
39999a2dd95SBruce Richardson 	RTE_FINI_PRIO(func, LAST)
40099a2dd95SBruce Richardson 
40199a2dd95SBruce Richardson /**
40299a2dd95SBruce Richardson  * Hint never returning function
40399a2dd95SBruce Richardson  */
40451574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
40551574a4fSTyler Retzlaff #define __rte_noreturn
40651574a4fSTyler Retzlaff #else
40799a2dd95SBruce Richardson #define __rte_noreturn __attribute__((noreturn))
40851574a4fSTyler Retzlaff #endif
40999a2dd95SBruce Richardson 
41099a2dd95SBruce Richardson /**
411bf7ded9aSMorten Brørup  * Hint point in program never reached
412bf7ded9aSMorten Brørup  */
413bf7ded9aSMorten Brørup #if defined(RTE_TOOLCHAIN_GCC) || defined(RTE_TOOLCHAIN_CLANG)
414bf7ded9aSMorten Brørup #define __rte_unreachable() __extension__(__builtin_unreachable())
415bf7ded9aSMorten Brørup #else
416bf7ded9aSMorten Brørup #define __rte_unreachable() __assume(0)
417bf7ded9aSMorten Brørup #endif
418bf7ded9aSMorten Brørup 
419bf7ded9aSMorten Brørup /**
420eb13e558SMattias Rönnblom  * Issue a warning in case the function's return value is ignored.
421eb13e558SMattias Rönnblom  *
422eb13e558SMattias Rönnblom  * The use of this attribute should be restricted to cases where
423eb13e558SMattias Rönnblom  * ignoring the marked function's return value is almost always a
424eb13e558SMattias Rönnblom  * bug. With GCC, some effort is required to make clear that ignoring
425eb13e558SMattias Rönnblom  * the return value is intentional. The usual void-casting method to
426eb13e558SMattias Rönnblom  * mark something unused as used does not suppress the warning with
427eb13e558SMattias Rönnblom  * this compiler.
428eb13e558SMattias Rönnblom  *
429eb13e558SMattias Rönnblom  * @code{.c}
430eb13e558SMattias Rönnblom  * __rte_warn_unused_result int foo();
431eb13e558SMattias Rönnblom  *
432eb13e558SMattias Rönnblom  * void ignore_foo_result(void) {
433eb13e558SMattias Rönnblom  *         foo(); // generates a warning with all compilers
434eb13e558SMattias Rönnblom  *
435eb13e558SMattias Rönnblom  *         (void)foo(); // still generates the warning with GCC (but not clang)
436eb13e558SMattias Rönnblom  *
437eb13e558SMattias Rönnblom  *         int unused __rte_unused;
438eb13e558SMattias Rönnblom  *         unused = foo(); // does the trick with all compilers
439eb13e558SMattias Rönnblom  *  }
440eb13e558SMattias Rönnblom  * @endcode
441eb13e558SMattias Rönnblom  */
44251574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
44351574a4fSTyler Retzlaff #define __rte_warn_unused_result
44451574a4fSTyler Retzlaff #else
445eb13e558SMattias Rönnblom #define __rte_warn_unused_result __attribute__((warn_unused_result))
44651574a4fSTyler Retzlaff #endif
447eb13e558SMattias Rönnblom 
448eb13e558SMattias Rönnblom /**
44999a2dd95SBruce Richardson  * Force a function to be inlined
45099a2dd95SBruce Richardson  */
45151574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
4524b4ed9ccSAndre Muezerie #define __rte_always_inline __forceinline
45351574a4fSTyler Retzlaff #else
45499a2dd95SBruce Richardson #define __rte_always_inline inline __attribute__((always_inline))
45551574a4fSTyler Retzlaff #endif
45699a2dd95SBruce Richardson 
45799a2dd95SBruce Richardson /**
45899a2dd95SBruce Richardson  * Force a function to be noinlined
45999a2dd95SBruce Richardson  */
4604b4ed9ccSAndre Muezerie #ifdef RTE_TOOLCHAIN_MSVC
4614b4ed9ccSAndre Muezerie #define __rte_noinline __declspec(noinline)
4624b4ed9ccSAndre Muezerie #else
46399a2dd95SBruce Richardson #define __rte_noinline __attribute__((noinline))
4644b4ed9ccSAndre Muezerie #endif
46599a2dd95SBruce Richardson 
46699a2dd95SBruce Richardson /**
46799a2dd95SBruce Richardson  * Hint function in the hot path
46899a2dd95SBruce Richardson  */
4694b4ed9ccSAndre Muezerie #ifdef RTE_TOOLCHAIN_MSVC
4704b4ed9ccSAndre Muezerie #define __rte_hot
4714b4ed9ccSAndre Muezerie #else
47299a2dd95SBruce Richardson #define __rte_hot __attribute__((hot))
4734b4ed9ccSAndre Muezerie #endif
47499a2dd95SBruce Richardson 
47599a2dd95SBruce Richardson /**
47699a2dd95SBruce Richardson  * Hint function in the cold path
47799a2dd95SBruce Richardson  */
47851574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
47951574a4fSTyler Retzlaff #define __rte_cold
48051574a4fSTyler Retzlaff #else
48199a2dd95SBruce Richardson #define __rte_cold __attribute__((cold))
48251574a4fSTyler Retzlaff #endif
48399a2dd95SBruce Richardson 
48448ff13efSDavid Marchand /**
485bf7ded9aSMorten Brørup  * Hint precondition
486bf7ded9aSMorten Brørup  *
487bf7ded9aSMorten Brørup  * @warning Depending on the compiler, any code in ``condition`` might be executed.
488bf7ded9aSMorten Brørup  * This currently only occurs with GCC prior to version 13.
489bf7ded9aSMorten Brørup  */
490bf7ded9aSMorten Brørup #if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 130000)
491bf7ded9aSMorten Brørup #define __rte_assume(condition) __attribute__((assume(condition)))
492bf7ded9aSMorten Brørup #elif defined(RTE_TOOLCHAIN_GCC)
493bf7ded9aSMorten Brørup #define __rte_assume(condition) do { if (!(condition)) __rte_unreachable(); } while (0)
494bf7ded9aSMorten Brørup #elif defined(RTE_TOOLCHAIN_CLANG)
495bf7ded9aSMorten Brørup #define __rte_assume(condition) __extension__(__builtin_assume(condition))
496bf7ded9aSMorten Brørup #else
497bf7ded9aSMorten Brørup #define __rte_assume(condition) __assume(condition)
498bf7ded9aSMorten Brørup #endif
499bf7ded9aSMorten Brørup 
500bf7ded9aSMorten Brørup /**
50148ff13efSDavid Marchand  * Disable AddressSanitizer on some code
50248ff13efSDavid Marchand  */
50348ff13efSDavid Marchand #ifdef RTE_MALLOC_ASAN
50448ff13efSDavid Marchand #ifdef RTE_CC_CLANG
50548ff13efSDavid Marchand #define __rte_no_asan __attribute__((no_sanitize("address", "hwaddress")))
50648ff13efSDavid Marchand #else
50748ff13efSDavid Marchand #define __rte_no_asan __attribute__((no_sanitize_address))
50848ff13efSDavid Marchand #endif
50948ff13efSDavid Marchand #else /* ! RTE_MALLOC_ASAN */
51048ff13efSDavid Marchand #define __rte_no_asan
51148ff13efSDavid Marchand #endif
51248ff13efSDavid Marchand 
51399a2dd95SBruce Richardson /*********** Macros for pointer arithmetic ********/
51499a2dd95SBruce Richardson 
51599a2dd95SBruce Richardson /**
51699a2dd95SBruce Richardson  * add a byte-value offset to a pointer
51799a2dd95SBruce Richardson  */
51899a2dd95SBruce Richardson #define RTE_PTR_ADD(ptr, x) ((void*)((uintptr_t)(ptr) + (x)))
51999a2dd95SBruce Richardson 
52099a2dd95SBruce Richardson /**
52199a2dd95SBruce Richardson  * subtract a byte-value offset from a pointer
52299a2dd95SBruce Richardson  */
5231a7374c9SDmitry Kozlyuk #define RTE_PTR_SUB(ptr, x) ((void *)((uintptr_t)(ptr) - (x)))
52499a2dd95SBruce Richardson 
52599a2dd95SBruce Richardson /**
52699a2dd95SBruce Richardson  * get the difference between two pointer values, i.e. how far apart
52799a2dd95SBruce Richardson  * in bytes are the locations they point two. It is assumed that
52899a2dd95SBruce Richardson  * ptr1 is greater than ptr2.
52999a2dd95SBruce Richardson  */
53099a2dd95SBruce Richardson #define RTE_PTR_DIFF(ptr1, ptr2) ((uintptr_t)(ptr1) - (uintptr_t)(ptr2))
53199a2dd95SBruce Richardson 
532*a1b873f1SAndre Muezerie /*********** Macros for casting pointers ********/
533*a1b873f1SAndre Muezerie 
534*a1b873f1SAndre Muezerie /**
535*a1b873f1SAndre Muezerie  * Macro to discard qualifiers (such as const, volatile, restrict) from a pointer,
536*a1b873f1SAndre Muezerie  * without the compiler emitting a warning.
537*a1b873f1SAndre Muezerie  */
538*a1b873f1SAndre Muezerie #define RTE_PTR_UNQUAL(X) ((void *)(uintptr_t)(X))
539*a1b873f1SAndre Muezerie 
540*a1b873f1SAndre Muezerie /**
541*a1b873f1SAndre Muezerie  * Macro to cast a pointer to a specific type,
542*a1b873f1SAndre Muezerie  * without the compiler emitting a warning about discarding qualifiers.
543*a1b873f1SAndre Muezerie  *
544*a1b873f1SAndre Muezerie  * @warning
545*a1b873f1SAndre Muezerie  * When casting a pointer to point to a larger type, the resulting pointer may
546*a1b873f1SAndre Muezerie  * be misaligned, which results in undefined behavior.
547*a1b873f1SAndre Muezerie  * E.g.:
548*a1b873f1SAndre Muezerie  *
549*a1b873f1SAndre Muezerie  * struct s {
550*a1b873f1SAndre Muezerie  *       uint16_t a;
551*a1b873f1SAndre Muezerie  *       uint8_t  b;
552*a1b873f1SAndre Muezerie  *       uint8_t  c;
553*a1b873f1SAndre Muezerie  *       uint8_t  d;
554*a1b873f1SAndre Muezerie  *   } v;
555*a1b873f1SAndre Muezerie  *   uint16_t * p = RTE_CAST_PTR(uint16_t *, &v.c); // "p" is not 16 bit aligned!
556*a1b873f1SAndre Muezerie  */
557*a1b873f1SAndre Muezerie #define RTE_CAST_PTR(type, ptr) ((type)(uintptr_t)(ptr))
558*a1b873f1SAndre Muezerie 
55999a2dd95SBruce Richardson /**
56099a2dd95SBruce Richardson  * Workaround to cast a const field of a structure to non-const type.
56199a2dd95SBruce Richardson  */
56299a2dd95SBruce Richardson #define RTE_CAST_FIELD(var, field, type) \
56399a2dd95SBruce Richardson 	(*(type *)((uintptr_t)(var) + offsetof(typeof(*(var)), field)))
56499a2dd95SBruce Richardson 
56599a2dd95SBruce Richardson /*********** Macros/static functions for doing alignment ********/
56699a2dd95SBruce Richardson 
56799a2dd95SBruce Richardson 
56899a2dd95SBruce Richardson /**
56999a2dd95SBruce Richardson  * Macro to align a pointer to a given power-of-two. The resultant
57099a2dd95SBruce Richardson  * pointer will be a pointer of the same type as the first parameter, and
57199a2dd95SBruce Richardson  * point to an address no higher than the first parameter. Second parameter
57299a2dd95SBruce Richardson  * must be a power-of-two value.
57399a2dd95SBruce Richardson  */
57499a2dd95SBruce Richardson #define RTE_PTR_ALIGN_FLOOR(ptr, align) \
5751a7374c9SDmitry Kozlyuk 	((typeof(ptr))RTE_ALIGN_FLOOR((uintptr_t)(ptr), align))
57699a2dd95SBruce Richardson 
57799a2dd95SBruce Richardson /**
57899a2dd95SBruce Richardson  * Macro to align a value to a given power-of-two. The resultant value
57999a2dd95SBruce Richardson  * will be of the same type as the first parameter, and will be no
58099a2dd95SBruce Richardson  * bigger than the first parameter. Second parameter must be a
58199a2dd95SBruce Richardson  * power-of-two value.
58299a2dd95SBruce Richardson  */
58399a2dd95SBruce Richardson #define RTE_ALIGN_FLOOR(val, align) \
58499a2dd95SBruce Richardson 	(typeof(val))((val) & (~((typeof(val))((align) - 1))))
58599a2dd95SBruce Richardson 
58699a2dd95SBruce Richardson /**
58799a2dd95SBruce Richardson  * Macro to align a pointer to a given power-of-two. The resultant
58899a2dd95SBruce Richardson  * pointer will be a pointer of the same type as the first parameter, and
58999a2dd95SBruce Richardson  * point to an address no lower than the first parameter. Second parameter
59099a2dd95SBruce Richardson  * must be a power-of-two value.
59199a2dd95SBruce Richardson  */
59299a2dd95SBruce Richardson #define RTE_PTR_ALIGN_CEIL(ptr, align) \
59399a2dd95SBruce Richardson 	RTE_PTR_ALIGN_FLOOR((typeof(ptr))RTE_PTR_ADD(ptr, (align) - 1), align)
59499a2dd95SBruce Richardson 
59599a2dd95SBruce Richardson /**
59699a2dd95SBruce Richardson  * Macro to align a value to a given power-of-two. The resultant value
59799a2dd95SBruce Richardson  * will be of the same type as the first parameter, and will be no lower
59899a2dd95SBruce Richardson  * than the first parameter. Second parameter must be a power-of-two
59999a2dd95SBruce Richardson  * value.
60099a2dd95SBruce Richardson  */
60199a2dd95SBruce Richardson #define RTE_ALIGN_CEIL(val, align) \
60299a2dd95SBruce Richardson 	RTE_ALIGN_FLOOR(((val) + ((typeof(val)) (align) - 1)), align)
60399a2dd95SBruce Richardson 
60499a2dd95SBruce Richardson /**
60599a2dd95SBruce Richardson  * Macro to align a pointer to a given power-of-two. The resultant
60699a2dd95SBruce Richardson  * pointer will be a pointer of the same type as the first parameter, and
60799a2dd95SBruce Richardson  * point to an address no lower than the first parameter. Second parameter
60899a2dd95SBruce Richardson  * must be a power-of-two value.
60999a2dd95SBruce Richardson  * This function is the same as RTE_PTR_ALIGN_CEIL
61099a2dd95SBruce Richardson  */
61199a2dd95SBruce Richardson #define RTE_PTR_ALIGN(ptr, align) RTE_PTR_ALIGN_CEIL(ptr, align)
61299a2dd95SBruce Richardson 
61399a2dd95SBruce Richardson /**
61499a2dd95SBruce Richardson  * Macro to align a value to a given power-of-two. The resultant
61599a2dd95SBruce Richardson  * value will be of the same type as the first parameter, and
61699a2dd95SBruce Richardson  * will be no lower than the first parameter. Second parameter
61799a2dd95SBruce Richardson  * must be a power-of-two value.
61899a2dd95SBruce Richardson  * This function is the same as RTE_ALIGN_CEIL
61999a2dd95SBruce Richardson  */
62099a2dd95SBruce Richardson #define RTE_ALIGN(val, align) RTE_ALIGN_CEIL(val, align)
62199a2dd95SBruce Richardson 
62299a2dd95SBruce Richardson /**
62399a2dd95SBruce Richardson  * Macro to align a value to the multiple of given value. The resultant
62499a2dd95SBruce Richardson  * value will be of the same type as the first parameter and will be no lower
62599a2dd95SBruce Richardson  * than the first parameter.
62699a2dd95SBruce Richardson  */
62799a2dd95SBruce Richardson #define RTE_ALIGN_MUL_CEIL(v, mul) \
62899a2dd95SBruce Richardson 	((((v) + (typeof(v))(mul) - 1) / ((typeof(v))(mul))) * (typeof(v))(mul))
62999a2dd95SBruce Richardson 
63099a2dd95SBruce Richardson /**
63199a2dd95SBruce Richardson  * Macro to align a value to the multiple of given value. The resultant
63299a2dd95SBruce Richardson  * value will be of the same type as the first parameter and will be no higher
63399a2dd95SBruce Richardson  * than the first parameter.
63499a2dd95SBruce Richardson  */
63599a2dd95SBruce Richardson #define RTE_ALIGN_MUL_FLOOR(v, mul) \
63699a2dd95SBruce Richardson 	(((v) / ((typeof(v))(mul))) * (typeof(v))(mul))
63799a2dd95SBruce Richardson 
63899a2dd95SBruce Richardson /**
63999a2dd95SBruce Richardson  * Macro to align value to the nearest multiple of the given value.
64099a2dd95SBruce Richardson  * The resultant value might be greater than or less than the first parameter
64199a2dd95SBruce Richardson  * whichever difference is the lowest.
64299a2dd95SBruce Richardson  */
64399a2dd95SBruce Richardson #define RTE_ALIGN_MUL_NEAR(v, mul)				\
644a24456c2STyler Retzlaff 	__extension__ ({					\
64599a2dd95SBruce Richardson 		typeof(v) ceil = RTE_ALIGN_MUL_CEIL(v, mul);	\
64699a2dd95SBruce Richardson 		typeof(v) floor = RTE_ALIGN_MUL_FLOOR(v, mul);	\
64799a2dd95SBruce Richardson 		(ceil - (v)) > ((v) - floor) ? floor : ceil;	\
64899a2dd95SBruce Richardson 	})
64999a2dd95SBruce Richardson 
65099a2dd95SBruce Richardson /**
65199a2dd95SBruce Richardson  * Checks if a pointer is aligned to a given power-of-two value
65299a2dd95SBruce Richardson  *
65399a2dd95SBruce Richardson  * @param ptr
65499a2dd95SBruce Richardson  *   The pointer whose alignment is to be checked
65599a2dd95SBruce Richardson  * @param align
65699a2dd95SBruce Richardson  *   The power-of-two value to which the ptr should be aligned
65799a2dd95SBruce Richardson  *
65899a2dd95SBruce Richardson  * @return
65999a2dd95SBruce Richardson  *   True(1) where the pointer is correctly aligned, false(0) otherwise
66099a2dd95SBruce Richardson  */
66199a2dd95SBruce Richardson static inline int
662f398ebd7SMorten Brørup rte_is_aligned(const void * const __rte_restrict ptr, const unsigned int align)
66399a2dd95SBruce Richardson {
664f398ebd7SMorten Brørup 	return ((uintptr_t)ptr & (align - 1)) == 0;
66599a2dd95SBruce Richardson }
66699a2dd95SBruce Richardson 
66799a2dd95SBruce Richardson /*********** Macros for compile type checks ********/
66899a2dd95SBruce Richardson 
669537caad2SStephen Hemminger /* Workaround for toolchain issues with missing C11 macro in FreeBSD */
670537caad2SStephen Hemminger #if !defined(static_assert) && !defined(__cplusplus)
671537caad2SStephen Hemminger #define	static_assert	_Static_assert
672537caad2SStephen Hemminger #endif
673537caad2SStephen Hemminger 
67499a2dd95SBruce Richardson /**
67599a2dd95SBruce Richardson  * Triggers an error at compilation time if the condition is true.
676537caad2SStephen Hemminger  *
677537caad2SStephen Hemminger  * The do { } while(0) exists to workaround a bug in clang (#55821)
678537caad2SStephen Hemminger  * where it would not handle _Static_assert in a switch case.
67999a2dd95SBruce Richardson  */
680537caad2SStephen Hemminger #define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0)
68199a2dd95SBruce Richardson 
68299a2dd95SBruce Richardson /*********** Cache line related macros ********/
68399a2dd95SBruce Richardson 
68499a2dd95SBruce Richardson /** Cache line mask. */
68599a2dd95SBruce Richardson #define RTE_CACHE_LINE_MASK (RTE_CACHE_LINE_SIZE-1)
68699a2dd95SBruce Richardson 
68799a2dd95SBruce Richardson /** Return the first cache-aligned value greater or equal to size. */
688107dc066SDmitry Kozlyuk #define RTE_CACHE_LINE_ROUNDUP(size) RTE_ALIGN_CEIL(size, RTE_CACHE_LINE_SIZE)
68999a2dd95SBruce Richardson 
69099a2dd95SBruce Richardson /** Cache line size in terms of log2 */
69199a2dd95SBruce Richardson #if RTE_CACHE_LINE_SIZE == 64
69299a2dd95SBruce Richardson #define RTE_CACHE_LINE_SIZE_LOG2 6
69399a2dd95SBruce Richardson #elif RTE_CACHE_LINE_SIZE == 128
69499a2dd95SBruce Richardson #define RTE_CACHE_LINE_SIZE_LOG2 7
69599a2dd95SBruce Richardson #else
69699a2dd95SBruce Richardson #error "Unsupported cache line size"
69799a2dd95SBruce Richardson #endif
69899a2dd95SBruce Richardson 
69999a2dd95SBruce Richardson /** Minimum Cache line size. */
70099a2dd95SBruce Richardson #define RTE_CACHE_LINE_MIN_SIZE 64
70199a2dd95SBruce Richardson 
70299a2dd95SBruce Richardson /** Force alignment to cache line. */
70399a2dd95SBruce Richardson #define __rte_cache_aligned __rte_aligned(RTE_CACHE_LINE_SIZE)
70499a2dd95SBruce Richardson 
70599a2dd95SBruce Richardson /** Force minimum cache line alignment. */
70699a2dd95SBruce Richardson #define __rte_cache_min_aligned __rte_aligned(RTE_CACHE_LINE_MIN_SIZE)
70799a2dd95SBruce Richardson 
70865f600c0SMorten Brørup #define _RTE_CACHE_GUARD_HELPER2(unique) \
709e9fd1ebfSTyler Retzlaff 	alignas(RTE_CACHE_LINE_SIZE) \
710e9fd1ebfSTyler Retzlaff 	char cache_guard_ ## unique[RTE_CACHE_LINE_SIZE * RTE_CACHE_GUARD_LINES]
71165f600c0SMorten Brørup #define _RTE_CACHE_GUARD_HELPER1(unique) _RTE_CACHE_GUARD_HELPER2(unique)
71265f600c0SMorten Brørup /**
71365f600c0SMorten Brørup  * Empty cache lines, to guard against false sharing-like effects
71465f600c0SMorten Brørup  * on systems with a next-N-lines hardware prefetcher.
71565f600c0SMorten Brørup  *
71665f600c0SMorten Brørup  * Use as spacing between data accessed by different lcores,
71765f600c0SMorten Brørup  * to prevent cache thrashing on hardware with speculative prefetching.
71865f600c0SMorten Brørup  */
71965f600c0SMorten Brørup #define RTE_CACHE_GUARD _RTE_CACHE_GUARD_HELPER1(__COUNTER__)
72065f600c0SMorten Brørup 
72199a2dd95SBruce Richardson /*********** PA/IOVA type definitions ********/
72299a2dd95SBruce Richardson 
72399a2dd95SBruce Richardson /** Physical address */
72499a2dd95SBruce Richardson typedef uint64_t phys_addr_t;
72599a2dd95SBruce Richardson #define RTE_BAD_PHYS_ADDR ((phys_addr_t)-1)
72699a2dd95SBruce Richardson 
72799a2dd95SBruce Richardson /**
72899a2dd95SBruce Richardson  * IO virtual address type.
72999a2dd95SBruce Richardson  * When the physical addressing mode (IOVA as PA) is in use,
73099a2dd95SBruce Richardson  * the translation from an IO virtual address (IOVA) to a physical address
73199a2dd95SBruce Richardson  * is a direct mapping, i.e. the same value.
73299a2dd95SBruce Richardson  * Otherwise, in virtual mode (IOVA as VA), an IOMMU may do the translation.
73399a2dd95SBruce Richardson  */
73499a2dd95SBruce Richardson typedef uint64_t rte_iova_t;
73599a2dd95SBruce Richardson #define RTE_BAD_IOVA ((rte_iova_t)-1)
73699a2dd95SBruce Richardson 
73799a2dd95SBruce Richardson /*********** Structure alignment markers ********/
73899a2dd95SBruce Richardson 
739fc9fa366STyler Retzlaff #ifndef RTE_TOOLCHAIN_MSVC
740fc9fa366STyler Retzlaff 
74199a2dd95SBruce Richardson /** Generic marker for any place in a structure. */
74299a2dd95SBruce Richardson __extension__ typedef void    *RTE_MARKER[0];
74399a2dd95SBruce Richardson /** Marker for 1B alignment in a structure. */
74499a2dd95SBruce Richardson __extension__ typedef uint8_t  RTE_MARKER8[0];
74599a2dd95SBruce Richardson /** Marker for 2B alignment in a structure. */
74699a2dd95SBruce Richardson __extension__ typedef uint16_t RTE_MARKER16[0];
74799a2dd95SBruce Richardson /** Marker for 4B alignment in a structure. */
74899a2dd95SBruce Richardson __extension__ typedef uint32_t RTE_MARKER32[0];
74999a2dd95SBruce Richardson /** Marker for 8B alignment in a structure. */
75099a2dd95SBruce Richardson __extension__ typedef uint64_t RTE_MARKER64[0];
75199a2dd95SBruce Richardson 
752fc9fa366STyler Retzlaff #endif
753fc9fa366STyler Retzlaff 
75499a2dd95SBruce Richardson /*********** Macros for calculating min and max **********/
75599a2dd95SBruce Richardson 
75699a2dd95SBruce Richardson /**
75799a2dd95SBruce Richardson  * Macro to return the minimum of two numbers
75899a2dd95SBruce Richardson  */
75999a2dd95SBruce Richardson #define RTE_MIN(a, b) \
76099a2dd95SBruce Richardson 	__extension__ ({ \
76199a2dd95SBruce Richardson 		typeof (a) _a = (a); \
76299a2dd95SBruce Richardson 		typeof (b) _b = (b); \
76399a2dd95SBruce Richardson 		_a < _b ? _a : _b; \
76499a2dd95SBruce Richardson 	})
76599a2dd95SBruce Richardson 
76699a2dd95SBruce Richardson /**
767ac718edaSStephen Hemminger  * Macro to return the minimum of two numbers
768ac718edaSStephen Hemminger  *
769ac718edaSStephen Hemminger  * As opposed to RTE_MIN, it does not use temporary variables so it is not safe
770ac718edaSStephen Hemminger  * if a or b is an expression. Yet it is guaranteed to be constant for use in
771ac718edaSStephen Hemminger  * static_assert().
772ac718edaSStephen Hemminger  */
773ac718edaSStephen Hemminger #define RTE_MIN_T(a, b, t) \
774ac718edaSStephen Hemminger 	((t)(a) < (t)(b) ? (t)(a) : (t)(b))
775ac718edaSStephen Hemminger 
776ac718edaSStephen Hemminger /**
77799a2dd95SBruce Richardson  * Macro to return the maximum of two numbers
77899a2dd95SBruce Richardson  */
77999a2dd95SBruce Richardson #define RTE_MAX(a, b) \
78099a2dd95SBruce Richardson 	__extension__ ({ \
78199a2dd95SBruce Richardson 		typeof (a) _a = (a); \
78299a2dd95SBruce Richardson 		typeof (b) _b = (b); \
78399a2dd95SBruce Richardson 		_a > _b ? _a : _b; \
78499a2dd95SBruce Richardson 	})
78599a2dd95SBruce Richardson 
786ac718edaSStephen Hemminger /**
787ac718edaSStephen Hemminger  * Macro to return the maximum of two numbers
788ac718edaSStephen Hemminger  *
789ac718edaSStephen Hemminger  * As opposed to RTE_MAX, it does not use temporary variables so it is not safe
790ac718edaSStephen Hemminger  * if a or b is an expression. Yet it is guaranteed to be constant for use in
791ac718edaSStephen Hemminger  * static_assert().
792ac718edaSStephen Hemminger  */
793ac718edaSStephen Hemminger #define RTE_MAX_T(a, b, t) \
794ac718edaSStephen Hemminger 	((t)(a) > (t)(b) ? (t)(a) : (t)(b))
795ac718edaSStephen Hemminger 
79699a2dd95SBruce Richardson /*********** Other general functions / macros ********/
79799a2dd95SBruce Richardson 
79899a2dd95SBruce Richardson #ifndef offsetof
79999a2dd95SBruce Richardson /** Return the offset of a field in a structure. */
80099a2dd95SBruce Richardson #define offsetof(TYPE, MEMBER)  __builtin_offsetof (TYPE, MEMBER)
80199a2dd95SBruce Richardson #endif
80299a2dd95SBruce Richardson 
80399a2dd95SBruce Richardson /**
80499a2dd95SBruce Richardson  * Return pointer to the wrapping struct instance.
80599a2dd95SBruce Richardson  *
80699a2dd95SBruce Richardson  * Example:
80799a2dd95SBruce Richardson  *
80899a2dd95SBruce Richardson  *  struct wrapper {
80999a2dd95SBruce Richardson  *      ...
81099a2dd95SBruce Richardson  *      struct child c;
81199a2dd95SBruce Richardson  *      ...
81299a2dd95SBruce Richardson  *  };
81399a2dd95SBruce Richardson  *
81499a2dd95SBruce Richardson  *  struct child *x = obtain(...);
81599a2dd95SBruce Richardson  *  struct wrapper *w = container_of(x, struct wrapper, c);
81699a2dd95SBruce Richardson  */
81799a2dd95SBruce Richardson #ifndef container_of
81851574a4fSTyler Retzlaff #ifdef RTE_TOOLCHAIN_MSVC
81951574a4fSTyler Retzlaff #define container_of(ptr, type, member) \
82051574a4fSTyler Retzlaff 			((type *)((uintptr_t)(ptr) - offsetof(type, member)))
82151574a4fSTyler Retzlaff #else
82299a2dd95SBruce Richardson #define container_of(ptr, type, member)	__extension__ ({		\
82399a2dd95SBruce Richardson 			const typeof(((type *)0)->member) *_ptr = (ptr); \
82499a2dd95SBruce Richardson 			__rte_unused type *_target_ptr =	\
82599a2dd95SBruce Richardson 				(type *)(ptr);				\
82699a2dd95SBruce Richardson 			(type *)(((uintptr_t)_ptr) - offsetof(type, member)); \
82799a2dd95SBruce Richardson 		})
82899a2dd95SBruce Richardson #endif
82951574a4fSTyler Retzlaff #endif
83099a2dd95SBruce Richardson 
831a0a388a8SShijith Thotton /** Swap two variables. */
832a0a388a8SShijith Thotton #define RTE_SWAP(a, b) \
833a0a388a8SShijith Thotton 	__extension__ ({ \
834a0a388a8SShijith Thotton 		typeof (a) _a = a; \
835a0a388a8SShijith Thotton 		a = b; \
836a0a388a8SShijith Thotton 		b = _a; \
837a0a388a8SShijith Thotton 	})
838a0a388a8SShijith Thotton 
83999a2dd95SBruce Richardson /**
84099a2dd95SBruce Richardson  * Get the size of a field in a structure.
84199a2dd95SBruce Richardson  *
84299a2dd95SBruce Richardson  * @param type
84399a2dd95SBruce Richardson  *   The type of the structure.
84499a2dd95SBruce Richardson  * @param field
84599a2dd95SBruce Richardson  *   The field in the structure.
84699a2dd95SBruce Richardson  * @return
84799a2dd95SBruce Richardson  *   The size of the field in the structure, in bytes.
84899a2dd95SBruce Richardson  */
84999a2dd95SBruce Richardson #define RTE_SIZEOF_FIELD(type, field) (sizeof(((type *)0)->field))
85099a2dd95SBruce Richardson 
85199a2dd95SBruce Richardson #define _RTE_STR(x) #x
85299a2dd95SBruce Richardson /** Take a macro value and get a string version of it */
85399a2dd95SBruce Richardson #define RTE_STR(x) _RTE_STR(x)
85499a2dd95SBruce Richardson 
85599a2dd95SBruce Richardson /**
85699a2dd95SBruce Richardson  * ISO C helpers to modify format strings using variadic macros.
85799a2dd95SBruce Richardson  * This is a replacement for the ", ## __VA_ARGS__" GNU extension.
85899a2dd95SBruce Richardson  * An empty %s argument is appended to avoid a dangling comma.
85999a2dd95SBruce Richardson  */
86099a2dd95SBruce Richardson #define RTE_FMT(fmt, ...) fmt "%.0s", __VA_ARGS__ ""
86199a2dd95SBruce Richardson #define RTE_FMT_HEAD(fmt, ...) fmt
86299a2dd95SBruce Richardson #define RTE_FMT_TAIL(fmt, ...) __VA_ARGS__
86399a2dd95SBruce Richardson 
86499a2dd95SBruce Richardson /** Mask value of type "tp" for the first "ln" bit set. */
86599a2dd95SBruce Richardson #define	RTE_LEN2MASK(ln, tp)	\
86699a2dd95SBruce Richardson 	((tp)((uint64_t)-1 >> (sizeof(uint64_t) * CHAR_BIT - (ln))))
86799a2dd95SBruce Richardson 
86899a2dd95SBruce Richardson /** Number of elements in the array. */
86999a2dd95SBruce Richardson #define	RTE_DIM(a)	(sizeof (a) / sizeof ((a)[0]))
87099a2dd95SBruce Richardson 
87199a2dd95SBruce Richardson /**
87299a2dd95SBruce Richardson  * Converts a numeric string to the equivalent uint64_t value.
87399a2dd95SBruce Richardson  * As well as straight number conversion, also recognises the suffixes
87499a2dd95SBruce Richardson  * k, m and g for kilobytes, megabytes and gigabytes respectively.
87599a2dd95SBruce Richardson  *
87699a2dd95SBruce Richardson  * If a negative number is passed in  i.e. a string with the first non-black
87799a2dd95SBruce Richardson  * character being "-", zero is returned. Zero is also returned in the case of
87899a2dd95SBruce Richardson  * an error with the strtoull call in the function.
87999a2dd95SBruce Richardson  *
88099a2dd95SBruce Richardson  * @param str
88199a2dd95SBruce Richardson  *     String containing number to convert.
88299a2dd95SBruce Richardson  * @return
88399a2dd95SBruce Richardson  *     Number.
88499a2dd95SBruce Richardson  */
885347623c9SDmitry Kozlyuk uint64_t
886347623c9SDmitry Kozlyuk rte_str_to_size(const char *str);
88799a2dd95SBruce Richardson 
88899a2dd95SBruce Richardson /**
88999a2dd95SBruce Richardson  * Function to terminate the application immediately, printing an error
89099a2dd95SBruce Richardson  * message and returning the exit_code back to the shell.
89199a2dd95SBruce Richardson  *
89299a2dd95SBruce Richardson  * This function never returns
89399a2dd95SBruce Richardson  *
89499a2dd95SBruce Richardson  * @param exit_code
89599a2dd95SBruce Richardson  *     The exit code to be returned by the application
89699a2dd95SBruce Richardson  * @param format
89799a2dd95SBruce Richardson  *     The format string to be used for printing the message. This can include
89899a2dd95SBruce Richardson  *     printf format characters which will be expanded using any further parameters
89999a2dd95SBruce Richardson  *     to the function.
90099a2dd95SBruce Richardson  */
90199a2dd95SBruce Richardson __rte_noreturn void
90299a2dd95SBruce Richardson rte_exit(int exit_code, const char *format, ...)
90399a2dd95SBruce Richardson 	__rte_format_printf(2, 3);
90499a2dd95SBruce Richardson 
90599a2dd95SBruce Richardson #ifdef __cplusplus
90699a2dd95SBruce Richardson }
90799a2dd95SBruce Richardson #endif
90899a2dd95SBruce Richardson 
90999a2dd95SBruce Richardson #endif
910