eal: add 64-bit bsf and 32-bit safe bsf functions
Add an rte_bsf64 function that follows the convention of existing rte_bsf32 function. Also, add missing implementation for safe version of rte_bsf32, and implement unit tests for all recently added bsf varieties. Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
This commit is contained in:
parent
cc7ddb00da
commit
4e261f5519
@ -649,19 +649,13 @@ calc_mem_size(uint32_t nb_mbufs, uint32_t mbuf_sz, size_t pgsz, size_t *out)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
bsf64(uint64_t v)
|
||||
{
|
||||
return (uint32_t)__builtin_ctzll(v);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
log2_u64(uint64_t v)
|
||||
{
|
||||
if (v == 0)
|
||||
return 0;
|
||||
v = rte_align64pow2(v);
|
||||
return bsf64(v);
|
||||
return rte_bsf64(v);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -115,7 +115,9 @@ API Changes
|
||||
=========================================================
|
||||
|
||||
* eal: Function ``rte_bsf64`` in ``rte_bitmap.h`` has been renamed to
|
||||
``rte_bsf64_safe`` and moved to ``rte_common.h``.
|
||||
``rte_bsf64_safe`` and moved to ``rte_common.h``. A new ``rte_bsf64`` function
|
||||
has been added in ``rte_common.h`` that follows convention set by existing
|
||||
``rte_bsf32`` function.
|
||||
|
||||
* eal: Segment fd API on Linux now sets error code to ``ENOTSUP`` in more cases
|
||||
where segment fd API is not expected to be supported:
|
||||
|
@ -447,6 +447,30 @@ 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.
|
||||
*
|
||||
@ -482,6 +506,23 @@ 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).
|
||||
@ -502,7 +543,7 @@ rte_bsf64_safe(uint64_t v, uint32_t *pos)
|
||||
if (v == 0)
|
||||
return 0;
|
||||
|
||||
*pos = __builtin_ctzll(v);
|
||||
*pos = rte_bsf64(v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -213,19 +213,13 @@ get_file_size(int fd)
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
bsf64(uint64_t v)
|
||||
{
|
||||
return (uint32_t)__builtin_ctzll(v);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
log2_u64(uint64_t v)
|
||||
{
|
||||
if (v == 0)
|
||||
return 0;
|
||||
v = rte_align64pow2(v);
|
||||
return bsf64(v);
|
||||
return rte_bsf64(v);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -50,12 +50,48 @@ test_macros(int __rte_unused unused_parm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_bsf(void)
|
||||
{
|
||||
uint32_t shift, pos;
|
||||
|
||||
/* safe versions should be able to handle 0 */
|
||||
if (rte_bsf32_safe(0, &pos) != 0)
|
||||
FAIL("rte_bsf32_safe");
|
||||
if (rte_bsf64_safe(0, &pos) != 0)
|
||||
FAIL("rte_bsf64_safe");
|
||||
|
||||
for (shift = 0; shift < 63; shift++) {
|
||||
uint32_t val32;
|
||||
uint64_t val64;
|
||||
|
||||
val64 = 1ULL << shift;
|
||||
if ((uint32_t)rte_bsf64(val64) != shift)
|
||||
FAIL("rte_bsf64");
|
||||
if (rte_bsf64_safe(val64, &pos) != 1)
|
||||
FAIL("rte_bsf64_safe");
|
||||
if (pos != shift)
|
||||
FAIL("rte_bsf64_safe");
|
||||
|
||||
if (shift > 31)
|
||||
continue;
|
||||
|
||||
val32 = 1U << shift;
|
||||
if ((uint32_t)rte_bsf32(val32) != shift)
|
||||
FAIL("rte_bsf32");
|
||||
if (rte_bsf32_safe(val32, &pos) != 1)
|
||||
FAIL("rte_bsf32_safe");
|
||||
if (pos != shift)
|
||||
FAIL("rte_bsf32_safe");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_misc(void)
|
||||
{
|
||||
char memdump[] = "memdump_test";
|
||||
if (rte_bsf32(129))
|
||||
FAIL("rte_bsf32");
|
||||
|
||||
rte_memdump(stdout, "test", memdump, sizeof(memdump));
|
||||
rte_hexdump(stdout, "test", memdump, sizeof(memdump));
|
||||
@ -226,6 +262,7 @@ test_common(void)
|
||||
ret |= test_align();
|
||||
ret |= test_macros(0);
|
||||
ret |= test_misc();
|
||||
ret |= test_bsf();
|
||||
ret |= test_log2();
|
||||
ret |= test_fls();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user