X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Finclude%2Frte_common.h;h=c3528380731052de81289c78a6cc4b08c35e4e20;hb=30a0df64aaed5cbf33fd5d237d5812cee1cc0ef9;hp=87f0f6302e0cc742d18aae94af4dce55391ff131;hpb=3a6f2c50b9dc27a958af87d7ca9533b51a36477b;p=dpdk.git diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h index 87f0f6302e..c352838073 100644 --- a/lib/librte_eal/common/include/rte_common.h +++ b/lib/librte_eal/common/include/rte_common.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation + * Copyright(c) 2010-2019 Intel Corporation */ #ifndef _RTE_COMMON_H_ @@ -24,6 +24,9 @@ extern "C" { #include +/* OS specific include */ +#include + #ifndef typeof #define typeof __typeof__ #endif @@ -103,8 +106,10 @@ typedef uint16_t unaligned_uint16_t; * Priority number must be above 100. * Lowest number is the first to run. */ +#ifndef RTE_INIT_PRIO /* Allow to override from EAL */ #define RTE_INIT_PRIO(func, prio) \ static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void) +#endif /** * Run function before main() with low priority. @@ -126,8 +131,10 @@ static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void) * Priority number must be above 100. * Lowest number is the last to run. */ +#ifndef RTE_FINI_PRIO /* Allow to override from EAL */ #define RTE_FINI_PRIO(func, prio) \ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) +#endif /** * Run after main() with high priority. @@ -248,6 +255,18 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) #define RTE_ALIGN_MUL_FLOOR(v, mul) \ ((v / ((typeof(v))(mul))) * (typeof(v))(mul)) +/** + * Macro to align value to the nearest multiple of the given value. + * The resultant value might be greater than or less than the first parameter + * whichever difference is the lowest. + */ +#define RTE_ALIGN_MUL_NEAR(v, mul) \ + ({ \ + typeof(v) ceil = RTE_ALIGN_MUL_CEIL(v, mul); \ + typeof(v) floor = RTE_ALIGN_MUL_FLOOR(v, mul); \ + (ceil - v) > (v - floor) ? floor : ceil; \ + }) + /** * Checks if a pointer is aligned to a given power-of-two value * @@ -270,17 +289,53 @@ rte_is_aligned(void *ptr, unsigned align) /** * Triggers an error at compilation time if the condition is true. */ -#ifndef __OPTIMIZE__ #define RTE_BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) + +/*********** Cache line related macros ********/ + +/** Cache line mask. */ +#define RTE_CACHE_LINE_MASK (RTE_CACHE_LINE_SIZE-1) + +/** Return the first cache-aligned value greater or equal to size. */ +#define RTE_CACHE_LINE_ROUNDUP(size) \ + (RTE_CACHE_LINE_SIZE * ((size + RTE_CACHE_LINE_SIZE - 1) / \ + RTE_CACHE_LINE_SIZE)) + +/** Cache line size in terms of log2 */ +#if RTE_CACHE_LINE_SIZE == 64 +#define RTE_CACHE_LINE_SIZE_LOG2 6 +#elif RTE_CACHE_LINE_SIZE == 128 +#define RTE_CACHE_LINE_SIZE_LOG2 7 #else -extern int RTE_BUILD_BUG_ON_detected_error; -#define RTE_BUILD_BUG_ON(condition) do { \ - ((void)sizeof(char[1 - 2*!!(condition)])); \ - if (condition) \ - RTE_BUILD_BUG_ON_detected_error = 1; \ -} while(0) +#error "Unsupported cache line size" #endif +/** Minimum Cache line size. */ +#define RTE_CACHE_LINE_MIN_SIZE 64 + +/** Force alignment to cache line. */ +#define __rte_cache_aligned __rte_aligned(RTE_CACHE_LINE_SIZE) + +/** Force minimum cache line alignment. */ +#define __rte_cache_min_aligned __rte_aligned(RTE_CACHE_LINE_MIN_SIZE) + +/*********** PA/IOVA type definitions ********/ + +/** Physical address */ +typedef uint64_t phys_addr_t; +#define RTE_BAD_PHYS_ADDR ((phys_addr_t)-1) + +/** + * IO virtual address type. + * When the physical addressing mode (IOVA as PA) is in use, + * the translation from an IO virtual address (IOVA) to a physical address + * is a direct mapping, i.e. the same value. + * Otherwise, in virtual mode (IOVA as VA), an IOMMU may do the translation. + */ +typedef uint64_t rte_iova_t; +#define RTE_BAD_IOVA ((rte_iova_t)-1) + + /** * Combines 32b inputs most significant set bits into the least * significant bits to construct a value with the same MSBs as x @@ -349,7 +404,7 @@ rte_is_power_of_2(uint32_t n) * Aligns input parameter to the next power of 2 * * @param x - * The integer value to algin + * The integer value to align * * @return * Input parameter aligned to the next power of 2 @@ -367,7 +422,7 @@ rte_align32pow2(uint32_t x) * Aligns input parameter to the previous power of 2 * * @param x - * The integer value to algin + * The integer value to align * * @return * Input parameter aligned to the previous power of 2 @@ -456,9 +511,36 @@ rte_bsf32(uint32_t v) return (uint32_t)__builtin_ctz(v); } +/** + * Searches the input parameter for the least significant set bit + * (starting from zero). Safe version (checks for input parameter being zero). + * + * @warning ``pos`` must be a valid pointer. It is not checked! + * + * @param v + * The input parameter. + * @param pos + * If ``v`` was not 0, this value will contain position of least significant + * bit within the input parameter. + * @return + * Returns 0 if ``v`` was 0, otherwise returns 1. + */ +static inline int +rte_bsf32_safe(uint64_t v, uint32_t *pos) +{ + if (v == 0) + return 0; + + *pos = rte_bsf32(v); + return 1; +} + /** * Return the rounded-up log2 of a integer. * + * @note Contrary to the logarithm mathematical operation, + * rte_log2_u32(0) == 0 and not -inf. + * * @param v * The input parameter. * @return @@ -491,6 +573,85 @@ rte_fls_u32(uint32_t x) return (x == 0) ? 0 : 32 - __builtin_clz(x); } +/** + * Searches the input parameter for the least significant set bit + * (starting from zero). + * If a least significant 1 bit is found, its bit index is returned. + * If the content of the input parameter is zero, then the content of the return + * value is undefined. + * @param v + * input parameter, should not be zero. + * @return + * least significant set bit in the input parameter. + */ +static inline int +rte_bsf64(uint64_t v) +{ + return (uint32_t)__builtin_ctzll(v); +} + +/** + * Searches the input parameter for the least significant set bit + * (starting from zero). Safe version (checks for input parameter being zero). + * + * @warning ``pos`` must be a valid pointer. It is not checked! + * + * @param v + * The input parameter. + * @param pos + * If ``v`` was not 0, this value will contain position of least significant + * bit within the input parameter. + * @return + * Returns 0 if ``v`` was 0, otherwise returns 1. + */ +static inline int +rte_bsf64_safe(uint64_t v, uint32_t *pos) +{ + if (v == 0) + return 0; + + *pos = rte_bsf64(v); + return 1; +} + +/** + * Return the last (most-significant) bit set. + * + * @note The last (most significant) bit is at position 64. + * @note rte_fls_u64(0) = 0, rte_fls_u64(1) = 1, + * rte_fls_u64(0x8000000000000000) = 64 + * + * @param x + * The input parameter. + * @return + * The last (most-significant) bit set, or 0 if the input is 0. + */ +static inline int +rte_fls_u64(uint64_t x) +{ + return (x == 0) ? 0 : 64 - __builtin_clzll(x); +} + +/** + * Return the rounded-up log2 of a 64-bit integer. + * + * @note Contrary to the logarithm mathematical operation, + * rte_log2_u64(0) == 0 and not -inf. + * + * @param v + * The input parameter. + * @return + * The rounded-up log2 of the input, or 0 if the input is 0. + */ +static inline uint32_t +rte_log2_u64(uint64_t v) +{ + if (v == 0) + return 0; + v = rte_align64pow2(v); + /* we checked for v being 0 already, so no undefined behavior */ + return rte_bsf64(v); +} #ifndef offsetof /** Return the offset of a field in a structure. */ @@ -520,6 +681,18 @@ rte_fls_u32(uint32_t x) }) #endif +/** + * Get the size of a field in a structure. + * + * @param type + * The type of the structure. + * @param field + * The field in the structure. + * @return + * The size of the field in the structure, in bytes. + */ +#define RTE_SIZEOF_FIELD(type, field) (sizeof(((type *)0)->field)) + #define _RTE_STR(x) #x /** Take a macro value and get a string version of it */ #define RTE_STR(x) _RTE_STR(x)