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
=========================================================
* 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:
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.
*
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).
if (v == 0)
return 0;
- *pos = __builtin_ctzll(v);
+ *pos = rte_bsf64(v);
return 1;
}
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
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));
ret |= test_align();
ret |= test_macros(0);
ret |= test_misc();
+ ret |= test_bsf();
ret |= test_log2();
ret |= test_fls();