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