* [PATCH 0/2] eal: provide leading and trailing zero bit count @ 2022-11-23 22:14 Tyler Retzlaff 2022-11-23 22:14 ` [PATCH 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff ` (7 more replies) 0 siblings, 8 replies; 81+ messages in thread From: Tyler Retzlaff @ 2022-11-23 22:14 UTC (permalink / raw) To: dev; +Cc: Tyler Retzlaff Provide leading and trailing zero bit count functions to abstract away compiler specific implementations. Include basic unit test for new leading/trailing zero bit count functions. Tyler Retzlaff (2): eal: provide leading and trailing zero bit count abstraction test/bitcount: add bitcount tests app/test/meson.build | 2 + app/test/test_bitcount.c | 92 +++++++++++++++ lib/eal/include/meson.build | 1 + lib/eal/include/rte_bitcount.h | 257 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 352 insertions(+) create mode 100644 app/test/test_bitcount.c create mode 100644 lib/eal/include/rte_bitcount.h -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH 1/2] eal: provide leading and trailing zero bit count abstraction 2022-11-23 22:14 [PATCH 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff @ 2022-11-23 22:14 ` Tyler Retzlaff 2023-04-03 21:46 ` Mattias Rönnblom 2022-11-23 22:14 ` [PATCH 2/2] test/bitcount: add bitcount tests Tyler Retzlaff ` (6 subsequent siblings) 7 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2022-11-23 22:14 UTC (permalink / raw) To: dev; +Cc: Tyler Retzlaff Provide an abstraction for leading and trailing zero bit counting functions to hide compiler specific intrinsics and builtins. Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- lib/eal/include/meson.build | 1 + lib/eal/include/rte_bitcount.h | 257 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 258 insertions(+) create mode 100644 lib/eal/include/rte_bitcount.h diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build index cfcd40a..8ff1d65 100644 --- a/lib/eal/include/meson.build +++ b/lib/eal/include/meson.build @@ -5,6 +5,7 @@ includes += include_directories('.') headers += files( 'rte_alarm.h', + 'rte_bitcount.h', 'rte_bitmap.h', 'rte_bitops.h', 'rte_branch_prediction.h', diff --git a/lib/eal/include/rte_bitcount.h b/lib/eal/include/rte_bitcount.h new file mode 100644 index 0000000..2f4dd38 --- /dev/null +++ b/lib/eal/include/rte_bitcount.h @@ -0,0 +1,257 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#ifndef EAL_BITCOUNT_H +#define EAL_BITCOUNT_H + +#include <rte_compat.h> + +#ifdef RTE_TOOLCHAIN_MSVC + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned +rte_clz(unsigned int v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned +rte_clzl(unsigned long v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned +rte_clzll(unsigned long long v) +{ + unsigned long rv; + + (void)_BitScanReverse64(&rv, v); + + return (unsigned)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned +rte_ctz(unsigned int v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned +rte_ctzl(unsigned long v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned +rte_ctzll(unsigned long long v) +{ + unsigned long rv; + + (void)_BitScanForward64(&rv, v); + + return (unsigned)rv; +} + +#else + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned +rte_clz(unsigned int v) +{ + return (unsigned)__builtin_clz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned +rte_clzl(unsigned long v) +{ + return (unsigned)__builtin_clzl(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned +rte_clzll(unsigned long v) +{ + return (unsigned)__builtin_clzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned +rte_ctz(unsigned int v) +{ + return (unsigned)__builtin_ctz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned +rte_ctzl(unsigned long v) +{ + return (unsigned)__builtin_ctzl(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned +rte_ctzll(unsigned long v) +{ + return (unsigned)__builtin_ctzll(v); +} + +#endif + +#endif /* EAL_BITCOUNT_H */ + -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH 1/2] eal: provide leading and trailing zero bit count abstraction 2022-11-23 22:14 ` [PATCH 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2023-04-03 21:46 ` Mattias Rönnblom 0 siblings, 0 replies; 81+ messages in thread From: Mattias Rönnblom @ 2023-04-03 21:46 UTC (permalink / raw) To: Tyler Retzlaff, dev On 2022-11-23 23:14, Tyler Retzlaff wrote: > Provide an abstraction for leading and trailing zero bit counting > functions to hide compiler specific intrinsics and builtins. > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > --- > lib/eal/include/meson.build | 1 + > lib/eal/include/rte_bitcount.h | 257 +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 258 insertions(+) > create mode 100644 lib/eal/include/rte_bitcount.h > > diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build > index cfcd40a..8ff1d65 100644 > --- a/lib/eal/include/meson.build > +++ b/lib/eal/include/meson.build > @@ -5,6 +5,7 @@ includes += include_directories('.') > > headers += files( > 'rte_alarm.h', > + 'rte_bitcount.h', Maybe rte_bitops.h should be the home of these new wrappers. > 'rte_bitmap.h', > 'rte_bitops.h', > 'rte_branch_prediction.h', > diff --git a/lib/eal/include/rte_bitcount.h b/lib/eal/include/rte_bitcount.h > new file mode 100644 > index 0000000..2f4dd38 > --- /dev/null > +++ b/lib/eal/include/rte_bitcount.h > @@ -0,0 +1,257 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright (C) 2022 Microsoft Corporation > + */ > + > +#ifndef EAL_BITCOUNT_H > +#define EAL_BITCOUNT_H > + > +#include <rte_compat.h> > + > +#ifdef RTE_TOOLCHAIN_MSVC > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned unsigned int If you want to be __builtin_clz()-compatible, you should stay with "int" as the return type. If you don't, you might want to change more than just the return type. In particular, it would be useful to have size-specific variants (although in practice they are on most [all?] DPDK-supported platforms). unsigned int rte_clz(uint32_t v); or rte_clz32(), to follow the naming convention from some other wrapper RFC you posted. > +rte_clz(unsigned int v) > +{ > + unsigned long rv; > + > + (void)_BitScanReverse(&rv, v); > + > + return (unsigned)rv; > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_clzl(unsigned long v) > +{ > + unsigned long rv; > + > + (void)_BitScanReverse(&rv, v); > + > + return (unsigned)rv; > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_clzll(unsigned long long v) > +{ > + unsigned long rv; > + > + (void)_BitScanReverse64(&rv, v); > + > + return (unsigned)rv; > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_ctz(unsigned int v) > +{ > + unsigned long rv; > + > + (void)_BitScanForward(&rv, v); > + > + return (unsigned)rv; > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_ctzl(unsigned long v) > +{ > + unsigned long rv; > + > + (void)_BitScanForward(&rv, v); > + > + return (unsigned)rv; > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_ctzll(unsigned long long v) > +{ > + unsigned long rv; > + > + (void)_BitScanForward64(&rv, v); > + > + return (unsigned)rv; > +} > + > +#else > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_clz(unsigned int v) > +{ > + return (unsigned)__builtin_clz(v); > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_clzl(unsigned long v) > +{ > + return (unsigned)__builtin_clzl(v); > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_clzll(unsigned long v) > +{ > + return (unsigned)__builtin_clzll(v); > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_ctz(unsigned int v) > +{ > + return (unsigned)__builtin_ctz(v); > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_ctzl(unsigned long v) > +{ > + return (unsigned)__builtin_ctzl(v); > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned > +rte_ctzll(unsigned long v) > +{ > + return (unsigned)__builtin_ctzll(v); > +} > + > +#endif > + > +#endif /* EAL_BITCOUNT_H */ > + ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH 2/2] test/bitcount: add bitcount tests 2022-11-23 22:14 [PATCH 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff 2022-11-23 22:14 ` [PATCH 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2022-11-23 22:14 ` Tyler Retzlaff 2022-11-23 23:43 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff ` (5 subsequent siblings) 7 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2022-11-23 22:14 UTC (permalink / raw) To: dev; +Cc: Tyler Retzlaff basic unit test of following functions rte_clz rte_clzl rte_clzll rte_ctz rte_ctzl rte_ctzll Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- app/test/meson.build | 2 ++ app/test/test_bitcount.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 app/test/test_bitcount.c diff --git a/app/test/meson.build b/app/test/meson.build index f34d19e..d1277bc 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -13,6 +13,7 @@ test_sources = files( 'test_alarm.c', 'test_atomic.c', 'test_barrier.c', + 'test_bitcount.c', 'test_bitops.c', 'test_bitmap.c', 'test_bpf.c', @@ -160,6 +161,7 @@ test_deps += ['bus_pci', 'bus_vdev'] fast_tests = [ ['acl_autotest', true, true], ['atomic_autotest', false, true], + ['bitcount_autotest', true, true], ['bitmap_autotest', true, true], ['bpf_autotest', true, true], ['bpf_convert_autotest', true, true], diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c new file mode 100644 index 0000000..7b71fdf --- /dev/null +++ b/app/test/test_bitcount.c @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#include <string.h> + +#include <rte_bitcount.h> +#include <rte_debug.h> + +#include "test.h" + +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); + +static int +test_clz(void) +{ + unsigned int v = 1; + RTE_TEST_ASSERT(rte_clz(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_clzl(void) +{ + unsigned long v = 1; + RTE_TEST_ASSERT(rte_clzl(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_clzll(void) +{ + unsigned long long v = 1; + RTE_TEST_ASSERT(rte_clzll(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_ctz(void) +{ + unsigned int v = 2; + RTE_TEST_ASSERT(rte_ctz(v) == 1, "Unexpected count."); + + return 0; +} + +static int +test_ctzl(void) +{ + unsigned long v = 2; + RTE_TEST_ASSERT(rte_ctzl(v) == 1, "Unexpected count."); + + return 0; +} + +static int +test_ctzll(void) +{ + unsigned long long v = 2; + RTE_TEST_ASSERT(rte_ctzll(v) == 1, "Unexpected count."); + + return 0; +} + +static struct unit_test_suite bitcount_test_suite = { + .suite_name = "bitcount autotest", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + TEST_CASE(test_clz), + TEST_CASE(test_clzl), + TEST_CASE(test_clzll), + TEST_CASE(test_ctz), + TEST_CASE(test_ctzl), + TEST_CASE(test_ctzll), + TEST_CASES_END() + } +}; + +static int +test_bitcount(void) +{ + return unit_test_suite_runner(&bitcount_test_suite); +} + +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v2 0/2] eal: provide leading and trailing zero bit count 2022-11-23 22:14 [PATCH 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff 2022-11-23 22:14 ` [PATCH 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2022-11-23 22:14 ` [PATCH 2/2] test/bitcount: add bitcount tests Tyler Retzlaff @ 2022-11-23 23:43 ` Tyler Retzlaff 2022-11-23 23:43 ` [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff ` (3 more replies) 2023-01-06 22:01 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Tyler Retzlaff ` (4 subsequent siblings) 7 siblings, 4 replies; 81+ messages in thread From: Tyler Retzlaff @ 2022-11-23 23:43 UTC (permalink / raw) To: dev; +Cc: Tyler Retzlaff Provide leading and trailing zero bit count functions to abstract away compiler specific implementations. Include basic unit test for new leading/trailing zero bit count functions. v2: * use unsigned int instead of unsigned (checkpatches) * match multiple include guard naming convention to rte_common.h * add explicit extern "C" linkage to rte_bitcount.h note: not really needed but checkpatches required * add missing space around '-' Tyler Retzlaff (2): eal: provide leading and trailing zero bit count abstraction test/bitcount: add bitcount tests app/test/meson.build | 2 + app/test/test_bitcount.c | 92 ++++++++++++++ lib/eal/include/meson.build | 1 + lib/eal/include/rte_bitcount.h | 265 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 360 insertions(+) create mode 100644 app/test/test_bitcount.c create mode 100644 lib/eal/include/rte_bitcount.h -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2022-11-23 23:43 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff @ 2022-11-23 23:43 ` Tyler Retzlaff 2022-11-24 10:17 ` Morten Brørup 2023-01-05 7:09 ` Morten Brørup 2022-11-23 23:43 ` [PATCH v2 2/2] test/bitcount: add bitcount tests Tyler Retzlaff ` (2 subsequent siblings) 3 siblings, 2 replies; 81+ messages in thread From: Tyler Retzlaff @ 2022-11-23 23:43 UTC (permalink / raw) To: dev; +Cc: Tyler Retzlaff Provide an abstraction for leading and trailing zero bit counting functions to hide compiler specific intrinsics and builtins. Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- lib/eal/include/meson.build | 1 + lib/eal/include/rte_bitcount.h | 265 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 lib/eal/include/rte_bitcount.h diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build index cfcd40a..8ff1d65 100644 --- a/lib/eal/include/meson.build +++ b/lib/eal/include/meson.build @@ -5,6 +5,7 @@ includes += include_directories('.') headers += files( 'rte_alarm.h', + 'rte_bitcount.h', 'rte_bitmap.h', 'rte_bitops.h', 'rte_branch_prediction.h', diff --git a/lib/eal/include/rte_bitcount.h b/lib/eal/include/rte_bitcount.h new file mode 100644 index 0000000..587de52 --- /dev/null +++ b/lib/eal/include/rte_bitcount.h @@ -0,0 +1,265 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#ifndef _RTE_BITCOUNT_H_ +#define _RTE_BITCOUNT_H_ + +#include <rte_compat.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef RTE_TOOLCHAIN_MSVC + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz(unsigned int v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clzl(unsigned long v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clzll(unsigned long long v) +{ + unsigned long rv; + + (void)_BitScanReverse64(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz(unsigned int v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctzl(unsigned long v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctzll(unsigned long long v) +{ + unsigned long rv; + + (void)_BitScanForward64(&rv, v); + + return (unsigned int)rv; +} + +#else + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz(unsigned int v) +{ + return (unsigned int)__builtin_clz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clzl(unsigned long v) +{ + return (unsigned int)__builtin_clzl(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clzll(unsigned long v) +{ + return (unsigned int)__builtin_clzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz(unsigned int v) +{ + return (unsigned int)__builtin_ctz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctzl(unsigned long v) +{ + return (unsigned int)__builtin_ctzl(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctzll(unsigned long v) +{ + return (unsigned int)__builtin_ctzll(v); +} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_BITCOUNT_H_ */ + -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* RE: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2022-11-23 23:43 ` [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2022-11-24 10:17 ` Morten Brørup 2022-11-28 17:13 ` Tyler Retzlaff 2023-01-05 7:09 ` Morten Brørup 1 sibling, 1 reply; 81+ messages in thread From: Morten Brørup @ 2022-11-24 10:17 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: dev > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > Sent: Thursday, 24 November 2022 00.43 > > Provide an abstraction for leading and trailing zero bit counting > functions to hide compiler specific intrinsics and builtins. > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > --- Related functions already exist in lib/eal/include/rte_common.h. If some functions are missing, it would be good to add them. Also, it makes sense moving them out of rte_common.h. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2022-11-24 10:17 ` Morten Brørup @ 2022-11-28 17:13 ` Tyler Retzlaff 2022-11-28 17:22 ` Morten Brørup 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2022-11-28 17:13 UTC (permalink / raw) To: Morten Brørup; +Cc: dev On Thu, Nov 24, 2022 at 11:17:23AM +0100, Morten Brørup wrote: > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > Sent: Thursday, 24 November 2022 00.43 > > > > Provide an abstraction for leading and trailing zero bit counting > > functions to hide compiler specific intrinsics and builtins. > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > --- > let me unpack what is being asked for here. > Related functions already exist in lib/eal/include/rte_common.h. i don't understand. are you saying these inline functions duplicate existing bit counting functionality? if so i'll relocate any you identify. > > If some functions are missing, it would be good to add them. the change here is to address a specific family of functions that are impeding portability of the rte_common.h header and nothing more. i'm open to having a separate mail thread discussing what other functions we might want and whether to relocate code out of rte_common.h since that is likely to be a drawn out discussion it shouldn't be a blocking dependency of this series. > > Also, it makes sense moving them out of rte_common.h. thanks! ^ permalink raw reply [flat|nested] 81+ messages in thread
* RE: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2022-11-28 17:13 ` Tyler Retzlaff @ 2022-11-28 17:22 ` Morten Brørup 2022-11-28 17:27 ` Tyler Retzlaff 0 siblings, 1 reply; 81+ messages in thread From: Morten Brørup @ 2022-11-28 17:22 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: dev > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > Sent: Monday, 28 November 2022 18.14 > > On Thu, Nov 24, 2022 at 11:17:23AM +0100, Morten Brørup wrote: > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > functions to hide compiler specific intrinsics and builtins. > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > --- > > > > let me unpack what is being asked for here. > > > Related functions already exist in lib/eal/include/rte_common.h. > > i don't understand. are you saying these inline functions duplicate > existing bit counting functionality? if so i'll relocate any you > identify. Sorry about not being clear about my intentions with the feedback. I'm not asking for anything; I only wanted to point at the similar family of functions in rte_common.h, to make sure that you were aware of them. > > > > > If some functions are missing, it would be good to add them. > > the change here is to address a specific family of functions that are > impeding portability of the rte_common.h header and nothing more. > > i'm open to having a separate mail thread discussing what other > functions we might want and whether to relocate code out of > rte_common.h > since that is likely to be a drawn out discussion it shouldn't be a > blocking dependency of this series. I do not request any new functions; I'll leave it up to you to decide if anything would be good to add. > > > > > Also, it makes sense moving them out of rte_common.h. > > thanks! Thank you! Cleaning up is always appreciated. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2022-11-28 17:22 ` Morten Brørup @ 2022-11-28 17:27 ` Tyler Retzlaff 2023-01-05 9:04 ` Thomas Monjalon 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2022-11-28 17:27 UTC (permalink / raw) To: Morten Brørup; +Cc: dev On Mon, Nov 28, 2022 at 06:22:10PM +0100, Morten Brørup wrote: > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > Sent: Monday, 28 November 2022 18.14 > > > > On Thu, Nov 24, 2022 at 11:17:23AM +0100, Morten Brørup wrote: > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > > functions to hide compiler specific intrinsics and builtins. > > > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > > --- > > > > > > > let me unpack what is being asked for here. > > > > > Related functions already exist in lib/eal/include/rte_common.h. > > > > i don't understand. are you saying these inline functions duplicate > > existing bit counting functionality? if so i'll relocate any you > > identify. > > Sorry about not being clear about my intentions with the feedback. > > I'm not asking for anything; I only wanted to point at the similar family of functions in rte_common.h, to make sure that you were aware of them. oh! not a problem. i'm very keen to catch any mistakes, thought i had missed something. > > > > > > > > > If some functions are missing, it would be good to add them. > > > > the change here is to address a specific family of functions that are > > impeding portability of the rte_common.h header and nothing more. > > > > i'm open to having a separate mail thread discussing what other > > functions we might want and whether to relocate code out of > > rte_common.h > > since that is likely to be a drawn out discussion it shouldn't be a > > blocking dependency of this series. > > I do not request any new functions; I'll leave it up to you to decide if anything would be good to add. > > > > > > > > > Also, it makes sense moving them out of rte_common.h. > > > > thanks! > > Thank you! Cleaning up is always appreciated. yes, if i can get more rapid approvals there is a lot more in the pipeline. i'd like gain some momentum if possible. ty ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2022-11-28 17:27 ` Tyler Retzlaff @ 2023-01-05 9:04 ` Thomas Monjalon 2023-01-05 17:23 ` Tyler Retzlaff 0 siblings, 1 reply; 81+ messages in thread From: Thomas Monjalon @ 2023-01-05 9:04 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: Morten Brørup, dev, david.marchand 28/11/2022 18:27, Tyler Retzlaff: > On Mon, Nov 28, 2022 at 06:22:10PM +0100, Morten Brørup wrote: > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > Sent: Monday, 28 November 2022 18.14 > > > > > > On Thu, Nov 24, 2022 at 11:17:23AM +0100, Morten Brørup wrote: > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > > > functions to hide compiler specific intrinsics and builtins. > > > > > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > > > > let me unpack what is being asked for here. > > > > > > > Related functions already exist in lib/eal/include/rte_common.h. > > > > > > i don't understand. are you saying these inline functions duplicate > > > existing bit counting functionality? if so i'll relocate any you > > > identify. > > > > Sorry about not being clear about my intentions with the feedback. > > > > I'm not asking for anything; I only wanted to point at the similar family of functions in rte_common.h, to make sure that you were aware of them. > > oh! not a problem. i'm very keen to catch any mistakes, thought i had > missed something. I think we should move all bit-related functions together. Please could you add another patch to your series moving "ms1b"/"bsf"/"fls" functions in this file? ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 9:04 ` Thomas Monjalon @ 2023-01-05 17:23 ` Tyler Retzlaff 2023-01-05 17:27 ` Tyler Retzlaff 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-05 17:23 UTC (permalink / raw) To: Thomas Monjalon; +Cc: Morten Brørup, dev, david.marchand On Thu, Jan 05, 2023 at 10:04:46AM +0100, Thomas Monjalon wrote: > 28/11/2022 18:27, Tyler Retzlaff: > > On Mon, Nov 28, 2022 at 06:22:10PM +0100, Morten Brørup wrote: > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > Sent: Monday, 28 November 2022 18.14 > > > > > > > > On Thu, Nov 24, 2022 at 11:17:23AM +0100, Morten Brørup wrote: > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > > > > functions to hide compiler specific intrinsics and builtins. > > > > > > > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > > > > > > let me unpack what is being asked for here. > > > > > > > > > Related functions already exist in lib/eal/include/rte_common.h. > > > > > > > > i don't understand. are you saying these inline functions duplicate > > > > existing bit counting functionality? if so i'll relocate any you > > > > identify. > > > > > > Sorry about not being clear about my intentions with the feedback. > > > > > > I'm not asking for anything; I only wanted to point at the similar family of functions in rte_common.h, to make sure that you were aware of them. > > > > oh! not a problem. i'm very keen to catch any mistakes, thought i had > > missed something. > > I think we should move all bit-related functions together. > Please could you add another patch to your series > moving "ms1b"/"bsf"/"fls" functions in this file? > > okay, so there is already a rte_bitops.h. i guess everything should go there including the leading/trailing count functions instead of adding a new header. i'll introduce a new patch to the series that gathers the existing functions into rte_bitops.h and place the new functions there too. thanks ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 17:23 ` Tyler Retzlaff @ 2023-01-05 17:27 ` Tyler Retzlaff 2023-01-05 20:57 ` Tyler Retzlaff 2023-01-06 10:00 ` Thomas Monjalon 0 siblings, 2 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-05 17:27 UTC (permalink / raw) To: Thomas Monjalon; +Cc: Morten Brørup, dev, david.marchand On Thu, Jan 05, 2023 at 09:23:49AM -0800, Tyler Retzlaff wrote: > On Thu, Jan 05, 2023 at 10:04:46AM +0100, Thomas Monjalon wrote: > > 28/11/2022 18:27, Tyler Retzlaff: > > > On Mon, Nov 28, 2022 at 06:22:10PM +0100, Morten Brørup wrote: > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > Sent: Monday, 28 November 2022 18.14 > > > > > > > > > > On Thu, Nov 24, 2022 at 11:17:23AM +0100, Morten Brørup wrote: > > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > > > > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > > > > > functions to hide compiler specific intrinsics and builtins. > > > > > > > > > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > > > > > > > > let me unpack what is being asked for here. > > > > > > > > > > > Related functions already exist in lib/eal/include/rte_common.h. > > > > > > > > > > i don't understand. are you saying these inline functions duplicate > > > > > existing bit counting functionality? if so i'll relocate any you > > > > > identify. > > > > > > > > Sorry about not being clear about my intentions with the feedback. > > > > > > > > I'm not asking for anything; I only wanted to point at the similar family of functions in rte_common.h, to make sure that you were aware of them. > > > > > > oh! not a problem. i'm very keen to catch any mistakes, thought i had > > > missed something. > > > > I think we should move all bit-related functions together. > > Please could you add another patch to your series > > moving "ms1b"/"bsf"/"fls" functions in this file? > > > > > > okay, so there is already a rte_bitops.h. i guess everything should go > there including the leading/trailing count functions instead of adding a > new header. > > i'll introduce a new patch to the series that gathers the existing > functions into rte_bitops.h and place the new functions there too. > > thanks just as a further follow up, you do understand that this is technically an api break? moving functions from rte_common.h to rte_bitops.h will make translation units that included only rte_common.h but used these functions will fail to compile without being updated to include rte_bitops.h. anyway, i'll submit v3 with this change anyway. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 17:27 ` Tyler Retzlaff @ 2023-01-05 20:57 ` Tyler Retzlaff 2023-01-05 21:34 ` Morten Brørup 2023-01-06 10:00 ` Thomas Monjalon 1 sibling, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-05 20:57 UTC (permalink / raw) To: Thomas Monjalon; +Cc: Morten Brørup, dev, david.marchand On Thu, Jan 05, 2023 at 09:27:12AM -0800, Tyler Retzlaff wrote: > On Thu, Jan 05, 2023 at 09:23:49AM -0800, Tyler Retzlaff wrote: > > > > oh! not a problem. i'm very keen to catch any mistakes, thought i had > > > > missed something. > > > > > > I think we should move all bit-related functions together. > > > Please could you add another patch to your series > > > moving "ms1b"/"bsf"/"fls" functions in this file? > > > > > > > > > > okay, so there is already a rte_bitops.h. i guess everything should go > > there including the leading/trailing count functions instead of adding a > > new header. > > > > i'll introduce a new patch to the series that gathers the existing > > functions into rte_bitops.h and place the new functions there too. > > > > thanks > > just as a further follow up, you do understand that this is technically > an api break? > > moving functions from rte_common.h to rte_bitops.h will make translation > units that included only rte_common.h but used these functions will > fail to compile without being updated to include rte_bitops.h. > > anyway, i'll submit v3 with this change anyway. so when attempting to do this it became immediately obvious that moving just the bit op functions out is going to create a circular dependency between rte_common.h, rte_bitops.h once the bit ops are moved out of common there are still other inline functions that remain in comman that require bringing bitops back in, but bitops depends on common. my compromise will be to break log2 and pow2 inline functions into their own files to break the cycle (common no longer depends on bitops). i'll submit patches for this but it ends up touching a lot more of the tree to add back includes for log/pow inline use. alternatively i can just not move the remaining bit manipulation functions, let me know which is preferred. thanks ^ permalink raw reply [flat|nested] 81+ messages in thread
* RE: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 20:57 ` Tyler Retzlaff @ 2023-01-05 21:34 ` Morten Brørup 2023-01-05 22:06 ` Tyler Retzlaff 0 siblings, 1 reply; 81+ messages in thread From: Morten Brørup @ 2023-01-05 21:34 UTC (permalink / raw) To: Tyler Retzlaff, Thomas Monjalon; +Cc: dev, david.marchand > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > Sent: Thursday, 5 January 2023 21.58 > > On Thu, Jan 05, 2023 at 09:27:12AM -0800, Tyler Retzlaff wrote: > > On Thu, Jan 05, 2023 at 09:23:49AM -0800, Tyler Retzlaff wrote: > > > > > oh! not a problem. i'm very keen to catch any mistakes, thought > i had > > > > > missed something. > > > > > > > > I think we should move all bit-related functions together. > > > > Please could you add another patch to your series > > > > moving "ms1b"/"bsf"/"fls" functions in this file? > > > > > > > > > > > > > > okay, so there is already a rte_bitops.h. i guess everything should > go > > > there including the leading/trailing count functions instead of > adding a > > > new header. > > > > > > i'll introduce a new patch to the series that gathers the existing > > > functions into rte_bitops.h and place the new functions there too. > > > > > > thanks > > > > just as a further follow up, you do understand that this is > technically > > an api break? > > > > moving functions from rte_common.h to rte_bitops.h will make > translation > > units that included only rte_common.h but used these functions will > > fail to compile without being updated to include rte_bitops.h. > > > > anyway, i'll submit v3 with this change anyway. > > so when attempting to do this it became immediately obvious that moving > just the bit op functions out is going to create a circular dependency > between rte_common.h, rte_bitops.h > > once the bit ops are moved out of common there are still other inline > functions that remain in comman that require bringing bitops back in, > but bitops depends on common. > > my compromise will be to break log2 and pow2 inline functions into > their > own files to break the cycle (common no longer depends on bitops). i'll > submit patches for this but it ends up touching a lot more of the > tree to add back includes for log/pow inline use. > > alternatively i can just not move the remaining bit manipulation > functions, let me know which is preferred. It seems that no perfect solution exists, so we will have to live with a compromise. Here is another proposal for a compromise, for yours and Thomas's consideration: I noticed that rte_bitops.h is mainly for setting/getting bits, used for accessing hardware. Your functions are mathematical functions, and so are the similar functions in rte_common.h (which is why it makes sense to keep them together with yours). If we cannot clean up rte_common.h by moving them out, perhaps we should accept the current situation (until we find a way to move them out) and just add your mathematical functions where the existing mathematical functions reside, i.e. in rte_common.h. This proposal only makes the existing mess slightly larger; it doesn't create a new kind of mess. -Morten ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 21:34 ` Morten Brørup @ 2023-01-05 22:06 ` Tyler Retzlaff 2023-01-05 23:10 ` Morten Brørup 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-05 22:06 UTC (permalink / raw) To: Morten Brørup; +Cc: Thomas Monjalon, dev, david.marchand On Thu, Jan 05, 2023 at 10:34:55PM +0100, Morten Brørup wrote: > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > Sent: Thursday, 5 January 2023 21.58 > > > > On Thu, Jan 05, 2023 at 09:27:12AM -0800, Tyler Retzlaff wrote: > > > On Thu, Jan 05, 2023 at 09:23:49AM -0800, Tyler Retzlaff wrote: > > > > > > oh! not a problem. i'm very keen to catch any mistakes, thought > > i had > > > > > > missed something. > > > > > > > > > > I think we should move all bit-related functions together. > > > > > Please could you add another patch to your series > > > > > moving "ms1b"/"bsf"/"fls" functions in this file? > > > > > > > > > > > > > > > > > > okay, so there is already a rte_bitops.h. i guess everything should > > go > > > > there including the leading/trailing count functions instead of > > adding a > > > > new header. > > > > > > > > i'll introduce a new patch to the series that gathers the existing > > > > functions into rte_bitops.h and place the new functions there too. > > > > > > > > thanks > > > > > > just as a further follow up, you do understand that this is > > technically > > > an api break? > > > > > > moving functions from rte_common.h to rte_bitops.h will make > > translation > > > units that included only rte_common.h but used these functions will > > > fail to compile without being updated to include rte_bitops.h. > > > > > > anyway, i'll submit v3 with this change anyway. > > > > so when attempting to do this it became immediately obvious that moving > > just the bit op functions out is going to create a circular dependency > > between rte_common.h, rte_bitops.h > > > > once the bit ops are moved out of common there are still other inline > > functions that remain in comman that require bringing bitops back in, > > but bitops depends on common. > > > > my compromise will be to break log2 and pow2 inline functions into > > their > > own files to break the cycle (common no longer depends on bitops). i'll > > submit patches for this but it ends up touching a lot more of the > > tree to add back includes for log/pow inline use. > > > > alternatively i can just not move the remaining bit manipulation > > functions, let me know which is preferred. > > It seems that no perfect solution exists, so we will have to live with a compromise. Here is another proposal for a compromise, for yours and Thomas's consideration: > > I noticed that rte_bitops.h is mainly for setting/getting bits, used for accessing hardware. > > Your functions are mathematical functions, and so are the similar functions in rte_common.h (which is why it makes sense to keep them together with yours). If we cannot clean up rte_common.h by moving them out, perhaps we should accept the current situation (until we find a way to move them out) and just add your mathematical functions where the existing mathematical functions reside, i.e. in rte_common.h. > > This proposal only makes the existing mess slightly larger; it doesn't create a new kind of mess. so i fudged around a bit to see if i could get a happy medium. i ended up with this. remove include of rte_debug.h from rte_bitops.h * had to remove the RTE_ASSERT from existing rte_bitops.h functions * this breaks a good piece of the cycle debug -> log -> common -> bitops -> debug * deal breaker? i don't think it was right that we were getting all of log, common just for using bitops anyway. move pow2 functions from rte_common.h -> rte_pow2ops.h * new header includes rte_bitops.h move log2 functions from rte_common.h -> rte_log2ops.h * new header includes rte_bitops.h, rte_pow2ops.h include rte_bitops.h, rte_pow2ops.h and rte_log2ops.h back into rte_common.h * this is done to reduce the impact of compatibility break by continuing to expose the pow2/log2/bitops via rte_common.h so we end up with 3 standalone headers, where the whole tree builds without having to add a pile of includes for the new headers. we can later deprecate the exposure of the inline functions when including rte_common.h * one caveat is that there was some contamination coming in via the removed rte_debug.h where rte_bitops.h was used. so technically a break of api too. objections? if this is no good i'll just fold my new functions into rte_common.h and leave the mess for the next person, though i am trying not to do that. thanks for the discussion. ^ permalink raw reply [flat|nested] 81+ messages in thread
* RE: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 22:06 ` Tyler Retzlaff @ 2023-01-05 23:10 ` Morten Brørup 2023-01-06 1:04 ` Tyler Retzlaff 0 siblings, 1 reply; 81+ messages in thread From: Morten Brørup @ 2023-01-05 23:10 UTC (permalink / raw) To: Tyler Retzlaff, Thomas Monjalon; +Cc: dev, david.marchand > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > Sent: Thursday, 5 January 2023 23.06 > > On Thu, Jan 05, 2023 at 10:34:55PM +0100, Morten Brørup wrote: > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > Sent: Thursday, 5 January 2023 21.58 > > > > > > On Thu, Jan 05, 2023 at 09:27:12AM -0800, Tyler Retzlaff wrote: > > > > On Thu, Jan 05, 2023 at 09:23:49AM -0800, Tyler Retzlaff wrote: > > > > > > > oh! not a problem. i'm very keen to catch any mistakes, > thought > > > i had > > > > > > > missed something. > > > > > > > > > > > > I think we should move all bit-related functions together. > > > > > > Please could you add another patch to your series > > > > > > moving "ms1b"/"bsf"/"fls" functions in this file? > > > > > > > > > > > > > > > > > > > > > > okay, so there is already a rte_bitops.h. i guess everything > should > > > go > > > > > there including the leading/trailing count functions instead of > > > adding a > > > > > new header. > > > > > > > > > > i'll introduce a new patch to the series that gathers the > existing > > > > > functions into rte_bitops.h and place the new functions there > too. > > > > > > > > > > thanks > > > > > > > > just as a further follow up, you do understand that this is > > > technically > > > > an api break? > > > > > > > > moving functions from rte_common.h to rte_bitops.h will make > > > translation > > > > units that included only rte_common.h but used these functions > will > > > > fail to compile without being updated to include rte_bitops.h. > > > > > > > > anyway, i'll submit v3 with this change anyway. > > > > > > so when attempting to do this it became immediately obvious that > moving > > > just the bit op functions out is going to create a circular > dependency > > > between rte_common.h, rte_bitops.h > > > > > > once the bit ops are moved out of common there are still other > inline > > > functions that remain in comman that require bringing bitops back > in, > > > but bitops depends on common. > > > > > > my compromise will be to break log2 and pow2 inline functions into > > > their > > > own files to break the cycle (common no longer depends on bitops). > i'll > > > submit patches for this but it ends up touching a lot more of the > > > tree to add back includes for log/pow inline use. > > > > > > alternatively i can just not move the remaining bit manipulation > > > functions, let me know which is preferred. > > > > It seems that no perfect solution exists, so we will have to live > with a compromise. Here is another proposal for a compromise, for yours > and Thomas's consideration: > > > > I noticed that rte_bitops.h is mainly for setting/getting bits, used > for accessing hardware. > > > > Your functions are mathematical functions, and so are the similar > functions in rte_common.h (which is why it makes sense to keep them > together with yours). If we cannot clean up rte_common.h by moving them > out, perhaps we should accept the current situation (until we find a > way to move them out) and just add your mathematical functions where > the existing mathematical functions reside, i.e. in rte_common.h. > > > > This proposal only makes the existing mess slightly larger; it > doesn't create a new kind of mess. > > so i fudged around a bit to see if i could get a happy medium. i ended > up with this. > > remove include of rte_debug.h from rte_bitops.h > > * had to remove the RTE_ASSERT from existing rte_bitops.h functions > * this breaks a good piece of the cycle debug -> log -> common -> > bitops -> debug > * deal breaker? i don't think it was right that we were getting all > of log, common just for using bitops anyway. > > move pow2 functions from rte_common.h -> rte_pow2ops.h > * new header includes rte_bitops.h > > move log2 functions from rte_common.h -> rte_log2ops.h > * new header includes rte_bitops.h, rte_pow2ops.h > > include rte_bitops.h, rte_pow2ops.h and rte_log2ops.h back into > rte_common.h > > * this is done to reduce the impact of compatibility break by > continuing to expose the pow2/log2/bitops via rte_common.h > > so we end up with 3 standalone headers, where the whole tree builds > without having to add a pile of includes for the new headers. we can > later deprecate the exposure of the inline functions when including > rte_common.h > > * one caveat is that there was some contamination coming in via the > removed rte_debug.h where rte_bitops.h was used. so technically > a break of api too. > > objections? > > if this is no good i'll just fold my new functions into rte_common.h > and > leave the mess for the next person, though i am trying not to do that. > > thanks for the discussion. Here's some long term thinking: EAL has grown into a trashcan where too much is thrown in. It should only be a thin shim to abstract the underlying hardware and O/S environment. A step in that direction could be splitting the current EAL into a true EAL and a Utils library. Not now, but perhaps some day in a rosy future. Your proposal effectively makes rte_common.h even bigger by including rte_bitops.h (which was intended for accessing hardware). I am not sure it is a step in the right direction. On the other hand, introducing yet another header file for bit-mathematical functions is probably worse than adding them to rte_bitops.h. I can't come up with something good myself, but I lean towards simply adding your functions to rte_common.h and live with the existing mess. If you think your proposal is better, I will not object. I'm only voicing my thoughts. @Thomas may have another perspective on the matter. Thanks for all the work you put into this. -Morten ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 23:10 ` Morten Brørup @ 2023-01-06 1:04 ` Tyler Retzlaff 2023-01-06 10:09 ` Thomas Monjalon 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-06 1:04 UTC (permalink / raw) To: Morten Brørup; +Cc: Thomas Monjalon, dev, david.marchand On Fri, Jan 06, 2023 at 12:10:45AM +0100, Morten Brørup wrote: > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > Sent: Thursday, 5 January 2023 23.06 > > > > doesn't create a new kind of mess. > > > > so i fudged around a bit to see if i could get a happy medium. i ended > > up with this. > > > > remove include of rte_debug.h from rte_bitops.h > > > > * had to remove the RTE_ASSERT from existing rte_bitops.h functions > > * this breaks a good piece of the cycle debug -> log -> common -> > > bitops -> debug > > * deal breaker? i don't think it was right that we were getting all > > of log, common just for using bitops anyway. > > > > move pow2 functions from rte_common.h -> rte_pow2ops.h > > * new header includes rte_bitops.h > > > > move log2 functions from rte_common.h -> rte_log2ops.h > > * new header includes rte_bitops.h, rte_pow2ops.h > > > > include rte_bitops.h, rte_pow2ops.h and rte_log2ops.h back into > > rte_common.h > > > > * this is done to reduce the impact of compatibility break by > > continuing to expose the pow2/log2/bitops via rte_common.h > > > > so we end up with 3 standalone headers, where the whole tree builds > > without having to add a pile of includes for the new headers. we can > > later deprecate the exposure of the inline functions when including > > rte_common.h > > > > * one caveat is that there was some contamination coming in via the > > removed rte_debug.h where rte_bitops.h was used. so technically > > a break of api too. > > > > objections? > > > > if this is no good i'll just fold my new functions into rte_common.h > > and > > leave the mess for the next person, though i am trying not to do that. > > > > thanks for the discussion. > > Here's some long term thinking: EAL has grown into a trashcan where too much is thrown in. It should only be a thin shim to abstract the underlying hardware and O/S environment. A step in that direction could be splitting the current EAL into a true EAL and a Utils library. Not now, but perhaps some day in a rosy future. > > Your proposal effectively makes rte_common.h even bigger by including rte_bitops.h (which was intended for accessing hardware). I am not sure it is a step in the right direction. On the other hand, introducing yet another header file for bit-mathematical functions is probably worse than adding them to rte_bitops.h. > > I can't come up with something good myself, but I lean towards simply adding your functions to rte_common.h and live with the existing mess. If you think your proposal is better, I will not object. I'm only voicing my thoughts. it's hard when we are starting with something monolithic and trying to split it. you always end up with these iterative transitions toward what you want because you have to keep some kind of compat. > > @Thomas may have another perspective on the matter. Thomas any last word after this back and forth? This change isn't necessarily blocking me but is a distraction i'd like to finish/offload. > > Thanks for all the work you put into this. np, it is somewhat out of necessity since i need this stuff to be portable. but having it move in the right direction at the same time is a benefit for anyone who comes later. ty ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-06 1:04 ` Tyler Retzlaff @ 2023-01-06 10:09 ` Thomas Monjalon 0 siblings, 0 replies; 81+ messages in thread From: Thomas Monjalon @ 2023-01-06 10:09 UTC (permalink / raw) To: Morten Brørup, Tyler Retzlaff; +Cc: dev, david.marchand 06/01/2023 02:04, Tyler Retzlaff: > On Fri, Jan 06, 2023 at 12:10:45AM +0100, Morten Brørup wrote: > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > Sent: Thursday, 5 January 2023 23.06 > > > > > > doesn't create a new kind of mess. > > > > > > so i fudged around a bit to see if i could get a happy medium. i ended > > > up with this. > > > > > > remove include of rte_debug.h from rte_bitops.h > > > > > > * had to remove the RTE_ASSERT from existing rte_bitops.h functions > > > * this breaks a good piece of the cycle debug -> log -> common -> > > > bitops -> debug > > > * deal breaker? i don't think it was right that we were getting all > > > of log, common just for using bitops anyway. > > > > > > move pow2 functions from rte_common.h -> rte_pow2ops.h > > > * new header includes rte_bitops.h > > > > > > move log2 functions from rte_common.h -> rte_log2ops.h > > > * new header includes rte_bitops.h, rte_pow2ops.h > > > > > > include rte_bitops.h, rte_pow2ops.h and rte_log2ops.h back into > > > rte_common.h > > > > > > * this is done to reduce the impact of compatibility break by > > > continuing to expose the pow2/log2/bitops via rte_common.h > > > > > > so we end up with 3 standalone headers, where the whole tree builds > > > without having to add a pile of includes for the new headers. we can > > > later deprecate the exposure of the inline functions when including > > > rte_common.h > > > > > > * one caveat is that there was some contamination coming in via the > > > removed rte_debug.h where rte_bitops.h was used. so technically > > > a break of api too. > > > > > > objections? > > > > > > if this is no good i'll just fold my new functions into rte_common.h > > > and > > > leave the mess for the next person, though i am trying not to do that. > > > > > > thanks for the discussion. > > > > Here's some long term thinking: EAL has grown into a trashcan where too much is thrown in. It should only be a thin shim to abstract the underlying hardware and O/S environment. A step in that direction could be splitting the current EAL into a true EAL and a Utils library. Not now, but perhaps some day in a rosy future. > > > > Your proposal effectively makes rte_common.h even bigger by including rte_bitops.h (which was intended for accessing hardware). I am not sure it is a step in the right direction. On the other hand, introducing yet another header file for bit-mathematical functions is probably worse than adding them to rte_bitops.h. > > > > I can't come up with something good myself, but I lean towards simply adding your functions to rte_common.h and live with the existing mess. If you think your proposal is better, I will not object. I'm only voicing my thoughts. > > it's hard when we are starting with something monolithic and trying to > split it. you always end up with these iterative transitions toward what > you want because you have to keep some kind of compat. > > > > > @Thomas may have another perspective on the matter. > > Thomas any last word after this back and forth? This change isn't > necessarily blocking me but is a distraction i'd like to finish/offload. I think it is better to move all in rte_bitops.h rte_common must have almost zero dependency. If log2 and pow2 are based on bitops operations, it is not a bad fit for rte_bitops.h. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 17:27 ` Tyler Retzlaff 2023-01-05 20:57 ` Tyler Retzlaff @ 2023-01-06 10:00 ` Thomas Monjalon 1 sibling, 0 replies; 81+ messages in thread From: Thomas Monjalon @ 2023-01-06 10:00 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: Morten Brørup, dev, david.marchand 05/01/2023 18:27, Tyler Retzlaff: > On Thu, Jan 05, 2023 at 09:23:49AM -0800, Tyler Retzlaff wrote: > > On Thu, Jan 05, 2023 at 10:04:46AM +0100, Thomas Monjalon wrote: > > > 28/11/2022 18:27, Tyler Retzlaff: > > > > On Mon, Nov 28, 2022 at 06:22:10PM +0100, Morten Brørup wrote: > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > Sent: Monday, 28 November 2022 18.14 > > > > > > > > > > > > On Thu, Nov 24, 2022 at 11:17:23AM +0100, Morten Brørup wrote: > > > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > > > > > > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > > > > > > functions to hide compiler specific intrinsics and builtins. > > > > > > > > > > > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > > > > > > > > > > let me unpack what is being asked for here. > > > > > > > > > > > > > Related functions already exist in lib/eal/include/rte_common.h. > > > > > > > > > > > > i don't understand. are you saying these inline functions duplicate > > > > > > existing bit counting functionality? if so i'll relocate any you > > > > > > identify. > > > > > > > > > > Sorry about not being clear about my intentions with the feedback. > > > > > > > > > > I'm not asking for anything; I only wanted to point at the similar family of functions in rte_common.h, to make sure that you were aware of them. > > > > > > > > oh! not a problem. i'm very keen to catch any mistakes, thought i had > > > > missed something. > > > > > > I think we should move all bit-related functions together. > > > Please could you add another patch to your series > > > moving "ms1b"/"bsf"/"fls" functions in this file? > > > > > > > > > > okay, so there is already a rte_bitops.h. i guess everything should go > > there including the leading/trailing count functions instead of adding a > > new header. Yes good idea to gather all in rte_bitops.h. > > i'll introduce a new patch to the series that gathers the existing > > functions into rte_bitops.h and place the new functions there too. > > > > thanks > > just as a further follow up, you do understand that this is technically > an api break? Yes > moving functions from rte_common.h to rte_bitops.h will make translation > units that included only rte_common.h but used these functions will > fail to compile without being updated to include rte_bitops.h. These functions are not used a lot, it is a "small" API break. ^ permalink raw reply [flat|nested] 81+ messages in thread
* RE: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2022-11-23 23:43 ` [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2022-11-24 10:17 ` Morten Brørup @ 2023-01-05 7:09 ` Morten Brørup 2023-01-05 9:01 ` Thomas Monjalon 2023-04-04 21:23 ` Tyler Retzlaff 1 sibling, 2 replies; 81+ messages in thread From: Morten Brørup @ 2023-01-05 7:09 UTC (permalink / raw) To: Tyler Retzlaff, dev; +Cc: david.marchand, thomas > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > Sent: Thursday, 24 November 2022 00.43 > > Provide an abstraction for leading and trailing zero bit counting > functions to hide compiler specific intrinsics and builtins. > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > --- > lib/eal/include/meson.build | 1 + > lib/eal/include/rte_bitcount.h | 265 > +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 266 insertions(+) > create mode 100644 lib/eal/include/rte_bitcount.h > > diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build > index cfcd40a..8ff1d65 100644 > --- a/lib/eal/include/meson.build > +++ b/lib/eal/include/meson.build > @@ -5,6 +5,7 @@ includes += include_directories('.') > > headers += files( > 'rte_alarm.h', > + 'rte_bitcount.h', > 'rte_bitmap.h', > 'rte_bitops.h', > 'rte_branch_prediction.h', > diff --git a/lib/eal/include/rte_bitcount.h > b/lib/eal/include/rte_bitcount.h > new file mode 100644 > index 0000000..587de52 > --- /dev/null > +++ b/lib/eal/include/rte_bitcount.h > @@ -0,0 +1,265 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright (C) 2022 Microsoft Corporation > + */ > + > +#ifndef _RTE_BITCOUNT_H_ > +#define _RTE_BITCOUNT_H_ > + > +#include <rte_compat.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#ifdef RTE_TOOLCHAIN_MSVC > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_clz(unsigned int v) > +{ > + unsigned long rv; > + > + (void)_BitScanReverse(&rv, v); > + > + return (unsigned int)rv; > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_clzl(unsigned long v) Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. E.g.: rte_clz32(uint32_t v) > +{ > + unsigned long rv; > + > + (void)_BitScanReverse(&rv, v); > + > + return (unsigned int)rv; > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_clzll(unsigned long long v) Same comment as above: e.g. rte_clz64(uint64_t v) ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 7:09 ` Morten Brørup @ 2023-01-05 9:01 ` Thomas Monjalon 2023-01-05 17:21 ` Tyler Retzlaff 2023-04-04 21:23 ` Tyler Retzlaff 1 sibling, 1 reply; 81+ messages in thread From: Thomas Monjalon @ 2023-01-05 9:01 UTC (permalink / raw) To: Tyler Retzlaff, Morten Brørup; +Cc: dev, david.marchand 05/01/2023 08:09, Morten Brørup: > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > notice > > + * > > + * Get the count of leading 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of leading zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_clzl(unsigned long v) > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > E.g.: rte_clz32(uint32_t v) I agree on using numbers. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 9:01 ` Thomas Monjalon @ 2023-01-05 17:21 ` Tyler Retzlaff 2023-01-06 0:32 ` Stephen Hemminger 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-05 17:21 UTC (permalink / raw) To: Thomas Monjalon; +Cc: Morten Brørup, dev, david.marchand On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: > 05/01/2023 08:09, Morten Brørup: > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > +/** > > > + * @warning > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > notice > > > + * > > > + * Get the count of leading 0-bits in v. > > > + * > > > + * @param v > > > + * The value. > > > + * @return > > > + * The count of leading zero bits. > > > + */ > > > +__rte_experimental > > > +static inline unsigned int > > > +rte_clzl(unsigned long v) > > > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > > > E.g.: rte_clz32(uint32_t v) > > I agree on using numbers. > love the idea, fewer functions too. though it is a shame we cannot adopt C11 standard because we could just do away with the bit suffixes entirely. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 17:21 ` Tyler Retzlaff @ 2023-01-06 0:32 ` Stephen Hemminger 2023-01-06 11:48 ` Bruce Richardson 0 siblings, 1 reply; 81+ messages in thread From: Stephen Hemminger @ 2023-01-06 0:32 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: Thomas Monjalon, Morten Brørup, dev, david.marchand On Thu, 5 Jan 2023 09:21:18 -0800 Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: > > 05/01/2023 08:09, Morten Brørup: > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > +/** > > > > + * @warning > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > notice > > > > + * > > > > + * Get the count of leading 0-bits in v. > > > > + * > > > > + * @param v > > > > + * The value. > > > > + * @return > > > > + * The count of leading zero bits. > > > > + */ > > > > +__rte_experimental > > > > +static inline unsigned int > > > > +rte_clzl(unsigned long v) > > > > > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > > > > > E.g.: rte_clz32(uint32_t v) > > > > I agree on using numbers. > > > > love the idea, fewer functions too. > > though it is a shame we cannot adopt C11 standard because we could just > do away with the bit suffixes entirely. We could but the project needs to support older RHEL releases which have older tool sets. Though probably this is moot point given how much meson seems to change. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-06 0:32 ` Stephen Hemminger @ 2023-01-06 11:48 ` Bruce Richardson 2023-01-06 12:41 ` Morten Brørup 2023-01-06 18:47 ` Tyler Retzlaff 0 siblings, 2 replies; 81+ messages in thread From: Bruce Richardson @ 2023-01-06 11:48 UTC (permalink / raw) To: Stephen Hemminger Cc: Tyler Retzlaff, Thomas Monjalon, Morten Brørup, dev, david.marchand On Thu, Jan 05, 2023 at 04:32:40PM -0800, Stephen Hemminger wrote: > On Thu, 5 Jan 2023 09:21:18 -0800 > Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > > On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: > > > 05/01/2023 08:09, Morten Brørup: > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > +/** > > > > > + * @warning > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > > notice > > > > > + * > > > > > + * Get the count of leading 0-bits in v. > > > > > + * > > > > > + * @param v > > > > > + * The value. > > > > > + * @return > > > > > + * The count of leading zero bits. > > > > > + */ > > > > > +__rte_experimental > > > > > +static inline unsigned int > > > > > +rte_clzl(unsigned long v) > > > > > > > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > > > > > > > E.g.: rte_clz32(uint32_t v) > > > > > > I agree on using numbers. > > > > > > > love the idea, fewer functions too. > > > > though it is a shame we cannot adopt C11 standard because we could just > > do away with the bit suffixes entirely. > > We could but the project needs to support older RHEL releases > which have older tool sets. Though probably this is moot point given > how much meson seems to change. True, though meson tends to be a bit easier to update than GCC on a system - no "pip3 install --upgrade gcc", sadly :-) If we can't go all the way to C11 support, how about at least going to C99 support? As far as I know DPDK has never updated its minimum C-standard version, and it might be a good idea to start the process of doing so, even if it is a baby step. /Bruce ^ permalink raw reply [flat|nested] 81+ messages in thread
* RE: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-06 11:48 ` Bruce Richardson @ 2023-01-06 12:41 ` Morten Brørup 2023-01-06 13:40 ` Thomas Monjalon 2023-01-06 18:47 ` Tyler Retzlaff 1 sibling, 1 reply; 81+ messages in thread From: Morten Brørup @ 2023-01-06 12:41 UTC (permalink / raw) To: Bruce Richardson, Stephen Hemminger, david.marchand Cc: Tyler Retzlaff, Thomas Monjalon, dev > From: Bruce Richardson [mailto:bruce.richardson@intel.com] > Sent: Friday, 6 January 2023 12.48 > > On Thu, Jan 05, 2023 at 04:32:40PM -0800, Stephen Hemminger wrote: > > On Thu, 5 Jan 2023 09:21:18 -0800 > > Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > > > > On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: > > > > 05/01/2023 08:09, Morten Brørup: > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > +/** > > > > > > + * @warning > > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, > without prior > > > > > > notice > > > > > > + * > > > > > > + * Get the count of leading 0-bits in v. > > > > > > + * > > > > > > + * @param v > > > > > > + * The value. > > > > > > + * @return > > > > > > + * The count of leading zero bits. > > > > > > + */ > > > > > > +__rte_experimental > > > > > > +static inline unsigned int > > > > > > +rte_clzl(unsigned long v) > > > > > > > > > > Don't use l (long) and ll (long long) for names (and types), > use explicit bit lengths, 32 and 64. > > > > > > > > > > E.g.: rte_clz32(uint32_t v) > > > > > > > > I agree on using numbers. > > > > > > > > > > love the idea, fewer functions too. > > > > > > though it is a shame we cannot adopt C11 standard because we could > just > > > do away with the bit suffixes entirely. > > > > We could but the project needs to support older RHEL releases > > which have older tool sets. Though probably this is moot point given > > how much meson seems to change. > > True, though meson tends to be a bit easier to update than GCC on a > system > - no "pip3 install --upgrade gcc", sadly :-) > > If we can't go all the way to C11 support, how about at least going to > C99 > support? As far as I know DPDK has never updated its minimum C-standard > version, and it might be a good idea to start the process of doing so, > even > if it is a baby step. > > /Bruce The DPDK Getting Started Guide [1] says: "Required Tools and Libraries: [...] a supported C compiler such as gcc (version 4.9+)" GCC version 4.9 supports C11 [2]: "GCC 4.9 Changes: "ISO C11 support is now at a similar level of completeness to ISO C99 support [...]" So why are we not going to support C11? Probably because of RHEL 7, which only provides GCC 4.8 [3]. RHEL 7 was released for GA on June 10, 2014 [4]. If someone has a server with a nine year old distro still used in production, it is probably because it is running some legacy application, which is difficult to get up and running on a newer distro. Partial conclusion: RHEL 7 is probably still widely used in production. However, I have a hard time understanding why anyone would build and/or deploy a brand new DPDK application (based on DPDK 23.03) on such a server. Can someone please justify this? Are we really going to postpone C11 support in DPDK until June 30, 2026, when RHEL 7 ends its Extended Life Cycle Support [4]? If so, then the GCC version mentioned in the DPDK Getting Started Guide should be corrected accordingly. [1]: https://doc.dpdk.org/guides/linux_gsg/sys_reqs.html#compilation-of-the-dpdk [2]: https://gcc.gnu.org/wiki/C11Status [3]: https://access.redhat.com/solutions/19458 [4]: https://access.redhat.com/support/policy/updates/errata#Life_Cycle_Dates ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-06 12:41 ` Morten Brørup @ 2023-01-06 13:40 ` Thomas Monjalon 2023-01-06 18:58 ` Tyler Retzlaff 0 siblings, 1 reply; 81+ messages in thread From: Thomas Monjalon @ 2023-01-06 13:40 UTC (permalink / raw) To: Bruce Richardson, Stephen Hemminger, david.marchand Cc: dev, Tyler Retzlaff, dev, Morten Brørup, honnappa.nagarahalli, jerinj, ktraynor, maxime.coquelin 06/01/2023 13:41, Morten Brørup: > > From: Bruce Richardson [mailto:bruce.richardson@intel.com] > > Sent: Friday, 6 January 2023 12.48 > > > > On Thu, Jan 05, 2023 at 04:32:40PM -0800, Stephen Hemminger wrote: > > > On Thu, 5 Jan 2023 09:21:18 -0800 > > > Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > > > > > > On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: > > > > > 05/01/2023 08:09, Morten Brørup: > > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > > +/** > > > > > > > + * @warning > > > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, > > without prior > > > > > > > notice > > > > > > > + * > > > > > > > + * Get the count of leading 0-bits in v. > > > > > > > + * > > > > > > > + * @param v > > > > > > > + * The value. > > > > > > > + * @return > > > > > > > + * The count of leading zero bits. > > > > > > > + */ > > > > > > > +__rte_experimental > > > > > > > +static inline unsigned int > > > > > > > +rte_clzl(unsigned long v) > > > > > > > > > > > > Don't use l (long) and ll (long long) for names (and types), > > use explicit bit lengths, 32 and 64. > > > > > > > > > > > > E.g.: rte_clz32(uint32_t v) > > > > > > > > > > I agree on using numbers. > > > > > > > > > > > > > love the idea, fewer functions too. > > > > > > > > though it is a shame we cannot adopt C11 standard because we could > > just > > > > do away with the bit suffixes entirely. > > > > > > We could but the project needs to support older RHEL releases > > > which have older tool sets. Though probably this is moot point given > > > how much meson seems to change. > > > > True, though meson tends to be a bit easier to update than GCC on a > > system > > - no "pip3 install --upgrade gcc", sadly :-) > > > > If we can't go all the way to C11 support, how about at least going to > > C99 > > support? As far as I know DPDK has never updated its minimum C-standard > > version, and it might be a good idea to start the process of doing so, > > even > > if it is a baby step. I am in favor of this baby step: define -std=c99 porject-wise and see what are the effects during the year. > The DPDK Getting Started Guide [1] says: > > "Required Tools and Libraries: > [...] > a supported C compiler such as gcc (version 4.9+)" > > GCC version 4.9 supports C11 [2]: > "GCC 4.9 Changes: "ISO C11 support is now at a similar level of completeness to ISO C99 support [...]" > > So why are we not going to support C11? We should make a plan to switch to C11 during next year. > Probably because of RHEL 7, which only provides GCC 4.8 [3]. > > RHEL 7 was released for GA on June 10, 2014 [4]. If someone has a server with a nine year old distro still used in production, it is probably because it is running some legacy application, which is difficult to get up and running on a newer distro. Partial conclusion: RHEL 7 is probably still widely used in production. > > However, I have a hard time understanding why anyone would build and/or deploy a brand new DPDK application (based on DPDK 23.03) on such a server. Can someone please justify this? > > Are we really going to postpone C11 support in DPDK until June 30, 2026, when RHEL 7 ends its Extended Life Cycle Support [4]? RHEL does its own choices to support old software for long. Upstream development should move forward. > If so, then the GCC version mentioned in the DPDK Getting Started Guide should be corrected accordingly. No let's keep GCC 4.9 as a minimum for now. If needed we could upgrade it later. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-06 13:40 ` Thomas Monjalon @ 2023-01-06 18:58 ` Tyler Retzlaff 2023-01-06 20:51 ` Thomas Monjalon 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-06 18:58 UTC (permalink / raw) To: Thomas Monjalon Cc: Bruce Richardson, Stephen Hemminger, david.marchand, dev, Morten Brørup, honnappa.nagarahalli, jerinj, ktraynor, maxime.coquelin On Fri, Jan 06, 2023 at 02:40:59PM +0100, Thomas Monjalon wrote: > 06/01/2023 13:41, Morten Brørup: > > > From: Bruce Richardson [mailto:bruce.richardson@intel.com] > > > Sent: Friday, 6 January 2023 12.48 > > > > > > On Thu, Jan 05, 2023 at 04:32:40PM -0800, Stephen Hemminger wrote: > > > > On Thu, 5 Jan 2023 09:21:18 -0800 > > > > Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > > > > > > > > On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: > > > > > > 05/01/2023 08:09, Morten Brørup: > > > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > > > +/** > > > > > > > > + * @warning > > > > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, > > > without prior > > > > > > > > notice > > > > > > > > + * > > > > > > > > + * Get the count of leading 0-bits in v. > > > > > > > > + * > > > > > > > > + * @param v > > > > > > > > + * The value. > > > > > > > > + * @return > > > > > > > > + * The count of leading zero bits. > > > > > > > > + */ > > > > > > > > +__rte_experimental > > > > > > > > +static inline unsigned int > > > > > > > > +rte_clzl(unsigned long v) > > > > > > > > > > > > > > Don't use l (long) and ll (long long) for names (and types), > > > use explicit bit lengths, 32 and 64. > > > > > > > > > > > > > > E.g.: rte_clz32(uint32_t v) > > > > > > > > > > > > I agree on using numbers. > > > > > > > > > > > > > > > > love the idea, fewer functions too. > > > > > > > > > > though it is a shame we cannot adopt C11 standard because we could > > > just > > > > > do away with the bit suffixes entirely. > > > > > > > > We could but the project needs to support older RHEL releases > > > > which have older tool sets. Though probably this is moot point given > > > > how much meson seems to change. > > > > > > True, though meson tends to be a bit easier to update than GCC on a > > > system > > > - no "pip3 install --upgrade gcc", sadly :-) > > > > > > If we can't go all the way to C11 support, how about at least going to > > > C99 > > > support? As far as I know DPDK has never updated its minimum C-standard > > > version, and it might be a good idea to start the process of doing so, > > > even > > > if it is a baby step. > > I am in favor of this baby step: define -std=c99 porject-wise > and see what are the effects during the year. > > > > The DPDK Getting Started Guide [1] says: > > > > "Required Tools and Libraries: > > [...] > > a supported C compiler such as gcc (version 4.9+)" > > > > GCC version 4.9 supports C11 [2]: > > "GCC 4.9 Changes: "ISO C11 support is now at a similar level of completeness to ISO C99 support [...]" > > > > So why are we not going to support C11? > > We should make a plan to switch to C11 during next year. > > > > Probably because of RHEL 7, which only provides GCC 4.8 [3]. > > > > RHEL 7 was released for GA on June 10, 2014 [4]. If someone has a server with a nine year old distro still used in production, it is probably because it is running some legacy application, which is difficult to get up and running on a newer distro. Partial conclusion: RHEL 7 is probably still widely used in production. > > > > However, I have a hard time understanding why anyone would build and/or deploy a brand new DPDK application (based on DPDK 23.03) on such a server. Can someone please justify this? > > > > Are we really going to postpone C11 support in DPDK until June 30, 2026, when RHEL 7 ends its Extended Life Cycle Support [4]? > > RHEL does its own choices to support old software for long. > Upstream development should move forward. > > > > If so, then the GCC version mentioned in the DPDK Getting Started Guide should be corrected accordingly. > > No let's keep GCC 4.9 as a minimum for now. > If needed we could upgrade it later. but i think the point Morten is making is that RHEL 7 gcc is 4.8 and therefore we implicitly no longer support it if we document requiring gcc 4.9. > > so i think the way to do this is through clarification at the next release / ltsc release. starting with dpdk 23.xx will require compiler conforming to standard X and optional features / annexes from standard X. anyone building applications targeting that version of dpdk release will need a conforming implementation. from there we just need to take care not to backport any code to stable branches that depend on standard features that exceed the requirements documented for that release. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-06 18:58 ` Tyler Retzlaff @ 2023-01-06 20:51 ` Thomas Monjalon 2023-01-10 9:18 ` Ferruh Yigit 0 siblings, 1 reply; 81+ messages in thread From: Thomas Monjalon @ 2023-01-06 20:51 UTC (permalink / raw) To: Tyler Retzlaff Cc: Bruce Richardson, Stephen Hemminger, david.marchand, dev, Morten Brørup, honnappa.nagarahalli, jerinj, ktraynor, maxime.coquelin 06/01/2023 19:58, Tyler Retzlaff: > On Fri, Jan 06, 2023 at 02:40:59PM +0100, Thomas Monjalon wrote: > > 06/01/2023 13:41, Morten Brørup: > > > > From: Bruce Richardson [mailto:bruce.richardson@intel.com] > > > > Sent: Friday, 6 January 2023 12.48 > > > > > > > > On Thu, Jan 05, 2023 at 04:32:40PM -0800, Stephen Hemminger wrote: > > > > > On Thu, 5 Jan 2023 09:21:18 -0800 > > > > > Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > > > > > > > > > > On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: > > > > > > > 05/01/2023 08:09, Morten Brørup: > > > > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > > > > +/** > > > > > > > > > + * @warning > > > > > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, > > > > without prior > > > > > > > > > notice > > > > > > > > > + * > > > > > > > > > + * Get the count of leading 0-bits in v. > > > > > > > > > + * > > > > > > > > > + * @param v > > > > > > > > > + * The value. > > > > > > > > > + * @return > > > > > > > > > + * The count of leading zero bits. > > > > > > > > > + */ > > > > > > > > > +__rte_experimental > > > > > > > > > +static inline unsigned int > > > > > > > > > +rte_clzl(unsigned long v) > > > > > > > > > > > > > > > > Don't use l (long) and ll (long long) for names (and types), > > > > use explicit bit lengths, 32 and 64. > > > > > > > > > > > > > > > > E.g.: rte_clz32(uint32_t v) > > > > > > > > > > > > > > I agree on using numbers. > > > > > > > > > > > > > > > > > > > love the idea, fewer functions too. > > > > > > > > > > > > though it is a shame we cannot adopt C11 standard because we could > > > > just > > > > > > do away with the bit suffixes entirely. > > > > > > > > > > We could but the project needs to support older RHEL releases > > > > > which have older tool sets. Though probably this is moot point given > > > > > how much meson seems to change. > > > > > > > > True, though meson tends to be a bit easier to update than GCC on a > > > > system > > > > - no "pip3 install --upgrade gcc", sadly :-) > > > > > > > > If we can't go all the way to C11 support, how about at least going to > > > > C99 > > > > support? As far as I know DPDK has never updated its minimum C-standard > > > > version, and it might be a good idea to start the process of doing so, > > > > even > > > > if it is a baby step. > > > > I am in favor of this baby step: define -std=c99 porject-wise > > and see what are the effects during the year. > > > > > > > The DPDK Getting Started Guide [1] says: > > > > > > "Required Tools and Libraries: > > > [...] > > > a supported C compiler such as gcc (version 4.9+)" > > > > > > GCC version 4.9 supports C11 [2]: > > > "GCC 4.9 Changes: "ISO C11 support is now at a similar level of completeness to ISO C99 support [...]" > > > > > > So why are we not going to support C11? > > > > We should make a plan to switch to C11 during next year. > > > > > > > Probably because of RHEL 7, which only provides GCC 4.8 [3]. > > > > > > RHEL 7 was released for GA on June 10, 2014 [4]. If someone has a server with a nine year old distro still used in production, it is probably because it is running some legacy application, which is difficult to get up and running on a newer distro. Partial conclusion: RHEL 7 is probably still widely used in production. > > > > > > However, I have a hard time understanding why anyone would build and/or deploy a brand new DPDK application (based on DPDK 23.03) on such a server. Can someone please justify this? > > > > > > Are we really going to postpone C11 support in DPDK until June 30, 2026, when RHEL 7 ends its Extended Life Cycle Support [4]? > > > > RHEL does its own choices to support old software for long. > > Upstream development should move forward. > > > > > > > If so, then the GCC version mentioned in the DPDK Getting Started Guide should be corrected accordingly. > > > > No let's keep GCC 4.9 as a minimum for now. > > If needed we could upgrade it later. > > but i think the point Morten is making is that RHEL 7 gcc is 4.8 and > therefore we implicitly no longer support it if we document requiring > gcc 4.9. Yes I got it. I think everything in DPDK works on RHEL 7 today, but I believe RHEL 7 is not a strong requirement anymore for the mainline. Asking for confirmation here. > so i think the way to do this is through clarification at the next > release / ltsc release. starting with dpdk 23.xx will require > compiler conforming to standard X and optional features / annexes from > standard X. anyone building applications targeting that version of dpdk > release will need a conforming implementation. > > from there we just need to take care not to backport any code to > stable branches that depend on standard features that exceed the > requirements documented for that release. We could even start testing C99 requirement in 23.03 I think. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-06 20:51 ` Thomas Monjalon @ 2023-01-10 9:18 ` Ferruh Yigit 0 siblings, 0 replies; 81+ messages in thread From: Ferruh Yigit @ 2023-01-10 9:18 UTC (permalink / raw) To: Thomas Monjalon, Tyler Retzlaff Cc: Bruce Richardson, Stephen Hemminger, david.marchand, dev, Morten Brørup, honnappa.nagarahalli, jerinj, ktraynor, maxime.coquelin On 1/6/2023 8:51 PM, Thomas Monjalon wrote: > 06/01/2023 19:58, Tyler Retzlaff: >> On Fri, Jan 06, 2023 at 02:40:59PM +0100, Thomas Monjalon wrote: >>> 06/01/2023 13:41, Morten Brørup: >>>>> From: Bruce Richardson [mailto:bruce.richardson@intel.com] >>>>> Sent: Friday, 6 January 2023 12.48 >>>>> >>>>> On Thu, Jan 05, 2023 at 04:32:40PM -0800, Stephen Hemminger wrote: >>>>>> On Thu, 5 Jan 2023 09:21:18 -0800 >>>>>> Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: >>>>>> >>>>>>> On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: >>>>>>>> 05/01/2023 08:09, Morten Brørup: >>>>>>>>>> From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] >>>>>>>>>> +/** >>>>>>>>>> + * @warning >>>>>>>>>> + * @b EXPERIMENTAL: this API may change, or be removed, >>>>> without prior >>>>>>>>>> notice >>>>>>>>>> + * >>>>>>>>>> + * Get the count of leading 0-bits in v. >>>>>>>>>> + * >>>>>>>>>> + * @param v >>>>>>>>>> + * The value. >>>>>>>>>> + * @return >>>>>>>>>> + * The count of leading zero bits. >>>>>>>>>> + */ >>>>>>>>>> +__rte_experimental >>>>>>>>>> +static inline unsigned int >>>>>>>>>> +rte_clzl(unsigned long v) >>>>>>>>> >>>>>>>>> Don't use l (long) and ll (long long) for names (and types), >>>>> use explicit bit lengths, 32 and 64. >>>>>>>>> >>>>>>>>> E.g.: rte_clz32(uint32_t v) >>>>>>>> >>>>>>>> I agree on using numbers. >>>>>>>> >>>>>>> >>>>>>> love the idea, fewer functions too. >>>>>>> >>>>>>> though it is a shame we cannot adopt C11 standard because we could >>>>> just >>>>>>> do away with the bit suffixes entirely. >>>>>> >>>>>> We could but the project needs to support older RHEL releases >>>>>> which have older tool sets. Though probably this is moot point given >>>>>> how much meson seems to change. >>>>> >>>>> True, though meson tends to be a bit easier to update than GCC on a >>>>> system >>>>> - no "pip3 install --upgrade gcc", sadly :-) >>>>> >>>>> If we can't go all the way to C11 support, how about at least going to >>>>> C99 >>>>> support? As far as I know DPDK has never updated its minimum C-standard >>>>> version, and it might be a good idea to start the process of doing so, >>>>> even >>>>> if it is a baby step. >>> >>> I am in favor of this baby step: define -std=c99 porject-wise >>> and see what are the effects during the year. >>> >>> >>>> The DPDK Getting Started Guide [1] says: >>>> >>>> "Required Tools and Libraries: >>>> [...] >>>> a supported C compiler such as gcc (version 4.9+)" >>>> >>>> GCC version 4.9 supports C11 [2]: >>>> "GCC 4.9 Changes: "ISO C11 support is now at a similar level of completeness to ISO C99 support [...]" >>>> >>>> So why are we not going to support C11? >>> >>> We should make a plan to switch to C11 during next year. >>> >>> >>>> Probably because of RHEL 7, which only provides GCC 4.8 [3]. >>>> >>>> RHEL 7 was released for GA on June 10, 2014 [4]. If someone has a server with a nine year old distro still used in production, it is probably because it is running some legacy application, which is difficult to get up and running on a newer distro. Partial conclusion: RHEL 7 is probably still widely used in production. >>>> >>>> However, I have a hard time understanding why anyone would build and/or deploy a brand new DPDK application (based on DPDK 23.03) on such a server. Can someone please justify this? >>>> >>>> Are we really going to postpone C11 support in DPDK until June 30, 2026, when RHEL 7 ends its Extended Life Cycle Support [4]? >>> >>> RHEL does its own choices to support old software for long. >>> Upstream development should move forward. >>> >>> >>>> If so, then the GCC version mentioned in the DPDK Getting Started Guide should be corrected accordingly. >>> >>> No let's keep GCC 4.9 as a minimum for now. >>> If needed we could upgrade it later. >> >> but i think the point Morten is making is that RHEL 7 gcc is 4.8 and >> therefore we implicitly no longer support it if we document requiring >> gcc 4.9. > > Yes I got it. > I think everything in DPDK works on RHEL 7 today, > but I believe RHEL 7 is not a strong requirement anymore for the mainline. > Asking for confirmation here. > >> so i think the way to do this is through clarification at the next >> release / ltsc release. starting with dpdk 23.xx will require >> compiler conforming to standard X and optional features / annexes from >> standard X. anyone building applications targeting that version of dpdk >> release will need a conforming implementation. >> >> from there we just need to take care not to backport any code to >> stable branches that depend on standard features that exceed the >> requirements documented for that release. > > We could even start testing C99 requirement in 23.03 I think. > > I missed discussion in this thread, but replied in other thread, replying here too. +1 to switch C99 support. There are bunch of C99 features used within DPDK already, and there were some drivers compiled with c89 support, that restriction is removed now, so it should be OK to move to C99 support. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-06 11:48 ` Bruce Richardson 2023-01-06 12:41 ` Morten Brørup @ 2023-01-06 18:47 ` Tyler Retzlaff 2023-01-09 8:50 ` Bruce Richardson 1 sibling, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-06 18:47 UTC (permalink / raw) To: Bruce Richardson Cc: Stephen Hemminger, Thomas Monjalon, Morten Brørup, dev, david.marchand On Fri, Jan 06, 2023 at 11:48:17AM +0000, Bruce Richardson wrote: > On Thu, Jan 05, 2023 at 04:32:40PM -0800, Stephen Hemminger wrote: > > On Thu, 5 Jan 2023 09:21:18 -0800 > > Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > > > > On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: > > > > 05/01/2023 08:09, Morten Brørup: > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > +/** > > > > > > + * @warning > > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > > > notice > > > > > > + * > > > > > > + * Get the count of leading 0-bits in v. > > > > > > + * > > > > > > + * @param v > > > > > > + * The value. > > > > > > + * @return > > > > > > + * The count of leading zero bits. > > > > > > + */ > > > > > > +__rte_experimental > > > > > > +static inline unsigned int > > > > > > +rte_clzl(unsigned long v) > > > > > > > > > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > > > > > > > > > E.g.: rte_clz32(uint32_t v) > > > > > > > > I agree on using numbers. > > > > > > > > > > love the idea, fewer functions too. > > > > > > though it is a shame we cannot adopt C11 standard because we could just > > > do away with the bit suffixes entirely. > > > > We could but the project needs to support older RHEL releases > > which have older tool sets. Though probably this is moot point given > > how much meson seems to change. > > True, though meson tends to be a bit easier to update than GCC on a system > - no "pip3 install --upgrade gcc", sadly :-) * on linux. :) > > If we can't go all the way to C11 support, how about at least going to C99 > support? As far as I know DPDK has never updated its minimum C-standard > version, and it might be a good idea to start the process of doing so, even > if it is a baby step. the thing that blurs the line a bit is how the gcc version that is holding us back does actually allow the use of some C99 optional features. for example we use the C99 fixed width integer types so technically some of the code already requires C99. i also notice at least one driver is explicitly specifying -std=gnu99 so maybe that driver just isn't being built when the old gcc is detected? anyway, i think we are stuck pre-c99 so long as we have RHEL 7 to contend with. the rationale is if we could use a compiler conforming to the new standard we could just directly use those features, but so long as we have to support non conforming compiler at a particular level we have to introduce an abstraction and that is where all the extra work comes from. a prominent example is atomics from C11, but for other reasons in our code base that i won't go into even if we required C11 we would still need to abstract atomics. fwiw i'm working on this patch series now and hope to provide a first draft in the next week or two. finally, i do think it would be good to document a minimum C compiler conformance level rather than specific gcc versions. though i admit we also have a hard dependency on gcc right now. my goal is to improve portability to a level where we could just state "you need a C<N> compliant compiler" (or as close to it as possible). ty ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-06 18:47 ` Tyler Retzlaff @ 2023-01-09 8:50 ` Bruce Richardson 0 siblings, 0 replies; 81+ messages in thread From: Bruce Richardson @ 2023-01-09 8:50 UTC (permalink / raw) To: Tyler Retzlaff Cc: Stephen Hemminger, Thomas Monjalon, Morten Brørup, dev, david.marchand On Fri, Jan 06, 2023 at 10:47:06AM -0800, Tyler Retzlaff wrote: > On Fri, Jan 06, 2023 at 11:48:17AM +0000, Bruce Richardson wrote: > > On Thu, Jan 05, 2023 at 04:32:40PM -0800, Stephen Hemminger wrote: > > > On Thu, 5 Jan 2023 09:21:18 -0800 > > > Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > > > > > > On Thu, Jan 05, 2023 at 10:01:31AM +0100, Thomas Monjalon wrote: > > > > > 05/01/2023 08:09, Morten Brørup: > > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > > +/** > > > > > > > + * @warning > > > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > > > > notice > > > > > > > + * > > > > > > > + * Get the count of leading 0-bits in v. > > > > > > > + * > > > > > > > + * @param v > > > > > > > + * The value. > > > > > > > + * @return > > > > > > > + * The count of leading zero bits. > > > > > > > + */ > > > > > > > +__rte_experimental > > > > > > > +static inline unsigned int > > > > > > > +rte_clzl(unsigned long v) > > > > > > > > > > > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > > > > > > > > > > > E.g.: rte_clz32(uint32_t v) > > > > > > > > > > I agree on using numbers. > > > > > > > > > > > > > love the idea, fewer functions too. > > > > > > > > though it is a shame we cannot adopt C11 standard because we could just > > > > do away with the bit suffixes entirely. > > > > > > We could but the project needs to support older RHEL releases > > > which have older tool sets. Though probably this is moot point given > > > how much meson seems to change. > > > > True, though meson tends to be a bit easier to update than GCC on a system > > - no "pip3 install --upgrade gcc", sadly :-) > > * on linux. :) > > > > > If we can't go all the way to C11 support, how about at least going to C99 > > support? As far as I know DPDK has never updated its minimum C-standard > > version, and it might be a good idea to start the process of doing so, even > > if it is a baby step. > > the thing that blurs the line a bit is how the gcc version that is > holding us back does actually allow the use of some C99 optional > features. for example we use the C99 fixed width integer types so > technically some of the code already requires C99. > > i also notice at least one driver is explicitly specifying -std=gnu99 so > maybe that driver just isn't being built when the old gcc is detected? > > anyway, i think we are stuck pre-c99 so long as we have RHEL 7 to > contend with. the rationale is if we could use a compiler conforming to > the new standard we could just directly use those features, but so long > as we have to support non conforming compiler at a particular level we > have to introduce an abstraction and that is where all the extra work > comes from. > AFAIK the gcc 4.8 compiler on RHEL 7/Centos 7 does support C99, it's just missing full support for C11 (which comes in 4.9). Therefore I see using C99 as hopefully being unproblematic, and allowing us to try moving forward revision and seeing what issues - if any - we hit. It should also allow us to put in place infrastructure to support such version changes, since, for example, we likely need to ensure that our headers still work with C90 compilation. /Bruce ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-01-05 7:09 ` Morten Brørup 2023-01-05 9:01 ` Thomas Monjalon @ 2023-04-04 21:23 ` Tyler Retzlaff 2023-04-05 8:44 ` Bruce Richardson 1 sibling, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-04 21:23 UTC (permalink / raw) To: Morten Brørup; +Cc: dev, david.marchand, thomas On Thu, Jan 05, 2023 at 08:09:19AM +0100, Morten Brørup wrote: > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > Sent: Thursday, 24 November 2022 00.43 > > > > Provide an abstraction for leading and trailing zero bit counting > > functions to hide compiler specific intrinsics and builtins. > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > --- > > lib/eal/include/meson.build | 1 + > > lib/eal/include/rte_bitcount.h | 265 > > +++++++++++++++++++++++++++++++++++++++++ > > 2 files changed, 266 insertions(+) > > create mode 100644 lib/eal/include/rte_bitcount.h > > > > diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build > > index cfcd40a..8ff1d65 100644 > > --- a/lib/eal/include/meson.build > > +++ b/lib/eal/include/meson.build > > @@ -5,6 +5,7 @@ includes += include_directories('.') > > > > headers += files( > > 'rte_alarm.h', > > + 'rte_bitcount.h', > > 'rte_bitmap.h', > > 'rte_bitops.h', > > 'rte_branch_prediction.h', > > diff --git a/lib/eal/include/rte_bitcount.h > > b/lib/eal/include/rte_bitcount.h > > new file mode 100644 > > index 0000000..587de52 > > --- /dev/null > > +++ b/lib/eal/include/rte_bitcount.h > > @@ -0,0 +1,265 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (C) 2022 Microsoft Corporation > > + */ > > + > > +#ifndef _RTE_BITCOUNT_H_ > > +#define _RTE_BITCOUNT_H_ > > + > > +#include <rte_compat.h> > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +#ifdef RTE_TOOLCHAIN_MSVC > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > notice > > + * > > + * Get the count of leading 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of leading zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_clz(unsigned int v) > > +{ > > + unsigned long rv; > > + > > + (void)_BitScanReverse(&rv, v); > > + > > + return (unsigned int)rv; > > +} > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > notice > > + * > > + * Get the count of leading 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of leading zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_clzl(unsigned long v) > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > E.g.: rte_clz32(uint32_t v) so i just noticed this, but sometimes these functions receive size_t so naming them specifically 32/64 bit becomes problematic because are going to end up with promotion on sizeof(size_t) == sizeof(long) == 4 platforms. i.e. size_t s = ...; x = rte_clz64(s); // assume 64-bit today this code is now broken because on 32-bit platform s will get promoted and the extra 32 zero-bits will be returned in the result breaking calculations. any thoughts? should we go back to l, ll? ty ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-04-04 21:23 ` Tyler Retzlaff @ 2023-04-05 8:44 ` Bruce Richardson 2023-04-05 15:22 ` Tyler Retzlaff 0 siblings, 1 reply; 81+ messages in thread From: Bruce Richardson @ 2023-04-05 8:44 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: Morten Brørup, dev, david.marchand, thomas On Tue, Apr 04, 2023 at 02:23:22PM -0700, Tyler Retzlaff wrote: > On Thu, Jan 05, 2023 at 08:09:19AM +0100, Morten Brørup wrote: > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > functions to hide compiler specific intrinsics and builtins. > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > --- > > > lib/eal/include/meson.build | 1 + > > > lib/eal/include/rte_bitcount.h | 265 > > > +++++++++++++++++++++++++++++++++++++++++ > > > 2 files changed, 266 insertions(+) > > > create mode 100644 lib/eal/include/rte_bitcount.h > > > > > > diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build > > > index cfcd40a..8ff1d65 100644 > > > --- a/lib/eal/include/meson.build > > > +++ b/lib/eal/include/meson.build > > > @@ -5,6 +5,7 @@ includes += include_directories('.') > > > > > > headers += files( > > > 'rte_alarm.h', > > > + 'rte_bitcount.h', > > > 'rte_bitmap.h', > > > 'rte_bitops.h', > > > 'rte_branch_prediction.h', > > > diff --git a/lib/eal/include/rte_bitcount.h > > > b/lib/eal/include/rte_bitcount.h > > > new file mode 100644 > > > index 0000000..587de52 > > > --- /dev/null > > > +++ b/lib/eal/include/rte_bitcount.h > > > @@ -0,0 +1,265 @@ > > > +/* SPDX-License-Identifier: BSD-3-Clause > > > + * Copyright (C) 2022 Microsoft Corporation > > > + */ > > > + > > > +#ifndef _RTE_BITCOUNT_H_ > > > +#define _RTE_BITCOUNT_H_ > > > + > > > +#include <rte_compat.h> > > > + > > > +#ifdef __cplusplus > > > +extern "C" { > > > +#endif > > > + > > > +#ifdef RTE_TOOLCHAIN_MSVC > > > + > > > +/** > > > + * @warning > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > notice > > > + * > > > + * Get the count of leading 0-bits in v. > > > + * > > > + * @param v > > > + * The value. > > > + * @return > > > + * The count of leading zero bits. > > > + */ > > > +__rte_experimental > > > +static inline unsigned int > > > +rte_clz(unsigned int v) > > > +{ > > > + unsigned long rv; > > > + > > > + (void)_BitScanReverse(&rv, v); > > > + > > > + return (unsigned int)rv; > > > +} > > > + > > > +/** > > > + * @warning > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > notice > > > + * > > > + * Get the count of leading 0-bits in v. > > > + * > > > + * @param v > > > + * The value. > > > + * @return > > > + * The count of leading zero bits. > > > + */ > > > +__rte_experimental > > > +static inline unsigned int > > > +rte_clzl(unsigned long v) > > > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > > > E.g.: rte_clz32(uint32_t v) > > so i just noticed this, but sometimes these functions receive size_t so > naming them specifically 32/64 bit becomes problematic because are going > to end up with promotion on sizeof(size_t) == sizeof(long) == 4 > platforms. > > i.e. > size_t s = ...; > x = rte_clz64(s); // assume 64-bit today > > this code is now broken because on 32-bit platform s will get promoted > and the extra 32 zero-bits will be returned in the result breaking > calculations. > > any thoughts? should we go back to l, ll? > Yes, promotion will happen, but I still think that the 32 and 64 versions are far clearer here in all cases. Anyone looking at the code will recognise that the result will be the leading zero count of a 64-bit number irrespective of the type actually passed in. It's less confusing now IMHO. /Bruce ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-04-05 8:44 ` Bruce Richardson @ 2023-04-05 15:22 ` Tyler Retzlaff 2023-04-05 15:51 ` Bruce Richardson 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-05 15:22 UTC (permalink / raw) To: Bruce Richardson; +Cc: Morten Brørup, dev, david.marchand, thomas On Wed, Apr 05, 2023 at 09:44:54AM +0100, Bruce Richardson wrote: > On Tue, Apr 04, 2023 at 02:23:22PM -0700, Tyler Retzlaff wrote: > > On Thu, Jan 05, 2023 at 08:09:19AM +0100, Morten Brørup wrote: > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > > functions to hide compiler specific intrinsics and builtins. > > > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > > --- > > > > lib/eal/include/meson.build | 1 + > > > > lib/eal/include/rte_bitcount.h | 265 > > > > +++++++++++++++++++++++++++++++++++++++++ > > > > 2 files changed, 266 insertions(+) > > > > create mode 100644 lib/eal/include/rte_bitcount.h > > > > > > > > diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build > > > > index cfcd40a..8ff1d65 100644 > > > > --- a/lib/eal/include/meson.build > > > > +++ b/lib/eal/include/meson.build > > > > @@ -5,6 +5,7 @@ includes += include_directories('.') > > > > > > > > headers += files( > > > > 'rte_alarm.h', > > > > + 'rte_bitcount.h', > > > > 'rte_bitmap.h', > > > > 'rte_bitops.h', > > > > 'rte_branch_prediction.h', > > > > diff --git a/lib/eal/include/rte_bitcount.h > > > > b/lib/eal/include/rte_bitcount.h > > > > new file mode 100644 > > > > index 0000000..587de52 > > > > --- /dev/null > > > > +++ b/lib/eal/include/rte_bitcount.h > > > > @@ -0,0 +1,265 @@ > > > > +/* SPDX-License-Identifier: BSD-3-Clause > > > > + * Copyright (C) 2022 Microsoft Corporation > > > > + */ > > > > + > > > > +#ifndef _RTE_BITCOUNT_H_ > > > > +#define _RTE_BITCOUNT_H_ > > > > + > > > > +#include <rte_compat.h> > > > > + > > > > +#ifdef __cplusplus > > > > +extern "C" { > > > > +#endif > > > > + > > > > +#ifdef RTE_TOOLCHAIN_MSVC > > > > + > > > > +/** > > > > + * @warning > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > notice > > > > + * > > > > + * Get the count of leading 0-bits in v. > > > > + * > > > > + * @param v > > > > + * The value. > > > > + * @return > > > > + * The count of leading zero bits. > > > > + */ > > > > +__rte_experimental > > > > +static inline unsigned int > > > > +rte_clz(unsigned int v) > > > > +{ > > > > + unsigned long rv; > > > > + > > > > + (void)_BitScanReverse(&rv, v); > > > > + > > > > + return (unsigned int)rv; > > > > +} > > > > + > > > > +/** > > > > + * @warning > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > notice > > > > + * > > > > + * Get the count of leading 0-bits in v. > > > > + * > > > > + * @param v > > > > + * The value. > > > > + * @return > > > > + * The count of leading zero bits. > > > > + */ > > > > +__rte_experimental > > > > +static inline unsigned int > > > > +rte_clzl(unsigned long v) > > > > > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > > > > > E.g.: rte_clz32(uint32_t v) > > > > so i just noticed this, but sometimes these functions receive size_t so > > naming them specifically 32/64 bit becomes problematic because are going > > to end up with promotion on sizeof(size_t) == sizeof(long) == 4 > > platforms. > > > > i.e. > > size_t s = ...; > > x = rte_clz64(s); // assume 64-bit today > > > > this code is now broken because on 32-bit platform s will get promoted > > and the extra 32 zero-bits will be returned in the result breaking > > calculations. > > > > any thoughts? should we go back to l, ll? > > > > Yes, promotion will happen, but I still think that the 32 and 64 versions > are far clearer here in all cases. Anyone looking at the code will > recognise that the result will be the leading zero count of a 64-bit number > irrespective of the type actually passed in. It's less confusing now IMHO. here's an example in the code that would result in a bad calculation or at least i believe so at a glance. switching to rte_clz32() would break on 64-bit since it would truncate. lib/eal/common/malloc_elem.c -log2 = sizeof(size) * 8 - __builtin_clzl(size); +log2 = sizeof(size) * 8 - rte_clz64(size); if i'm right you'd have to conditionally compile at the site. #ifdef 64-bit rte_clz64() #else rte_clz32() #endif and that seems very undesirable. another solution is to defer this change until post 23.07 release (where C11 can be used) and we could then just provide a single generic. with C11 i can provide a single macro that doesn't need 8/16/32/64 suffix. size_t v; n = rte_clz(v); // sizeof(v) doesn't matter. > > /Bruce ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-04-05 15:22 ` Tyler Retzlaff @ 2023-04-05 15:51 ` Bruce Richardson 2023-04-05 17:25 ` Tyler Retzlaff 0 siblings, 1 reply; 81+ messages in thread From: Bruce Richardson @ 2023-04-05 15:51 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: Morten Brørup, dev, david.marchand, thomas On Wed, Apr 05, 2023 at 08:22:16AM -0700, Tyler Retzlaff wrote: > On Wed, Apr 05, 2023 at 09:44:54AM +0100, Bruce Richardson wrote: > > On Tue, Apr 04, 2023 at 02:23:22PM -0700, Tyler Retzlaff wrote: > > > On Thu, Jan 05, 2023 at 08:09:19AM +0100, Morten Brørup wrote: > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > > > functions to hide compiler specific intrinsics and builtins. > > > > > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > > > --- > > > > > lib/eal/include/meson.build | 1 + > > > > > lib/eal/include/rte_bitcount.h | 265 > > > > > +++++++++++++++++++++++++++++++++++++++++ > > > > > 2 files changed, 266 insertions(+) > > > > > create mode 100644 lib/eal/include/rte_bitcount.h > > > > > > > > > > diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build > > > > > index cfcd40a..8ff1d65 100644 > > > > > --- a/lib/eal/include/meson.build > > > > > +++ b/lib/eal/include/meson.build > > > > > @@ -5,6 +5,7 @@ includes += include_directories('.') > > > > > > > > > > headers += files( > > > > > 'rte_alarm.h', > > > > > + 'rte_bitcount.h', > > > > > 'rte_bitmap.h', > > > > > 'rte_bitops.h', > > > > > 'rte_branch_prediction.h', > > > > > diff --git a/lib/eal/include/rte_bitcount.h > > > > > b/lib/eal/include/rte_bitcount.h > > > > > new file mode 100644 > > > > > index 0000000..587de52 > > > > > --- /dev/null > > > > > +++ b/lib/eal/include/rte_bitcount.h > > > > > @@ -0,0 +1,265 @@ > > > > > +/* SPDX-License-Identifier: BSD-3-Clause > > > > > + * Copyright (C) 2022 Microsoft Corporation > > > > > + */ > > > > > + > > > > > +#ifndef _RTE_BITCOUNT_H_ > > > > > +#define _RTE_BITCOUNT_H_ > > > > > + > > > > > +#include <rte_compat.h> > > > > > + > > > > > +#ifdef __cplusplus > > > > > +extern "C" { > > > > > +#endif > > > > > + > > > > > +#ifdef RTE_TOOLCHAIN_MSVC > > > > > + > > > > > +/** > > > > > + * @warning > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > > notice > > > > > + * > > > > > + * Get the count of leading 0-bits in v. > > > > > + * > > > > > + * @param v > > > > > + * The value. > > > > > + * @return > > > > > + * The count of leading zero bits. > > > > > + */ > > > > > +__rte_experimental > > > > > +static inline unsigned int > > > > > +rte_clz(unsigned int v) > > > > > +{ > > > > > + unsigned long rv; > > > > > + > > > > > + (void)_BitScanReverse(&rv, v); > > > > > + > > > > > + return (unsigned int)rv; > > > > > +} > > > > > + > > > > > +/** > > > > > + * @warning > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > > notice > > > > > + * > > > > > + * Get the count of leading 0-bits in v. > > > > > + * > > > > > + * @param v > > > > > + * The value. > > > > > + * @return > > > > > + * The count of leading zero bits. > > > > > + */ > > > > > +__rte_experimental > > > > > +static inline unsigned int > > > > > +rte_clzl(unsigned long v) > > > > > > > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > > > > > > > E.g.: rte_clz32(uint32_t v) > > > > > > so i just noticed this, but sometimes these functions receive size_t so > > > naming them specifically 32/64 bit becomes problematic because are going > > > to end up with promotion on sizeof(size_t) == sizeof(long) == 4 > > > platforms. > > > > > > i.e. > > > size_t s = ...; > > > x = rte_clz64(s); // assume 64-bit today > > > > > > this code is now broken because on 32-bit platform s will get promoted > > > and the extra 32 zero-bits will be returned in the result breaking > > > calculations. > > > > > > any thoughts? should we go back to l, ll? > > > > > > > Yes, promotion will happen, but I still think that the 32 and 64 versions > > are far clearer here in all cases. Anyone looking at the code will > > recognise that the result will be the leading zero count of a 64-bit number > > irrespective of the type actually passed in. It's less confusing now IMHO. > > here's an example in the code that would result in a bad calculation or > at least i believe so at a glance. switching to rte_clz32() would break > on 64-bit since it would truncate. > > lib/eal/common/malloc_elem.c > > -log2 = sizeof(size) * 8 - __builtin_clzl(size); > +log2 = sizeof(size) * 8 - rte_clz64(size); > > if i'm right you'd have to conditionally compile at the site. > > #ifdef 64-bit > rte_clz64() > #else > rte_clz32() > #endif > Why can clz64 not be used in both 32 and 64 bit cases? You know the result will always include zeros in high bits of a 64-bit value, and the result will still fit inside even an 8-bit variable? /Bruce ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction 2023-04-05 15:51 ` Bruce Richardson @ 2023-04-05 17:25 ` Tyler Retzlaff 0 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-05 17:25 UTC (permalink / raw) To: Bruce Richardson; +Cc: Morten Brørup, dev, david.marchand, thomas On Wed, Apr 05, 2023 at 04:51:42PM +0100, Bruce Richardson wrote: > On Wed, Apr 05, 2023 at 08:22:16AM -0700, Tyler Retzlaff wrote: > > On Wed, Apr 05, 2023 at 09:44:54AM +0100, Bruce Richardson wrote: > > > On Tue, Apr 04, 2023 at 02:23:22PM -0700, Tyler Retzlaff wrote: > > > > On Thu, Jan 05, 2023 at 08:09:19AM +0100, Morten Brørup wrote: > > > > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > > > > > > Sent: Thursday, 24 November 2022 00.43 > > > > > > > > > > > > Provide an abstraction for leading and trailing zero bit counting > > > > > > functions to hide compiler specific intrinsics and builtins. > > > > > > > > > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > > > > > --- > > > > > > lib/eal/include/meson.build | 1 + > > > > > > lib/eal/include/rte_bitcount.h | 265 > > > > > > +++++++++++++++++++++++++++++++++++++++++ > > > > > > 2 files changed, 266 insertions(+) > > > > > > create mode 100644 lib/eal/include/rte_bitcount.h > > > > > > > > > > > > diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build > > > > > > index cfcd40a..8ff1d65 100644 > > > > > > --- a/lib/eal/include/meson.build > > > > > > +++ b/lib/eal/include/meson.build > > > > > > @@ -5,6 +5,7 @@ includes += include_directories('.') > > > > > > > > > > > > headers += files( > > > > > > 'rte_alarm.h', > > > > > > + 'rte_bitcount.h', > > > > > > 'rte_bitmap.h', > > > > > > 'rte_bitops.h', > > > > > > 'rte_branch_prediction.h', > > > > > > diff --git a/lib/eal/include/rte_bitcount.h > > > > > > b/lib/eal/include/rte_bitcount.h > > > > > > new file mode 100644 > > > > > > index 0000000..587de52 > > > > > > --- /dev/null > > > > > > +++ b/lib/eal/include/rte_bitcount.h > > > > > > @@ -0,0 +1,265 @@ > > > > > > +/* SPDX-License-Identifier: BSD-3-Clause > > > > > > + * Copyright (C) 2022 Microsoft Corporation > > > > > > + */ > > > > > > + > > > > > > +#ifndef _RTE_BITCOUNT_H_ > > > > > > +#define _RTE_BITCOUNT_H_ > > > > > > + > > > > > > +#include <rte_compat.h> > > > > > > + > > > > > > +#ifdef __cplusplus > > > > > > +extern "C" { > > > > > > +#endif > > > > > > + > > > > > > +#ifdef RTE_TOOLCHAIN_MSVC > > > > > > + > > > > > > +/** > > > > > > + * @warning > > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > > > notice > > > > > > + * > > > > > > + * Get the count of leading 0-bits in v. > > > > > > + * > > > > > > + * @param v > > > > > > + * The value. > > > > > > + * @return > > > > > > + * The count of leading zero bits. > > > > > > + */ > > > > > > +__rte_experimental > > > > > > +static inline unsigned int > > > > > > +rte_clz(unsigned int v) > > > > > > +{ > > > > > > + unsigned long rv; > > > > > > + > > > > > > + (void)_BitScanReverse(&rv, v); > > > > > > + > > > > > > + return (unsigned int)rv; > > > > > > +} > > > > > > + > > > > > > +/** > > > > > > + * @warning > > > > > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior > > > > > > notice > > > > > > + * > > > > > > + * Get the count of leading 0-bits in v. > > > > > > + * > > > > > > + * @param v > > > > > > + * The value. > > > > > > + * @return > > > > > > + * The count of leading zero bits. > > > > > > + */ > > > > > > +__rte_experimental > > > > > > +static inline unsigned int > > > > > > +rte_clzl(unsigned long v) > > > > > > > > > > Don't use l (long) and ll (long long) for names (and types), use explicit bit lengths, 32 and 64. > > > > > > > > > > E.g.: rte_clz32(uint32_t v) > > > > > > > > so i just noticed this, but sometimes these functions receive size_t so > > > > naming them specifically 32/64 bit becomes problematic because are going > > > > to end up with promotion on sizeof(size_t) == sizeof(long) == 4 > > > > platforms. > > > > > > > > i.e. > > > > size_t s = ...; > > > > x = rte_clz64(s); // assume 64-bit today > > > > > > > > this code is now broken because on 32-bit platform s will get promoted > > > > and the extra 32 zero-bits will be returned in the result breaking > > > > calculations. > > > > > > > > any thoughts? should we go back to l, ll? > > > > > > > > > > Yes, promotion will happen, but I still think that the 32 and 64 versions > > > are far clearer here in all cases. Anyone looking at the code will > > > recognise that the result will be the leading zero count of a 64-bit number > > > irrespective of the type actually passed in. It's less confusing now IMHO. > > > > here's an example in the code that would result in a bad calculation or > > at least i believe so at a glance. switching to rte_clz32() would break > > on 64-bit since it would truncate. > > > > lib/eal/common/malloc_elem.c > > > > -log2 = sizeof(size) * 8 - __builtin_clzl(size); > > +log2 = sizeof(size) * 8 - rte_clz64(size); > > > > if i'm right you'd have to conditionally compile at the site. > > > > #ifdef 64-bit > > rte_clz64() > > #else > > rte_clz32() > > #endif > > > > Why can clz64 not be used in both 32 and 64 bit cases? You know the result > will always include zeros in high bits of a 64-bit value, and the result > will still fit inside even an 8-bit variable? of course. doh. sorry for the noise! and thank you as always. > > /Bruce ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v2 2/2] test/bitcount: add bitcount tests 2022-11-23 23:43 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff 2022-11-23 23:43 ` [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2022-11-23 23:43 ` Tyler Retzlaff 2023-01-04 23:46 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff 2023-01-09 17:36 ` [PATCH v4 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 3 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2022-11-23 23:43 UTC (permalink / raw) To: dev; +Cc: Tyler Retzlaff basic unit test of following functions rte_clz rte_clzl rte_clzll rte_ctz rte_ctzl rte_ctzll Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- app/test/meson.build | 2 ++ app/test/test_bitcount.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 app/test/test_bitcount.c diff --git a/app/test/meson.build b/app/test/meson.build index f34d19e..d1277bc 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -13,6 +13,7 @@ test_sources = files( 'test_alarm.c', 'test_atomic.c', 'test_barrier.c', + 'test_bitcount.c', 'test_bitops.c', 'test_bitmap.c', 'test_bpf.c', @@ -160,6 +161,7 @@ test_deps += ['bus_pci', 'bus_vdev'] fast_tests = [ ['acl_autotest', true, true], ['atomic_autotest', false, true], + ['bitcount_autotest', true, true], ['bitmap_autotest', true, true], ['bpf_autotest', true, true], ['bpf_convert_autotest', true, true], diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c new file mode 100644 index 0000000..7b71fdf --- /dev/null +++ b/app/test/test_bitcount.c @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#include <string.h> + +#include <rte_bitcount.h> +#include <rte_debug.h> + +#include "test.h" + +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); + +static int +test_clz(void) +{ + unsigned int v = 1; + RTE_TEST_ASSERT(rte_clz(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_clzl(void) +{ + unsigned long v = 1; + RTE_TEST_ASSERT(rte_clzl(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_clzll(void) +{ + unsigned long long v = 1; + RTE_TEST_ASSERT(rte_clzll(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_ctz(void) +{ + unsigned int v = 2; + RTE_TEST_ASSERT(rte_ctz(v) == 1, "Unexpected count."); + + return 0; +} + +static int +test_ctzl(void) +{ + unsigned long v = 2; + RTE_TEST_ASSERT(rte_ctzl(v) == 1, "Unexpected count."); + + return 0; +} + +static int +test_ctzll(void) +{ + unsigned long long v = 2; + RTE_TEST_ASSERT(rte_ctzll(v) == 1, "Unexpected count."); + + return 0; +} + +static struct unit_test_suite bitcount_test_suite = { + .suite_name = "bitcount autotest", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + TEST_CASE(test_clz), + TEST_CASE(test_clzl), + TEST_CASE(test_clzll), + TEST_CASE(test_ctz), + TEST_CASE(test_ctzl), + TEST_CASE(test_ctzll), + TEST_CASES_END() + } +}; + +static int +test_bitcount(void) +{ + return unit_test_suite_runner(&bitcount_test_suite); +} + +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v2 0/2] eal: provide leading and trailing zero bit count 2022-11-23 23:43 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff 2022-11-23 23:43 ` [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2022-11-23 23:43 ` [PATCH v2 2/2] test/bitcount: add bitcount tests Tyler Retzlaff @ 2023-01-04 23:46 ` Tyler Retzlaff 2023-01-09 17:36 ` [PATCH v4 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 3 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-04 23:46 UTC (permalink / raw) To: dev, david.marchand, thomas hi just adding a few extra folks to the to line to try and get some reviewer attention since this patch has been sitting here for a while. the change is fairly straight forward, would just like to get it cleared. feedback is appreciated! thanks On Wed, Nov 23, 2022 at 03:43:15PM -0800, Tyler Retzlaff wrote: > Provide leading and trailing zero bit count functions to abstract away > compiler specific implementations. > > Include basic unit test for new leading/trailing zero bit count functions. > > v2: > * use unsigned int instead of unsigned (checkpatches) > * match multiple include guard naming convention to rte_common.h > * add explicit extern "C" linkage to rte_bitcount.h > note: not really needed but checkpatches required > * add missing space around '-' > > Tyler Retzlaff (2): > eal: provide leading and trailing zero bit count abstraction > test/bitcount: add bitcount tests > > app/test/meson.build | 2 + > app/test/test_bitcount.c | 92 ++++++++++++++ > lib/eal/include/meson.build | 1 + > lib/eal/include/rte_bitcount.h | 265 +++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 360 insertions(+) > create mode 100644 app/test/test_bitcount.c > create mode 100644 lib/eal/include/rte_bitcount.h > > -- > 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v4 0/2] eal: provide leading and trailing zero bit count abstraction 2022-11-23 23:43 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff ` (2 preceding siblings ...) 2023-01-04 23:46 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff @ 2023-01-09 17:36 ` Tyler Retzlaff 2023-01-09 17:36 ` [PATCH v4 1/2] eal: move bit operation functions from common to bitops header Tyler Retzlaff ` (2 more replies) 3 siblings, 3 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-09 17:36 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, Tyler Retzlaff Move existing bit manipulation, log and npow functions from rte_common.h to rte_bitops.h Provide leading and trailing zero bit count functions to abstract away compiler specific implementations. Include basic unit test for new leading/trailing zero bit count functions. v4: * combine unit test commit into function addition commit v3: * rename to use 32/64 instead of l/ll suffixes * add new functions to rte_bitops.h instead of new header * move other bit functions from rte_common.h to rte_bitops.h v2: * use unsigned int instead of unsigned (checkpatches) * match multiple include guard naming convention to rte_common.h * add explicit extern "C" linkage to rte_bitcount.h note: not really needed but checkpatches required * add missing space around '-' Tyler Retzlaff (2): eal: move bit operation functions from common to bitops header eal: provide leading and trailing zero bit count abstraction app/test/meson.build | 2 + app/test/test_bitcount.c | 71 +++++++ app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 460 ++++++++++++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ------------------------- 6 files changed, 535 insertions(+), 293 deletions(-) create mode 100644 app/test/test_bitcount.c -- Series-acked-by: Morten Brørup <mb@smartsharesystems.com> Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v4 1/2] eal: move bit operation functions from common to bitops header 2023-01-09 17:36 ` [PATCH v4 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2023-01-09 17:36 ` Tyler Retzlaff 2023-01-10 13:56 ` Ferruh Yigit 2023-01-09 17:36 ` [PATCH v4 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-10 13:56 ` [PATCH v4 0/2] " Ferruh Yigit 2 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-09 17:36 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, Tyler Retzlaff Move the following inline functions from rte_common.h to rte_bitops.h rte_combine32ms1b rte_combine64ms1b rte_bsf32 rte_bsf32_safe rte_bsf64 rte_bsf64_safe rte_fls_u32 rte_fls_u64 rte_is_power_of_2 rte_align32pow2 rte_align32prevpow2 rte_align64pow2 rte_align64prevpow2 rte_log2_u32 rte_log2_u64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 292 +++++++++++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ---------------------------------------- 4 files changed, 294 insertions(+), 293 deletions(-) diff --git a/app/test/test_common.c b/app/test/test_common.c index f89e1eb..cf4a2c7 100644 --- a/app/test/test_common.c +++ b/app/test/test_common.c @@ -7,6 +7,7 @@ #include <string.h> #include <math.h> #include <rte_common.h> +#include <rte_bitops.h> #include <rte_hexdump.h> #include <rte_pause.h> diff --git a/lib/eal/common/rte_reciprocal.c b/lib/eal/common/rte_reciprocal.c index 42dfa44..d47dc47 100644 --- a/lib/eal/common/rte_reciprocal.c +++ b/lib/eal/common/rte_reciprocal.c @@ -8,6 +8,7 @@ #include <stdint.h> #include <rte_common.h> +#include <rte_bitops.h> #include "rte_reciprocal.h" diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index f50dbe4..531479e 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -275,6 +275,298 @@ return val & mask; } +/** + * Combines 32b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param x + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint32_t +rte_combine32ms1b(uint32_t x) +{ + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return x; +} + +/** + * Combines 64b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param v + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint64_t +rte_combine64ms1b(uint64_t v) +{ + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + + return v; +} + +/** + * 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 uint32_t +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(uint32_t v, uint32_t *pos) +{ + if (v == 0) + return 0; + + *pos = rte_bsf32(v); + return 1; +} + +/** + * 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 uint32_t +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 32. + * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 + * + * @param x + * The input parameter. + * @return + * The last (most-significant) bit set, or 0 if the input is 0. + */ +static inline uint32_t +rte_fls_u32(uint32_t x) +{ + return (x == 0) ? 0 : 32 - __builtin_clz(x); +} + +/** + * 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 uint32_t +rte_fls_u64(uint64_t x) +{ + return (x == 0) ? 0 : 64 - __builtin_clzll(x); +} + +/*********** Macros to work with powers of 2 ********/ + +/** + * Macro to return 1 if n is a power of 2, 0 otherwise + */ +#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) + +/** + * Returns true if n is a power of 2 + * @param n + * Number to check + * @return 1 if true, 0 otherwise + */ +static inline int +rte_is_power_of_2(uint32_t n) +{ + return n && !(n & (n - 1)); +} + +/** + * Aligns input parameter to the next power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint32_t +rte_align32pow2(uint32_t x) +{ + x--; + x = rte_combine32ms1b(x); + + return x + 1; +} + +/** + * Aligns input parameter to the previous power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint32_t +rte_align32prevpow2(uint32_t x) +{ + x = rte_combine32ms1b(x); + + return x - (x >> 1); +} + +/** + * Aligns 64b input parameter to the next power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint64_t +rte_align64pow2(uint64_t v) +{ + v--; + v = rte_combine64ms1b(v); + + return v + 1; +} + +/** + * Aligns 64b input parameter to the previous power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint64_t +rte_align64prevpow2(uint64_t v) +{ + v = rte_combine64ms1b(v); + + return v - (v >> 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 + * The rounded-up log2 of the input, or 0 if the input is 0. + */ +static inline uint32_t +rte_log2_u32(uint32_t v) +{ + if (v == 0) + return 0; + v = rte_align32pow2(v); + return rte_bsf32(v); +} + +/** + * 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); +} + #ifdef __cplusplus } #endif diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h index 15765b4..c5ad69c 100644 --- a/lib/eal/include/rte_common.h +++ b/lib/eal/include/rte_common.h @@ -471,140 +471,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /** Marker for 8B alignment in a structure. */ __extension__ typedef uint64_t RTE_MARKER64[0]; -/** - * Combines 32b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param x - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint32_t -rte_combine32ms1b(uint32_t x) -{ - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - - return x; -} - -/** - * Combines 64b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param v - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint64_t -rte_combine64ms1b(uint64_t v) -{ - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - - return v; -} - -/*********** Macros to work with powers of 2 ********/ - -/** - * Macro to return 1 if n is a power of 2, 0 otherwise - */ -#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) - -/** - * Returns true if n is a power of 2 - * @param n - * Number to check - * @return 1 if true, 0 otherwise - */ -static inline int -rte_is_power_of_2(uint32_t n) -{ - return n && !(n & (n - 1)); -} - -/** - * Aligns input parameter to the next power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint32_t -rte_align32pow2(uint32_t x) -{ - x--; - x = rte_combine32ms1b(x); - - return x + 1; -} - -/** - * Aligns input parameter to the previous power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint32_t -rte_align32prevpow2(uint32_t x) -{ - x = rte_combine32ms1b(x); - - return x - (x >> 1); -} - -/** - * Aligns 64b input parameter to the next power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint64_t -rte_align64pow2(uint64_t v) -{ - v--; - v = rte_combine64ms1b(v); - - return v + 1; -} - -/** - * Aligns 64b input parameter to the previous power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint64_t -rte_align64prevpow2(uint64_t v) -{ - v = rte_combine64ms1b(v); - - return v - (v >> 1); -} - /*********** Macros for calculating min and max **********/ /** @@ -629,165 +495,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /*********** Other general functions / macros ********/ -/** - * 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 uint32_t -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(uint32_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 - * The rounded-up log2 of the input, or 0 if the input is 0. - */ -static inline uint32_t -rte_log2_u32(uint32_t v) -{ - if (v == 0) - return 0; - v = rte_align32pow2(v); - return rte_bsf32(v); -} - - -/** - * Return the last (most-significant) bit set. - * - * @note The last (most significant) bit is at position 32. - * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 - * - * @param x - * The input parameter. - * @return - * The last (most-significant) bit set, or 0 if the input is 0. - */ -static inline uint32_t -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 uint32_t -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 uint32_t -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. */ #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v4 1/2] eal: move bit operation functions from common to bitops header 2023-01-09 17:36 ` [PATCH v4 1/2] eal: move bit operation functions from common to bitops header Tyler Retzlaff @ 2023-01-10 13:56 ` Ferruh Yigit 0 siblings, 0 replies; 81+ messages in thread From: Ferruh Yigit @ 2023-01-10 13:56 UTC (permalink / raw) To: Tyler Retzlaff, dev; +Cc: thomas, mb, bruce.richardson On 1/9/2023 5:36 PM, Tyler Retzlaff wrote: > Move the following inline functions from rte_common.h to rte_bitops.h > > rte_combine32ms1b > rte_combine64ms1b > rte_bsf32 > rte_bsf32_safe > rte_bsf64 > rte_bsf64_safe > rte_fls_u32 > rte_fls_u64 > rte_is_power_of_2 > rte_align32pow2 > rte_align32prevpow2 > rte_align64pow2 > rte_align64prevpow2 > rte_log2_u32 > rte_log2_u64 > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v4 2/2] eal: provide leading and trailing zero bit count abstraction 2023-01-09 17:36 ` [PATCH v4 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-09 17:36 ` [PATCH v4 1/2] eal: move bit operation functions from common to bitops header Tyler Retzlaff @ 2023-01-09 17:36 ` Tyler Retzlaff 2023-01-10 13:55 ` Ferruh Yigit 2023-01-10 13:56 ` [PATCH v4 0/2] " Ferruh Yigit 2 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-09 17:36 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, Tyler Retzlaff, Tyler Retzlaff From: Tyler Retzlaff <roretzla@microsoft.com> Provide an abstraction for leading and trailing zero bit counting functions to hide compiler specific intrinsics and builtins. Include basic unit test of following functions added. rte_clz32 rte_clz64 rte_ctz32 rte_ctz64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- app/test/meson.build | 2 + app/test/test_bitcount.c | 71 ++++++++++++++++++ lib/eal/include/rte_bitops.h | 168 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 241 insertions(+) create mode 100644 app/test/test_bitcount.c diff --git a/app/test/meson.build b/app/test/meson.build index f34d19e..d1277bc 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -13,6 +13,7 @@ test_sources = files( 'test_alarm.c', 'test_atomic.c', 'test_barrier.c', + 'test_bitcount.c', 'test_bitops.c', 'test_bitmap.c', 'test_bpf.c', @@ -160,6 +161,7 @@ test_deps += ['bus_pci', 'bus_vdev'] fast_tests = [ ['acl_autotest', true, true], ['atomic_autotest', false, true], + ['bitcount_autotest', true, true], ['bitmap_autotest', true, true], ['bpf_autotest', true, true], ['bpf_convert_autotest', true, true], diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c new file mode 100644 index 0000000..36eb05c --- /dev/null +++ b/app/test/test_bitcount.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#include <string.h> + +#include <rte_bitops.h> +#include <rte_debug.h> + +#include "test.h" + +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); + +static int +test_clz32(void) +{ + uint32_t v = 1; + RTE_TEST_ASSERT(rte_clz32(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_clz64(void) +{ + uint64_t v = 1; + RTE_TEST_ASSERT(rte_clz64(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_ctz32(void) +{ + uint32_t v = 2; + RTE_TEST_ASSERT(rte_ctz32(v) == 1, "Unexpected count."); + + return 0; +} + +static int +test_ctz64(void) +{ + uint64_t v = 2; + RTE_TEST_ASSERT(rte_ctz64(v) == 1, "Unexpected count."); + + return 0; +} + +static struct unit_test_suite bitcount_test_suite = { + .suite_name = "bitcount autotest", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + TEST_CASE(test_clz32), + TEST_CASE(test_clz64), + TEST_CASE(test_ctz32), + TEST_CASE(test_ctz64), + TEST_CASES_END() + } +}; + +static int +test_bitcount(void) +{ + return unit_test_suite_runner(&bitcount_test_suite); +} + +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index 531479e..387d7aa 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2020 Arm Limited + * Copyright(c) 2010-2019 Intel Corporation + * Copyright(c) 2023 Microsoft Corporation */ #ifndef _RTE_BITOPS_H_ @@ -275,6 +277,172 @@ return val & mask; } +#ifdef RTE_TOOLCHAIN_MSVC + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanReverse64(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanForward64(&rv, v); + + return (unsigned int)rv; +} + +#else + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + return (unsigned int)__builtin_clz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + return (unsigned int)__builtin_clzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + return (unsigned int)__builtin_ctz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + return (unsigned int)__builtin_ctzll(v); +} + +#endif + /** * Combines 32b inputs most significant set bits into the least * significant bits to construct a value with the same MSBs as x -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v4 2/2] eal: provide leading and trailing zero bit count abstraction 2023-01-09 17:36 ` [PATCH v4 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2023-01-10 13:55 ` Ferruh Yigit 2023-01-10 17:34 ` Tyler Retzlaff 2023-01-10 18:37 ` Tyler Retzlaff 0 siblings, 2 replies; 81+ messages in thread From: Ferruh Yigit @ 2023-01-10 13:55 UTC (permalink / raw) To: Tyler Retzlaff, dev; +Cc: thomas, mb, bruce.richardson, Tyler Retzlaff On 1/9/2023 5:36 PM, Tyler Retzlaff wrote: > From: Tyler Retzlaff <roretzla@microsoft.com> > > Provide an abstraction for leading and trailing zero bit counting > functions to hide compiler specific intrinsics and builtins. > > Include basic unit test of following functions added. > > rte_clz32 > rte_clz64 > rte_ctz32 > rte_ctz64 > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > --- > app/test/meson.build | 2 + > app/test/test_bitcount.c | 71 ++++++++++++++++++ > lib/eal/include/rte_bitops.h | 168 +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 241 insertions(+) > create mode 100644 app/test/test_bitcount.c > > diff --git a/app/test/meson.build b/app/test/meson.build > index f34d19e..d1277bc 100644 > --- a/app/test/meson.build > +++ b/app/test/meson.build > @@ -13,6 +13,7 @@ test_sources = files( > 'test_alarm.c', > 'test_atomic.c', > 'test_barrier.c', > + 'test_bitcount.c', > 'test_bitops.c', > 'test_bitmap.c', > 'test_bpf.c', > @@ -160,6 +161,7 @@ test_deps += ['bus_pci', 'bus_vdev'] > fast_tests = [ > ['acl_autotest', true, true], > ['atomic_autotest', false, true], > + ['bitcount_autotest', true, true], > ['bitmap_autotest', true, true], > ['bpf_autotest', true, true], > ['bpf_convert_autotest', true, true], > diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c > new file mode 100644 > index 0000000..36eb05c > --- /dev/null > +++ b/app/test/test_bitcount.c > @@ -0,0 +1,71 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright (C) 2022 Microsoft Corporation > + */ > + > +#include <string.h> > + > +#include <rte_bitops.h> > +#include <rte_debug.h> > + > +#include "test.h" > + > +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); > + > +static int > +test_clz32(void) > +{ > + uint32_t v = 1; > + RTE_TEST_ASSERT(rte_clz32(v) == sizeof(v) * CHAR_BIT - 1, > + "Unexpected count."); > + > + return 0; > +} > + > +static int > +test_clz64(void) > +{ > + uint64_t v = 1; > + RTE_TEST_ASSERT(rte_clz64(v) == sizeof(v) * CHAR_BIT - 1, > + "Unexpected count."); > + > + return 0; > +} > + > +static int > +test_ctz32(void) > +{ > + uint32_t v = 2; > + RTE_TEST_ASSERT(rte_ctz32(v) == 1, "Unexpected count."); > + > + return 0; > +} > + > +static int > +test_ctz64(void) > +{ > + uint64_t v = 2; > + RTE_TEST_ASSERT(rte_ctz64(v) == 1, "Unexpected count."); > + > + return 0; > +} > + > +static struct unit_test_suite bitcount_test_suite = { > + .suite_name = "bitcount autotest", > + .setup = NULL, > + .teardown = NULL, > + .unit_test_cases = { > + TEST_CASE(test_clz32), > + TEST_CASE(test_clz64), > + TEST_CASE(test_ctz32), > + TEST_CASE(test_ctz64), > + TEST_CASES_END() > + } > +}; > + > +static int > +test_bitcount(void) > +{ > + return unit_test_suite_runner(&bitcount_test_suite); > +} > + > +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); > diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h > index 531479e..387d7aa 100644 > --- a/lib/eal/include/rte_bitops.h > +++ b/lib/eal/include/rte_bitops.h > @@ -1,5 +1,7 @@ > /* SPDX-License-Identifier: BSD-3-Clause > * Copyright(c) 2020 Arm Limited > + * Copyright(c) 2010-2019 Intel Corporation > + * Copyright(c) 2023 Microsoft Corporation > */ > > #ifndef _RTE_BITOPS_H_ > @@ -275,6 +277,172 @@ > return val & mask; > } > > +#ifdef RTE_TOOLCHAIN_MSVC > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_clz32(uint32_t v) > +{ > + unsigned long rv; > + > + (void)_BitScanReverse(&rv, v); > + > + return (unsigned int)rv; > +} OK, this looks wrong to me, '_BitScanReverse' is [1]: "Search the mask data from most significant bit (MSB) to least significant bit (LSB) for a set bit (1)." As far as I can see index starts from zero and from lsb to msb. So _BitScanReverse() returns following index values: 0x2 => 1 0xffffffff => 31 If above is correct, above function doesn't return number of leading zeros, but it should return "31 - (unsigned int)rv". Please check godbolt experiment for above: https://godbolt.org/z/znYn54f57 As far as I can see unit test is correct, so above should fail with windows compiler, and I assume you run unit test with windows compiler, so probably I am missing something but please help me understand. [1] https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64?view=msvc-170 > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_clz64(uint64_t v) > +{ > + unsigned long rv; > + > + (void)_BitScanReverse64(&rv, v); > + > + return (unsigned int)rv; > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_ctz32(uint32_t v) > +{ > + unsigned long rv; > + > + (void)_BitScanForward(&rv, v); > + > + return (unsigned int)rv; > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_ctz64(uint64_t v) > +{ > + unsigned long rv; > + > + (void)_BitScanForward64(&rv, v); > + > + return (unsigned int)rv; > +} > + > +#else > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_clz32(uint32_t v) > +{ > + return (unsigned int)__builtin_clz(v); > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of leading 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of leading zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_clz64(uint64_t v) > +{ > + return (unsigned int)__builtin_clzll(v); > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_ctz32(uint32_t v) > +{ > + return (unsigned int)__builtin_ctz(v); > +} > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > + * > + * Get the count of trailing 0-bits in v. > + * > + * @param v > + * The value. > + * @return > + * The count of trailing zero bits. > + */ > +__rte_experimental > +static inline unsigned int > +rte_ctz64(uint64_t v) > +{ > + return (unsigned int)__builtin_ctzll(v); > +} 'rte_ctz32()' & 'rte_ctz64()' are practically exact same with 'rte_bsf32()' & 'rte_bsf64()', Although I can see description is different, do we need same functionality with new function name, why not add 'rte_bsf32()' & 'rte_bsf64()' versions for the Windows? btw, do you guys know what 'bsf' & 'fls' (rte_fls_u32) stands for? > + > +#endif > + > /** > * Combines 32b inputs most significant set bits into the least > * significant bits to construct a value with the same MSBs as x ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v4 2/2] eal: provide leading and trailing zero bit count abstraction 2023-01-10 13:55 ` Ferruh Yigit @ 2023-01-10 17:34 ` Tyler Retzlaff 2023-01-10 18:37 ` Tyler Retzlaff 1 sibling, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-10 17:34 UTC (permalink / raw) To: Ferruh Yigit; +Cc: dev, thomas, mb, bruce.richardson, Tyler Retzlaff On Tue, Jan 10, 2023 at 01:55:59PM +0000, Ferruh Yigit wrote: > On 1/9/2023 5:36 PM, Tyler Retzlaff wrote: > > From: Tyler Retzlaff <roretzla@microsoft.com> > > > > Provide an abstraction for leading and trailing zero bit counting > > functions to hide compiler specific intrinsics and builtins. > > > > Include basic unit test of following functions added. > > > > rte_clz32 > > rte_clz64 > > rte_ctz32 > > rte_ctz64 > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > --- > > app/test/meson.build | 2 + > > app/test/test_bitcount.c | 71 ++++++++++++++++++ > > lib/eal/include/rte_bitops.h | 168 +++++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 241 insertions(+) > > create mode 100644 app/test/test_bitcount.c > > > > diff --git a/app/test/meson.build b/app/test/meson.build > > index f34d19e..d1277bc 100644 > > --- a/app/test/meson.build > > +++ b/app/test/meson.build > > @@ -13,6 +13,7 @@ test_sources = files( > > 'test_alarm.c', > > 'test_atomic.c', > > 'test_barrier.c', > > + 'test_bitcount.c', > > 'test_bitops.c', > > 'test_bitmap.c', > > 'test_bpf.c', > > @@ -160,6 +161,7 @@ test_deps += ['bus_pci', 'bus_vdev'] > > fast_tests = [ > > ['acl_autotest', true, true], > > ['atomic_autotest', false, true], > > + ['bitcount_autotest', true, true], > > ['bitmap_autotest', true, true], > > ['bpf_autotest', true, true], > > ['bpf_convert_autotest', true, true], > > diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c > > new file mode 100644 > > index 0000000..36eb05c > > --- /dev/null > > +++ b/app/test/test_bitcount.c > > @@ -0,0 +1,71 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (C) 2022 Microsoft Corporation > > + */ > > + > > +#include <string.h> > > + > > +#include <rte_bitops.h> > > +#include <rte_debug.h> > > + > > +#include "test.h" > > + > > +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); > > + > > +static int > > +test_clz32(void) > > +{ > > + uint32_t v = 1; > > + RTE_TEST_ASSERT(rte_clz32(v) == sizeof(v) * CHAR_BIT - 1, > > + "Unexpected count."); > > + > > + return 0; > > +} > > + > > +static int > > +test_clz64(void) > > +{ > > + uint64_t v = 1; > > + RTE_TEST_ASSERT(rte_clz64(v) == sizeof(v) * CHAR_BIT - 1, > > + "Unexpected count."); > > + > > + return 0; > > +} > > + > > +static int > > +test_ctz32(void) > > +{ > > + uint32_t v = 2; > > + RTE_TEST_ASSERT(rte_ctz32(v) == 1, "Unexpected count."); > > + > > + return 0; > > +} > > + > > +static int > > +test_ctz64(void) > > +{ > > + uint64_t v = 2; > > + RTE_TEST_ASSERT(rte_ctz64(v) == 1, "Unexpected count."); > > + > > + return 0; > > +} > > + > > +static struct unit_test_suite bitcount_test_suite = { > > + .suite_name = "bitcount autotest", > > + .setup = NULL, > > + .teardown = NULL, > > + .unit_test_cases = { > > + TEST_CASE(test_clz32), > > + TEST_CASE(test_clz64), > > + TEST_CASE(test_ctz32), > > + TEST_CASE(test_ctz64), > > + TEST_CASES_END() > > + } > > +}; > > + > > +static int > > +test_bitcount(void) > > +{ > > + return unit_test_suite_runner(&bitcount_test_suite); > > +} > > + > > +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); > > diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h > > index 531479e..387d7aa 100644 > > --- a/lib/eal/include/rte_bitops.h > > +++ b/lib/eal/include/rte_bitops.h > > @@ -1,5 +1,7 @@ > > /* SPDX-License-Identifier: BSD-3-Clause > > * Copyright(c) 2020 Arm Limited > > + * Copyright(c) 2010-2019 Intel Corporation > > + * Copyright(c) 2023 Microsoft Corporation > > */ > > > > #ifndef _RTE_BITOPS_H_ > > @@ -275,6 +277,172 @@ > > return val & mask; > > } > > > > +#ifdef RTE_TOOLCHAIN_MSVC > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > > + * > > + * Get the count of leading 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of leading zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_clz32(uint32_t v) > > +{ > > + unsigned long rv; > > + > > + (void)_BitScanReverse(&rv, v); > > + > > + return (unsigned int)rv; > > +} > > > OK, this looks wrong to me, > > > '_BitScanReverse' is [1]: > "Search the mask data from most significant bit (MSB) to least > significant bit (LSB) for a set bit (1)." > > As far as I can see index starts from zero and from lsb to msb. > > So _BitScanReverse() returns following index values: > 0x2 => 1 > 0xffffffff => 31 > > If above is correct, above function doesn't return number of leading > zeros, but it should return "31 - (unsigned int)rv". > > Please check godbolt experiment for above: > https://godbolt.org/z/znYn54f57 > > > As far as I can see unit test is correct, so above should fail with > windows compiler, and I assume you run unit test with windows compiler, > so probably I am missing something but please help me understand. > > > > [1] > https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64?view=msvc-170 > > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > > + * > > + * Get the count of leading 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of leading zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_clz64(uint64_t v) > > +{ > > + unsigned long rv; > > + > > + (void)_BitScanReverse64(&rv, v); > > + > > + return (unsigned int)rv; > > +} > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > > + * > > + * Get the count of trailing 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of trailing zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_ctz32(uint32_t v) > > +{ > > + unsigned long rv; > > + > > + (void)_BitScanForward(&rv, v); > > + > > + return (unsigned int)rv; > > +} > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > > + * > > + * Get the count of trailing 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of trailing zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_ctz64(uint64_t v) > > +{ > > + unsigned long rv; > > + > > + (void)_BitScanForward64(&rv, v); > > + > > + return (unsigned int)rv; > > +} > > + > > +#else > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > > + * > > + * Get the count of leading 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of leading zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_clz32(uint32_t v) > > +{ > > + return (unsigned int)__builtin_clz(v); > > +} > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > > + * > > + * Get the count of leading 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of leading zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_clz64(uint64_t v) > > +{ > > + return (unsigned int)__builtin_clzll(v); > > +} > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > > + * > > + * Get the count of trailing 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of trailing zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_ctz32(uint32_t v) > > +{ > > + return (unsigned int)__builtin_ctz(v); > > +} > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > > + * > > + * Get the count of trailing 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of trailing zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_ctz64(uint64_t v) > > +{ > > + return (unsigned int)__builtin_ctzll(v); > > +} > > 'rte_ctz32()' & 'rte_ctz64()' are practically exact same with > 'rte_bsf32()' & 'rte_bsf64()', > > Although I can see description is different, do we need same > functionality with new function name, > why not add 'rte_bsf32()' & 'rte_bsf64()' versions for the Windows? i agree. i need a consensus from reviewers if they think this series should be changed. if we do take bsf{32,64} instead then does that mean we ban the use of __ctz{32,64} in dpdk? keeping in mind the end goal is portability. > > > > btw, do you guys know what 'bsf' & 'fls' (rte_fls_u32) stands for? no idea. before my time. > > > + > > +#endif > > + > > /** > > * Combines 32b inputs most significant set bits into the least > > * significant bits to construct a value with the same MSBs as x ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v4 2/2] eal: provide leading and trailing zero bit count abstraction 2023-01-10 13:55 ` Ferruh Yigit 2023-01-10 17:34 ` Tyler Retzlaff @ 2023-01-10 18:37 ` Tyler Retzlaff 1 sibling, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-10 18:37 UTC (permalink / raw) To: Ferruh Yigit; +Cc: dev, thomas, mb, bruce.richardson, Tyler Retzlaff On Tue, Jan 10, 2023 at 01:55:59PM +0000, Ferruh Yigit wrote: > On 1/9/2023 5:36 PM, Tyler Retzlaff wrote: > > From: Tyler Retzlaff <roretzla@microsoft.com> > > > > Provide an abstraction for leading and trailing zero bit counting > > functions to hide compiler specific intrinsics and builtins. > > > > Include basic unit test of following functions added. > > > > rte_clz32 > > rte_clz64 > > rte_ctz32 > > rte_ctz64 > > > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > > --- > > app/test/meson.build | 2 + > > app/test/test_bitcount.c | 71 ++++++++++++++++++ > > lib/eal/include/rte_bitops.h | 168 +++++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 241 insertions(+) > > create mode 100644 app/test/test_bitcount.c > > > > diff --git a/app/test/meson.build b/app/test/meson.build > > index f34d19e..d1277bc 100644 > > --- a/app/test/meson.build > > +++ b/app/test/meson.build > > @@ -13,6 +13,7 @@ test_sources = files( > > 'test_alarm.c', > > 'test_atomic.c', > > 'test_barrier.c', > > + 'test_bitcount.c', > > 'test_bitops.c', > > 'test_bitmap.c', > > 'test_bpf.c', > > @@ -160,6 +161,7 @@ test_deps += ['bus_pci', 'bus_vdev'] > > fast_tests = [ > > ['acl_autotest', true, true], > > ['atomic_autotest', false, true], > > + ['bitcount_autotest', true, true], > > ['bitmap_autotest', true, true], > > ['bpf_autotest', true, true], > > ['bpf_convert_autotest', true, true], > > diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c > > new file mode 100644 > > index 0000000..36eb05c > > --- /dev/null > > +++ b/app/test/test_bitcount.c > > @@ -0,0 +1,71 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright (C) 2022 Microsoft Corporation > > + */ > > + > > +#include <string.h> > > + > > +#include <rte_bitops.h> > > +#include <rte_debug.h> > > + > > +#include "test.h" > > + > > +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); > > + > > +static int > > +test_clz32(void) > > +{ > > + uint32_t v = 1; > > + RTE_TEST_ASSERT(rte_clz32(v) == sizeof(v) * CHAR_BIT - 1, > > + "Unexpected count."); > > + > > + return 0; > > +} > > + > > +static int > > +test_clz64(void) > > +{ > > + uint64_t v = 1; > > + RTE_TEST_ASSERT(rte_clz64(v) == sizeof(v) * CHAR_BIT - 1, > > + "Unexpected count."); > > + > > + return 0; > > +} > > + > > +static int > > +test_ctz32(void) > > +{ > > + uint32_t v = 2; > > + RTE_TEST_ASSERT(rte_ctz32(v) == 1, "Unexpected count."); > > + > > + return 0; > > +} > > + > > +static int > > +test_ctz64(void) > > +{ > > + uint64_t v = 2; > > + RTE_TEST_ASSERT(rte_ctz64(v) == 1, "Unexpected count."); > > + > > + return 0; > > +} > > + > > +static struct unit_test_suite bitcount_test_suite = { > > + .suite_name = "bitcount autotest", > > + .setup = NULL, > > + .teardown = NULL, > > + .unit_test_cases = { > > + TEST_CASE(test_clz32), > > + TEST_CASE(test_clz64), > > + TEST_CASE(test_ctz32), > > + TEST_CASE(test_ctz64), > > + TEST_CASES_END() > > + } > > +}; > > + > > +static int > > +test_bitcount(void) > > +{ > > + return unit_test_suite_runner(&bitcount_test_suite); > > +} > > + > > +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); > > diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h > > index 531479e..387d7aa 100644 > > --- a/lib/eal/include/rte_bitops.h > > +++ b/lib/eal/include/rte_bitops.h > > @@ -1,5 +1,7 @@ > > /* SPDX-License-Identifier: BSD-3-Clause > > * Copyright(c) 2020 Arm Limited > > + * Copyright(c) 2010-2019 Intel Corporation > > + * Copyright(c) 2023 Microsoft Corporation > > */ > > > > #ifndef _RTE_BITOPS_H_ > > @@ -275,6 +277,172 @@ > > return val & mask; > > } > > > > +#ifdef RTE_TOOLCHAIN_MSVC > > + > > +/** > > + * @warning > > + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice > > + * > > + * Get the count of leading 0-bits in v. > > + * > > + * @param v > > + * The value. > > + * @return > > + * The count of leading zero bits. > > + */ > > +__rte_experimental > > +static inline unsigned int > > +rte_clz32(uint32_t v) > > +{ > > + unsigned long rv; > > + > > + (void)_BitScanReverse(&rv, v); > > + > > + return (unsigned int)rv; > > +} > > > OK, this looks wrong to me, > > > '_BitScanReverse' is [1]: > "Search the mask data from most significant bit (MSB) to least > significant bit (LSB) for a set bit (1)." > > As far as I can see index starts from zero and from lsb to msb. > > So _BitScanReverse() returns following index values: > 0x2 => 1 > 0xffffffff => 31 > > If above is correct, above function doesn't return number of leading > zeros, but it should return "31 - (unsigned int)rv". > > Please check godbolt experiment for above: > https://godbolt.org/z/znYn54f57 > > > As far as I can see unit test is correct, so above should fail with > windows compiler, and I assume you run unit test with windows compiler, > so probably I am missing something but please help me understand. the test is wrong, i will fix both the test and the implementation. thank you for the careful review. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v4 0/2] eal: provide leading and trailing zero bit count abstraction 2023-01-09 17:36 ` [PATCH v4 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-09 17:36 ` [PATCH v4 1/2] eal: move bit operation functions from common to bitops header Tyler Retzlaff 2023-01-09 17:36 ` [PATCH v4 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2023-01-10 13:56 ` Ferruh Yigit 2 siblings, 0 replies; 81+ messages in thread From: Ferruh Yigit @ 2023-01-10 13:56 UTC (permalink / raw) To: Tyler Retzlaff, dev; +Cc: thomas, mb, bruce.richardson On 1/9/2023 5:36 PM, Tyler Retzlaff wrote: > Move existing bit manipulation, log and npow functions from > rte_common.h to rte_bitops.h > > Provide leading and trailing zero bit count functions to abstract away > compiler specific implementations. > > Include basic unit test for new leading/trailing zero bit count functions. > > v4: > * combine unit test commit into function addition commit > > v3: > * rename to use 32/64 instead of l/ll suffixes > * add new functions to rte_bitops.h instead of new header > * move other bit functions from rte_common.h to rte_bitops.h > > v2: > * use unsigned int instead of unsigned (checkpatches) > * match multiple include guard naming convention to rte_common.h > * add explicit extern "C" linkage to rte_bitcount.h > note: not really needed but checkpatches required > * add missing space around '-' > > Tyler Retzlaff (2): > eal: move bit operation functions from common to bitops header > eal: provide leading and trailing zero bit count abstraction > There are checkpatch / checkgitlog errors, can you please check them: - checkpatches: ### [PATCH] eal: provide leading and trailing zero bit count abstraction WARNING:FROM_SIGN_OFF_MISMATCH: From:/Signed-off-by: email address mismatch: 'From: Tyler Retzlaff <roretzla@microsoft.com>' != 'Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>' total: 0 errors, 1 warnings, 264 lines checked 1/2 valid patch - check-git-log: Headline too long: eal: move bit operation functions from common to bitops header ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v3 0/3] eal: provide leading and trailing zero bit count 2022-11-23 22:14 [PATCH 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff ` (2 preceding siblings ...) 2022-11-23 23:43 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff @ 2023-01-06 22:01 ` Tyler Retzlaff 2023-01-06 22:01 ` [PATCH v3 1/3] eal: move bit functions from common to bitops header Tyler Retzlaff ` (3 more replies) 2023-01-10 19:38 ` [PATCH v5 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff ` (3 subsequent siblings) 7 siblings, 4 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-06 22:01 UTC (permalink / raw) To: dev; +Cc: mb, thomas, david.marchand, Tyler Retzlaff Move existing bit manipulation, log and npow functions from rte_common.h to rte_bitops.h Provide leading and trailing zero bit count functions to abstract away compiler specific implementations. Include basic unit test for new leading/trailing zero bit count functions. v3: * rename to use 32/64 instead of l/ll suffixes * add new functions to rte_bitops.h instead of new header * move other bit functions from rte_common.h to rte_bitops.h v2: * use unsigned int instead of unsigned (checkpatches) * match multiple include guard naming convention to rte_common.h * add explicit extern "C" linkage to rte_bitcount.h note: not really needed but checkpatches required * add missing space around '-' Tyler Retzlaff (3): eal: move bit functions from common to bitops header eal: provide leading and trailing zero bit count abstraction test/bitcount: add bitcount tests app/test/meson.build | 2 + app/test/test_bitcount.c | 71 +++++++ app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 460 ++++++++++++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ------------------------- 6 files changed, 535 insertions(+), 293 deletions(-) create mode 100644 app/test/test_bitcount.c -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v3 1/3] eal: move bit functions from common to bitops header 2023-01-06 22:01 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Tyler Retzlaff @ 2023-01-06 22:01 ` Tyler Retzlaff 2023-01-06 22:01 ` [PATCH v3 2/3] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff ` (2 subsequent siblings) 3 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-06 22:01 UTC (permalink / raw) To: dev; +Cc: mb, thomas, david.marchand, Tyler Retzlaff Move the following inline functions from rte_common.h to rte_bitops.h rte_combine32ms1b rte_combine64ms1b rte_bsf32 rte_bsf32_safe rte_bsf64 rte_bsf64_safe rte_fls_u32 rte_fls_u64 rte_is_power_of_2 rte_align32pow2 rte_align32prevpow2 rte_align64pow2 rte_align64prevpow2 rte_log2_u32 rte_log2_u64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 292 +++++++++++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ---------------------------------------- 4 files changed, 294 insertions(+), 293 deletions(-) diff --git a/app/test/test_common.c b/app/test/test_common.c index f89e1eb..cf4a2c7 100644 --- a/app/test/test_common.c +++ b/app/test/test_common.c @@ -7,6 +7,7 @@ #include <string.h> #include <math.h> #include <rte_common.h> +#include <rte_bitops.h> #include <rte_hexdump.h> #include <rte_pause.h> diff --git a/lib/eal/common/rte_reciprocal.c b/lib/eal/common/rte_reciprocal.c index 42dfa44..d47dc47 100644 --- a/lib/eal/common/rte_reciprocal.c +++ b/lib/eal/common/rte_reciprocal.c @@ -8,6 +8,7 @@ #include <stdint.h> #include <rte_common.h> +#include <rte_bitops.h> #include "rte_reciprocal.h" diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index f50dbe4..531479e 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -275,6 +275,298 @@ return val & mask; } +/** + * Combines 32b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param x + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint32_t +rte_combine32ms1b(uint32_t x) +{ + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return x; +} + +/** + * Combines 64b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param v + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint64_t +rte_combine64ms1b(uint64_t v) +{ + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + + return v; +} + +/** + * 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 uint32_t +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(uint32_t v, uint32_t *pos) +{ + if (v == 0) + return 0; + + *pos = rte_bsf32(v); + return 1; +} + +/** + * 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 uint32_t +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 32. + * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 + * + * @param x + * The input parameter. + * @return + * The last (most-significant) bit set, or 0 if the input is 0. + */ +static inline uint32_t +rte_fls_u32(uint32_t x) +{ + return (x == 0) ? 0 : 32 - __builtin_clz(x); +} + +/** + * 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 uint32_t +rte_fls_u64(uint64_t x) +{ + return (x == 0) ? 0 : 64 - __builtin_clzll(x); +} + +/*********** Macros to work with powers of 2 ********/ + +/** + * Macro to return 1 if n is a power of 2, 0 otherwise + */ +#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) + +/** + * Returns true if n is a power of 2 + * @param n + * Number to check + * @return 1 if true, 0 otherwise + */ +static inline int +rte_is_power_of_2(uint32_t n) +{ + return n && !(n & (n - 1)); +} + +/** + * Aligns input parameter to the next power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint32_t +rte_align32pow2(uint32_t x) +{ + x--; + x = rte_combine32ms1b(x); + + return x + 1; +} + +/** + * Aligns input parameter to the previous power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint32_t +rte_align32prevpow2(uint32_t x) +{ + x = rte_combine32ms1b(x); + + return x - (x >> 1); +} + +/** + * Aligns 64b input parameter to the next power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint64_t +rte_align64pow2(uint64_t v) +{ + v--; + v = rte_combine64ms1b(v); + + return v + 1; +} + +/** + * Aligns 64b input parameter to the previous power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint64_t +rte_align64prevpow2(uint64_t v) +{ + v = rte_combine64ms1b(v); + + return v - (v >> 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 + * The rounded-up log2 of the input, or 0 if the input is 0. + */ +static inline uint32_t +rte_log2_u32(uint32_t v) +{ + if (v == 0) + return 0; + v = rte_align32pow2(v); + return rte_bsf32(v); +} + +/** + * 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); +} + #ifdef __cplusplus } #endif diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h index 15765b4..c5ad69c 100644 --- a/lib/eal/include/rte_common.h +++ b/lib/eal/include/rte_common.h @@ -471,140 +471,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /** Marker for 8B alignment in a structure. */ __extension__ typedef uint64_t RTE_MARKER64[0]; -/** - * Combines 32b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param x - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint32_t -rte_combine32ms1b(uint32_t x) -{ - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - - return x; -} - -/** - * Combines 64b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param v - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint64_t -rte_combine64ms1b(uint64_t v) -{ - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - - return v; -} - -/*********** Macros to work with powers of 2 ********/ - -/** - * Macro to return 1 if n is a power of 2, 0 otherwise - */ -#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) - -/** - * Returns true if n is a power of 2 - * @param n - * Number to check - * @return 1 if true, 0 otherwise - */ -static inline int -rte_is_power_of_2(uint32_t n) -{ - return n && !(n & (n - 1)); -} - -/** - * Aligns input parameter to the next power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint32_t -rte_align32pow2(uint32_t x) -{ - x--; - x = rte_combine32ms1b(x); - - return x + 1; -} - -/** - * Aligns input parameter to the previous power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint32_t -rte_align32prevpow2(uint32_t x) -{ - x = rte_combine32ms1b(x); - - return x - (x >> 1); -} - -/** - * Aligns 64b input parameter to the next power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint64_t -rte_align64pow2(uint64_t v) -{ - v--; - v = rte_combine64ms1b(v); - - return v + 1; -} - -/** - * Aligns 64b input parameter to the previous power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint64_t -rte_align64prevpow2(uint64_t v) -{ - v = rte_combine64ms1b(v); - - return v - (v >> 1); -} - /*********** Macros for calculating min and max **********/ /** @@ -629,165 +495,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /*********** Other general functions / macros ********/ -/** - * 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 uint32_t -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(uint32_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 - * The rounded-up log2 of the input, or 0 if the input is 0. - */ -static inline uint32_t -rte_log2_u32(uint32_t v) -{ - if (v == 0) - return 0; - v = rte_align32pow2(v); - return rte_bsf32(v); -} - - -/** - * Return the last (most-significant) bit set. - * - * @note The last (most significant) bit is at position 32. - * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 - * - * @param x - * The input parameter. - * @return - * The last (most-significant) bit set, or 0 if the input is 0. - */ -static inline uint32_t -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 uint32_t -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 uint32_t -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. */ #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v3 2/3] eal: provide leading and trailing zero bit count abstraction 2023-01-06 22:01 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Tyler Retzlaff 2023-01-06 22:01 ` [PATCH v3 1/3] eal: move bit functions from common to bitops header Tyler Retzlaff @ 2023-01-06 22:01 ` Tyler Retzlaff 2023-01-06 22:01 ` [PATCH v3 3/3] test/bitcount: add bitcount tests Tyler Retzlaff 2023-01-09 8:51 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Bruce Richardson 3 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-06 22:01 UTC (permalink / raw) To: dev; +Cc: mb, thomas, david.marchand, Tyler Retzlaff, Tyler Retzlaff From: Tyler Retzlaff <roretzla@microsoft.com> Provide an abstraction for leading and trailing zero bit counting functions to hide compiler specific intrinsics and builtins. Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- lib/eal/include/rte_bitops.h | 168 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index 531479e..387d7aa 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2020 Arm Limited + * Copyright(c) 2010-2019 Intel Corporation + * Copyright(c) 2023 Microsoft Corporation */ #ifndef _RTE_BITOPS_H_ @@ -275,6 +277,172 @@ return val & mask; } +#ifdef RTE_TOOLCHAIN_MSVC + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanReverse64(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanForward64(&rv, v); + + return (unsigned int)rv; +} + +#else + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + return (unsigned int)__builtin_clz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + return (unsigned int)__builtin_clzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + return (unsigned int)__builtin_ctz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + return (unsigned int)__builtin_ctzll(v); +} + +#endif + /** * Combines 32b inputs most significant set bits into the least * significant bits to construct a value with the same MSBs as x -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v3 3/3] test/bitcount: add bitcount tests 2023-01-06 22:01 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Tyler Retzlaff 2023-01-06 22:01 ` [PATCH v3 1/3] eal: move bit functions from common to bitops header Tyler Retzlaff 2023-01-06 22:01 ` [PATCH v3 2/3] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2023-01-06 22:01 ` Tyler Retzlaff 2023-01-07 8:15 ` Thomas Monjalon 2023-01-07 13:40 ` Morten Brørup 2023-01-09 8:51 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Bruce Richardson 3 siblings, 2 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-06 22:01 UTC (permalink / raw) To: dev; +Cc: mb, thomas, david.marchand, Tyler Retzlaff basic unit test of following functions rte_clz32 rte_clz64 rte_ctz32 rte_ctz64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- app/test/meson.build | 2 ++ app/test/test_bitcount.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 app/test/test_bitcount.c diff --git a/app/test/meson.build b/app/test/meson.build index f34d19e..d1277bc 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -13,6 +13,7 @@ test_sources = files( 'test_alarm.c', 'test_atomic.c', 'test_barrier.c', + 'test_bitcount.c', 'test_bitops.c', 'test_bitmap.c', 'test_bpf.c', @@ -160,6 +161,7 @@ test_deps += ['bus_pci', 'bus_vdev'] fast_tests = [ ['acl_autotest', true, true], ['atomic_autotest', false, true], + ['bitcount_autotest', true, true], ['bitmap_autotest', true, true], ['bpf_autotest', true, true], ['bpf_convert_autotest', true, true], diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c new file mode 100644 index 0000000..36eb05c --- /dev/null +++ b/app/test/test_bitcount.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#include <string.h> + +#include <rte_bitops.h> +#include <rte_debug.h> + +#include "test.h" + +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); + +static int +test_clz32(void) +{ + uint32_t v = 1; + RTE_TEST_ASSERT(rte_clz32(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_clz64(void) +{ + uint64_t v = 1; + RTE_TEST_ASSERT(rte_clz64(v) == sizeof(v) * CHAR_BIT - 1, + "Unexpected count."); + + return 0; +} + +static int +test_ctz32(void) +{ + uint32_t v = 2; + RTE_TEST_ASSERT(rte_ctz32(v) == 1, "Unexpected count."); + + return 0; +} + +static int +test_ctz64(void) +{ + uint64_t v = 2; + RTE_TEST_ASSERT(rte_ctz64(v) == 1, "Unexpected count."); + + return 0; +} + +static struct unit_test_suite bitcount_test_suite = { + .suite_name = "bitcount autotest", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + TEST_CASE(test_clz32), + TEST_CASE(test_clz64), + TEST_CASE(test_ctz32), + TEST_CASE(test_ctz64), + TEST_CASES_END() + } +}; + +static int +test_bitcount(void) +{ + return unit_test_suite_runner(&bitcount_test_suite); +} + +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v3 3/3] test/bitcount: add bitcount tests 2023-01-06 22:01 ` [PATCH v3 3/3] test/bitcount: add bitcount tests Tyler Retzlaff @ 2023-01-07 8:15 ` Thomas Monjalon 2023-01-09 16:57 ` Tyler Retzlaff 2023-01-07 13:40 ` Morten Brørup 1 sibling, 1 reply; 81+ messages in thread From: Thomas Monjalon @ 2023-01-07 8:15 UTC (permalink / raw) To: dev, Tyler Retzlaff; +Cc: mb, david.marchand 06/01/2023 23:01, Tyler Retzlaff: > basic unit test of following functions > > rte_clz32 > rte_clz64 > rte_ctz32 > rte_ctz64 This can be squashed with implementation in previous patch. ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v3 3/3] test/bitcount: add bitcount tests 2023-01-07 8:15 ` Thomas Monjalon @ 2023-01-09 16:57 ` Tyler Retzlaff 2023-01-09 17:26 ` Tyler Retzlaff 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-09 16:57 UTC (permalink / raw) To: Thomas Monjalon; +Cc: dev, mb, david.marchand On Sat, Jan 07, 2023 at 09:15:27AM +0100, Thomas Monjalon wrote: > 06/01/2023 23:01, Tyler Retzlaff: > > basic unit test of following functions > > > > rte_clz32 > > rte_clz64 > > rte_ctz32 > > rte_ctz64 > > This can be squashed with implementation in previous patch. > > if you mean squashed into the patch that moves the existing functions sure it can be, but really the addtions are a self contained change separate from the move of the existing functions. ordinarily i'd rather see history order be as follows. - here is a change that just moves code (no addtions no deletions). - here is a change that adds new apis (no moves). you sure you want the move and additions all combined into one change? either way confirm what you want and if needed i'll combine and push a v4. thanks ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v3 3/3] test/bitcount: add bitcount tests 2023-01-09 16:57 ` Tyler Retzlaff @ 2023-01-09 17:26 ` Tyler Retzlaff 0 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-09 17:26 UTC (permalink / raw) To: Thomas Monjalon; +Cc: dev, mb, david.marchand On Mon, Jan 09, 2023 at 08:57:32AM -0800, Tyler Retzlaff wrote: > On Sat, Jan 07, 2023 at 09:15:27AM +0100, Thomas Monjalon wrote: > > 06/01/2023 23:01, Tyler Retzlaff: > > > basic unit test of following functions > > > > > > rte_clz32 > > > rte_clz64 > > > rte_ctz32 > > > rte_ctz64 > > > > This can be squashed with implementation in previous patch. > > > > > > if you mean squashed into the patch that moves the existing functions > sure it can be, but really the addtions are a self contained change > separate from the move of the existing functions. > > ordinarily i'd rather see history order be as follows. > > - here is a change that just moves code (no addtions no deletions). > - here is a change that adds new apis (no moves). > > you sure you want the move and additions all combined into one change? > > either way confirm what you want and if needed i'll combine and push a > v4. > ignore the above, i misread what you were asking for. i will submit a new version with the unit tests squished in to the new function additions. > thanks ^ permalink raw reply [flat|nested] 81+ messages in thread
* RE: [PATCH v3 3/3] test/bitcount: add bitcount tests 2023-01-06 22:01 ` [PATCH v3 3/3] test/bitcount: add bitcount tests Tyler Retzlaff 2023-01-07 8:15 ` Thomas Monjalon @ 2023-01-07 13:40 ` Morten Brørup 1 sibling, 0 replies; 81+ messages in thread From: Morten Brørup @ 2023-01-07 13:40 UTC (permalink / raw) To: Tyler Retzlaff, dev; +Cc: thomas, david.marchand > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > Sent: Friday, 6 January 2023 23.02 > > basic unit test of following functions > > rte_clz32 > rte_clz64 > rte_ctz32 > rte_ctz64 > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> > --- Series-acked-by: Morten Brørup <mb@smartsharesystems.com> ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v3 0/3] eal: provide leading and trailing zero bit count 2023-01-06 22:01 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Tyler Retzlaff ` (2 preceding siblings ...) 2023-01-06 22:01 ` [PATCH v3 3/3] test/bitcount: add bitcount tests Tyler Retzlaff @ 2023-01-09 8:51 ` Bruce Richardson 3 siblings, 0 replies; 81+ messages in thread From: Bruce Richardson @ 2023-01-09 8:51 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: dev, mb, thomas, david.marchand On Fri, Jan 06, 2023 at 02:01:42PM -0800, Tyler Retzlaff wrote: > Move existing bit manipulation, log and npow functions from > rte_common.h to rte_bitops.h > > Provide leading and trailing zero bit count functions to abstract away > compiler specific implementations. > > Include basic unit test for new leading/trailing zero bit count functions. > > v3: > * rename to use 32/64 instead of l/ll suffixes > * add new functions to rte_bitops.h instead of new header > * move other bit functions from rte_common.h to rte_bitops.h > Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v5 0/2] eal: provide leading and trailing zero bit count abstraction 2022-11-23 22:14 [PATCH 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff ` (3 preceding siblings ...) 2023-01-06 22:01 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Tyler Retzlaff @ 2023-01-10 19:38 ` Tyler Retzlaff 2023-01-10 19:38 ` [PATCH v5 1/2] eal: move bit operation common to bitops header Tyler Retzlaff 2023-01-10 19:38 ` [PATCH v5 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-10 19:46 ` [PATCH v6 0/2] " Tyler Retzlaff ` (2 subsequent siblings) 7 siblings, 2 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-10 19:38 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, ferruh.yigit, Tyler Retzlaff Move existing bit manipulation, log and npow functions from rte_common.h to rte_bitops.h Provide leading and trailing zero bit count functions to abstract away compiler specific implementations. Include basic unit test for new leading/trailing zero bit count functions. v5: * fix implementation of msvc versions of rte_clz{32,64} incorrect use of _BitscanReverse{,64} index. * fix and expand unit test to exercise full range of counting over uint{32,64}_t input values. (which would have caught above mistake). * reduce commit title length * correct commit author v4: * combine unit test commit into function addition commit v3: * rename to use 32/64 instead of l/ll suffixes * add new functions to rte_bitops.h instead of new header * move other bit functions from rte_common.h to rte_bitops.h v2: * use unsigned int instead of unsigned (checkpatches) * match multiple include guard naming convention to rte_common.h * add explicit extern "C" linkage to rte_bitcount.h note: not really needed but checkpatches required * add missing space around '-' Tyler Retzlaff (2): eal: move bit operation common to bitops header eal: provide leading and trailing zero bit count abstraction app/test/meson.build | 2 + app/test/test_bitcount.c | 86 ++++++++ app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 460 ++++++++++++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ------------------------- 6 files changed, 550 insertions(+), 293 deletions(-) create mode 100644 app/test/test_bitcount.c -- Series-acked-by: Morten Brørup <mb@smartsharesystems.com> Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v5 1/2] eal: move bit operation common to bitops header 2023-01-10 19:38 ` [PATCH v5 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2023-01-10 19:38 ` Tyler Retzlaff 2023-01-10 19:38 ` [PATCH v5 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 1 sibling, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-10 19:38 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, ferruh.yigit, Tyler Retzlaff Move the following inline functions from rte_common.h to rte_bitops.h rte_combine32ms1b rte_combine64ms1b rte_bsf32 rte_bsf32_safe rte_bsf64 rte_bsf64_safe rte_fls_u32 rte_fls_u64 rte_is_power_of_2 rte_align32pow2 rte_align32prevpow2 rte_align64pow2 rte_align64prevpow2 rte_log2_u32 rte_log2_u64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 292 +++++++++++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ---------------------------------------- 4 files changed, 294 insertions(+), 293 deletions(-) diff --git a/app/test/test_common.c b/app/test/test_common.c index f89e1eb..cf4a2c7 100644 --- a/app/test/test_common.c +++ b/app/test/test_common.c @@ -7,6 +7,7 @@ #include <string.h> #include <math.h> #include <rte_common.h> +#include <rte_bitops.h> #include <rte_hexdump.h> #include <rte_pause.h> diff --git a/lib/eal/common/rte_reciprocal.c b/lib/eal/common/rte_reciprocal.c index 42dfa44..d47dc47 100644 --- a/lib/eal/common/rte_reciprocal.c +++ b/lib/eal/common/rte_reciprocal.c @@ -8,6 +8,7 @@ #include <stdint.h> #include <rte_common.h> +#include <rte_bitops.h> #include "rte_reciprocal.h" diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index f50dbe4..531479e 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -275,6 +275,298 @@ return val & mask; } +/** + * Combines 32b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param x + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint32_t +rte_combine32ms1b(uint32_t x) +{ + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return x; +} + +/** + * Combines 64b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param v + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint64_t +rte_combine64ms1b(uint64_t v) +{ + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + + return v; +} + +/** + * 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 uint32_t +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(uint32_t v, uint32_t *pos) +{ + if (v == 0) + return 0; + + *pos = rte_bsf32(v); + return 1; +} + +/** + * 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 uint32_t +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 32. + * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 + * + * @param x + * The input parameter. + * @return + * The last (most-significant) bit set, or 0 if the input is 0. + */ +static inline uint32_t +rte_fls_u32(uint32_t x) +{ + return (x == 0) ? 0 : 32 - __builtin_clz(x); +} + +/** + * 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 uint32_t +rte_fls_u64(uint64_t x) +{ + return (x == 0) ? 0 : 64 - __builtin_clzll(x); +} + +/*********** Macros to work with powers of 2 ********/ + +/** + * Macro to return 1 if n is a power of 2, 0 otherwise + */ +#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) + +/** + * Returns true if n is a power of 2 + * @param n + * Number to check + * @return 1 if true, 0 otherwise + */ +static inline int +rte_is_power_of_2(uint32_t n) +{ + return n && !(n & (n - 1)); +} + +/** + * Aligns input parameter to the next power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint32_t +rte_align32pow2(uint32_t x) +{ + x--; + x = rte_combine32ms1b(x); + + return x + 1; +} + +/** + * Aligns input parameter to the previous power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint32_t +rte_align32prevpow2(uint32_t x) +{ + x = rte_combine32ms1b(x); + + return x - (x >> 1); +} + +/** + * Aligns 64b input parameter to the next power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint64_t +rte_align64pow2(uint64_t v) +{ + v--; + v = rte_combine64ms1b(v); + + return v + 1; +} + +/** + * Aligns 64b input parameter to the previous power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint64_t +rte_align64prevpow2(uint64_t v) +{ + v = rte_combine64ms1b(v); + + return v - (v >> 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 + * The rounded-up log2 of the input, or 0 if the input is 0. + */ +static inline uint32_t +rte_log2_u32(uint32_t v) +{ + if (v == 0) + return 0; + v = rte_align32pow2(v); + return rte_bsf32(v); +} + +/** + * 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); +} + #ifdef __cplusplus } #endif diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h index 15765b4..c5ad69c 100644 --- a/lib/eal/include/rte_common.h +++ b/lib/eal/include/rte_common.h @@ -471,140 +471,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /** Marker for 8B alignment in a structure. */ __extension__ typedef uint64_t RTE_MARKER64[0]; -/** - * Combines 32b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param x - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint32_t -rte_combine32ms1b(uint32_t x) -{ - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - - return x; -} - -/** - * Combines 64b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param v - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint64_t -rte_combine64ms1b(uint64_t v) -{ - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - - return v; -} - -/*********** Macros to work with powers of 2 ********/ - -/** - * Macro to return 1 if n is a power of 2, 0 otherwise - */ -#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) - -/** - * Returns true if n is a power of 2 - * @param n - * Number to check - * @return 1 if true, 0 otherwise - */ -static inline int -rte_is_power_of_2(uint32_t n) -{ - return n && !(n & (n - 1)); -} - -/** - * Aligns input parameter to the next power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint32_t -rte_align32pow2(uint32_t x) -{ - x--; - x = rte_combine32ms1b(x); - - return x + 1; -} - -/** - * Aligns input parameter to the previous power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint32_t -rte_align32prevpow2(uint32_t x) -{ - x = rte_combine32ms1b(x); - - return x - (x >> 1); -} - -/** - * Aligns 64b input parameter to the next power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint64_t -rte_align64pow2(uint64_t v) -{ - v--; - v = rte_combine64ms1b(v); - - return v + 1; -} - -/** - * Aligns 64b input parameter to the previous power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint64_t -rte_align64prevpow2(uint64_t v) -{ - v = rte_combine64ms1b(v); - - return v - (v >> 1); -} - /*********** Macros for calculating min and max **********/ /** @@ -629,165 +495,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /*********** Other general functions / macros ********/ -/** - * 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 uint32_t -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(uint32_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 - * The rounded-up log2 of the input, or 0 if the input is 0. - */ -static inline uint32_t -rte_log2_u32(uint32_t v) -{ - if (v == 0) - return 0; - v = rte_align32pow2(v); - return rte_bsf32(v); -} - - -/** - * Return the last (most-significant) bit set. - * - * @note The last (most significant) bit is at position 32. - * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 - * - * @param x - * The input parameter. - * @return - * The last (most-significant) bit set, or 0 if the input is 0. - */ -static inline uint32_t -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 uint32_t -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 uint32_t -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. */ #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v5 2/2] eal: provide leading and trailing zero bit count abstraction 2023-01-10 19:38 ` [PATCH v5 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-10 19:38 ` [PATCH v5 1/2] eal: move bit operation common to bitops header Tyler Retzlaff @ 2023-01-10 19:38 ` Tyler Retzlaff 1 sibling, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-10 19:38 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, ferruh.yigit, Tyler Retzlaff Provide an abstraction for leading and trailing zero bit counting functions to hide compiler specific intrinsics and builtins. Include basic unit test of following functions added. rte_clz32 rte_clz64 rte_ctz32 rte_ctz64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- app/test/meson.build | 2 + app/test/test_bitcount.c | 94 ++++++++++++++++++++++++ lib/eal/include/rte_bitops.h | 168 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 app/test/test_bitcount.c diff --git a/app/test/meson.build b/app/test/meson.build index f34d19e..d1277bc 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -13,6 +13,7 @@ test_sources = files( 'test_alarm.c', 'test_atomic.c', 'test_barrier.c', + 'test_bitcount.c', 'test_bitops.c', 'test_bitmap.c', 'test_bpf.c', @@ -160,6 +161,7 @@ test_deps += ['bus_pci', 'bus_vdev'] fast_tests = [ ['acl_autotest', true, true], ['atomic_autotest', false, true], + ['bitcount_autotest', true, true], ['bitmap_autotest', true, true], ['bpf_autotest', true, true], ['bpf_convert_autotest', true, true], diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c new file mode 100644 index 0000000..1359bed --- /dev/null +++ b/app/test/test_bitcount.c @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#include <string.h> +#include <stdio.h> + +#include <rte_bitops.h> +#include <rte_debug.h> + +#include "test.h" + +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); + +static int +test_clz32(void) +{ + size_t leading; + uint32_t v = 0xffffffff; + + for (leading = 0; v; leading++) { + RTE_TEST_ASSERT(rte_clz32(v) == leading, + "Unexpected count."); + v >>= 1; + } + + return 0; +} + +static int +test_clz64(void) +{ + size_t leading; + uint64_t v = 0xffffffffffffffff; + + for (leading = 0; v; leading++) { + RTE_TEST_ASSERT(rte_clz64(v) == leading, + "Unexpected count."); + v >>= 1; + } + + return 0; +} + +static int +test_ctz32(void) +{ + size_t trailing; + uint32_t v = 1; + + for (trailing = 0; v; trailing++) { + RTE_TEST_ASSERT(rte_ctz32(v) == trailing, + "Unexpected count."); + v <<= 1; + } + + return 0; +} + +static int +test_ctz64(void) +{ + size_t trailing; + uint64_t v = 1; + + for (trailing = 0; v; trailing++) { + RTE_TEST_ASSERT(rte_ctz64(v) == trailing, + "Unexpected count."); + v <<= 1; + } + + return 0; +} + +static struct unit_test_suite bitcount_test_suite = { + .suite_name = "bitcount autotest", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + TEST_CASE(test_clz32), + TEST_CASE(test_clz64), + TEST_CASE(test_ctz32), + TEST_CASE(test_ctz64), + TEST_CASES_END() + } +}; + +static int +test_bitcount(void) +{ + return unit_test_suite_runner(&bitcount_test_suite); +} + +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index 531479e..e578fc1 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2020 Arm Limited + * Copyright(c) 2010-2019 Intel Corporation + * Copyright(c) 2023 Microsoft Corporation */ #ifndef _RTE_BITOPS_H_ @@ -275,6 +277,172 @@ return val & mask; } +#ifdef RTE_TOOLCHAIN_MSVC + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanReverse64(&rv, v); + + return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanForward64(&rv, v); + + return (unsigned int)rv; +} + +#else + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + return (unsigned int)__builtin_clz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + return (unsigned int)__builtin_clzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + return (unsigned int)__builtin_ctz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + return (unsigned int)__builtin_ctzll(v); +} + +#endif + /** * Combines 32b inputs most significant set bits into the least * significant bits to construct a value with the same MSBs as x -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v6 0/2] eal: provide leading and trailing zero bit count abstraction 2022-11-23 22:14 [PATCH 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff ` (4 preceding siblings ...) 2023-01-10 19:38 ` [PATCH v5 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2023-01-10 19:46 ` Tyler Retzlaff 2023-01-10 19:46 ` [PATCH v6 1/2] eal: move bit operation common to bitops header Tyler Retzlaff ` (2 more replies) 2023-04-01 0:45 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 0/3] " Tyler Retzlaff 7 siblings, 3 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-10 19:46 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, ferruh.yigit, Tyler Retzlaff v6: * remove stray #include <stdio.h> v5: * fix implementation of msvc versions of rte_clz{32,64} incorrect use of _BitscanReverse{,64} index. * fix and expand unit test to exercise full range of counting over uint{32,64}_t input values. (which would have caught above mistake). * reduce commit title length * correct commit author v4: * combine unit test commit into function addition commit v3: * rename to use 32/64 instead of l/ll suffixes * add new functions to rte_bitops.h instead of new header * move other bit functions from rte_common.h to rte_bitops.h v2: * use unsigned int instead of unsigned (checkpatches) * match multiple include guard naming convention to rte_common.h * add explicit extern "C" linkage to rte_bitcount.h note: not really needed but checkpatches required * add missing space around '-' Tyler Retzlaff (2): eal: move bit operation common to bitops header eal: provide leading and trailing zero bit count abstraction app/test/meson.build | 2 + app/test/test_bitcount.c | 93 ++++++++ app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 460 ++++++++++++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ------------------------- 6 files changed, 557 insertions(+), 293 deletions(-) create mode 100644 app/test/test_bitcount.c -- Series-acked-by: Morten Brørup <mb@smartsharesystems.com> Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v6 1/2] eal: move bit operation common to bitops header 2023-01-10 19:46 ` [PATCH v6 0/2] " Tyler Retzlaff @ 2023-01-10 19:46 ` Tyler Retzlaff 2023-01-10 19:46 ` [PATCH v6 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-20 22:14 ` [PATCH v6 0/2] " Tyler Retzlaff 2 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-10 19:46 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, ferruh.yigit, Tyler Retzlaff Move the following inline functions from rte_common.h to rte_bitops.h rte_combine32ms1b rte_combine64ms1b rte_bsf32 rte_bsf32_safe rte_bsf64 rte_bsf64_safe rte_fls_u32 rte_fls_u64 rte_is_power_of_2 rte_align32pow2 rte_align32prevpow2 rte_align64pow2 rte_align64prevpow2 rte_log2_u32 rte_log2_u64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 292 +++++++++++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ---------------------------------------- 4 files changed, 294 insertions(+), 293 deletions(-) diff --git a/app/test/test_common.c b/app/test/test_common.c index f89e1eb..cf4a2c7 100644 --- a/app/test/test_common.c +++ b/app/test/test_common.c @@ -7,6 +7,7 @@ #include <string.h> #include <math.h> #include <rte_common.h> +#include <rte_bitops.h> #include <rte_hexdump.h> #include <rte_pause.h> diff --git a/lib/eal/common/rte_reciprocal.c b/lib/eal/common/rte_reciprocal.c index 42dfa44..d47dc47 100644 --- a/lib/eal/common/rte_reciprocal.c +++ b/lib/eal/common/rte_reciprocal.c @@ -8,6 +8,7 @@ #include <stdint.h> #include <rte_common.h> +#include <rte_bitops.h> #include "rte_reciprocal.h" diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index f50dbe4..531479e 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -275,6 +275,298 @@ return val & mask; } +/** + * Combines 32b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param x + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint32_t +rte_combine32ms1b(uint32_t x) +{ + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return x; +} + +/** + * Combines 64b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param v + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint64_t +rte_combine64ms1b(uint64_t v) +{ + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + + return v; +} + +/** + * 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 uint32_t +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(uint32_t v, uint32_t *pos) +{ + if (v == 0) + return 0; + + *pos = rte_bsf32(v); + return 1; +} + +/** + * 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 uint32_t +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 32. + * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 + * + * @param x + * The input parameter. + * @return + * The last (most-significant) bit set, or 0 if the input is 0. + */ +static inline uint32_t +rte_fls_u32(uint32_t x) +{ + return (x == 0) ? 0 : 32 - __builtin_clz(x); +} + +/** + * 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 uint32_t +rte_fls_u64(uint64_t x) +{ + return (x == 0) ? 0 : 64 - __builtin_clzll(x); +} + +/*********** Macros to work with powers of 2 ********/ + +/** + * Macro to return 1 if n is a power of 2, 0 otherwise + */ +#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) + +/** + * Returns true if n is a power of 2 + * @param n + * Number to check + * @return 1 if true, 0 otherwise + */ +static inline int +rte_is_power_of_2(uint32_t n) +{ + return n && !(n & (n - 1)); +} + +/** + * Aligns input parameter to the next power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint32_t +rte_align32pow2(uint32_t x) +{ + x--; + x = rte_combine32ms1b(x); + + return x + 1; +} + +/** + * Aligns input parameter to the previous power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint32_t +rte_align32prevpow2(uint32_t x) +{ + x = rte_combine32ms1b(x); + + return x - (x >> 1); +} + +/** + * Aligns 64b input parameter to the next power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint64_t +rte_align64pow2(uint64_t v) +{ + v--; + v = rte_combine64ms1b(v); + + return v + 1; +} + +/** + * Aligns 64b input parameter to the previous power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint64_t +rte_align64prevpow2(uint64_t v) +{ + v = rte_combine64ms1b(v); + + return v - (v >> 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 + * The rounded-up log2 of the input, or 0 if the input is 0. + */ +static inline uint32_t +rte_log2_u32(uint32_t v) +{ + if (v == 0) + return 0; + v = rte_align32pow2(v); + return rte_bsf32(v); +} + +/** + * 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); +} + #ifdef __cplusplus } #endif diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h index 15765b4..c5ad69c 100644 --- a/lib/eal/include/rte_common.h +++ b/lib/eal/include/rte_common.h @@ -471,140 +471,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /** Marker for 8B alignment in a structure. */ __extension__ typedef uint64_t RTE_MARKER64[0]; -/** - * Combines 32b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param x - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint32_t -rte_combine32ms1b(uint32_t x) -{ - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - - return x; -} - -/** - * Combines 64b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param v - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint64_t -rte_combine64ms1b(uint64_t v) -{ - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - - return v; -} - -/*********** Macros to work with powers of 2 ********/ - -/** - * Macro to return 1 if n is a power of 2, 0 otherwise - */ -#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) - -/** - * Returns true if n is a power of 2 - * @param n - * Number to check - * @return 1 if true, 0 otherwise - */ -static inline int -rte_is_power_of_2(uint32_t n) -{ - return n && !(n & (n - 1)); -} - -/** - * Aligns input parameter to the next power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint32_t -rte_align32pow2(uint32_t x) -{ - x--; - x = rte_combine32ms1b(x); - - return x + 1; -} - -/** - * Aligns input parameter to the previous power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint32_t -rte_align32prevpow2(uint32_t x) -{ - x = rte_combine32ms1b(x); - - return x - (x >> 1); -} - -/** - * Aligns 64b input parameter to the next power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint64_t -rte_align64pow2(uint64_t v) -{ - v--; - v = rte_combine64ms1b(v); - - return v + 1; -} - -/** - * Aligns 64b input parameter to the previous power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint64_t -rte_align64prevpow2(uint64_t v) -{ - v = rte_combine64ms1b(v); - - return v - (v >> 1); -} - /*********** Macros for calculating min and max **********/ /** @@ -629,165 +495,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /*********** Other general functions / macros ********/ -/** - * 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 uint32_t -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(uint32_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 - * The rounded-up log2 of the input, or 0 if the input is 0. - */ -static inline uint32_t -rte_log2_u32(uint32_t v) -{ - if (v == 0) - return 0; - v = rte_align32pow2(v); - return rte_bsf32(v); -} - - -/** - * Return the last (most-significant) bit set. - * - * @note The last (most significant) bit is at position 32. - * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 - * - * @param x - * The input parameter. - * @return - * The last (most-significant) bit set, or 0 if the input is 0. - */ -static inline uint32_t -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 uint32_t -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 uint32_t -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. */ #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v6 2/2] eal: provide leading and trailing zero bit count abstraction 2023-01-10 19:46 ` [PATCH v6 0/2] " Tyler Retzlaff 2023-01-10 19:46 ` [PATCH v6 1/2] eal: move bit operation common to bitops header Tyler Retzlaff @ 2023-01-10 19:46 ` Tyler Retzlaff 2023-01-20 22:14 ` [PATCH v6 0/2] " Tyler Retzlaff 2 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-10 19:46 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, ferruh.yigit, Tyler Retzlaff Provide an abstraction for leading and trailing zero bit counting functions to hide compiler specific intrinsics and builtins. Include basic unit test of following functions added. rte_clz32 rte_clz64 rte_ctz32 rte_ctz64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- app/test/meson.build | 2 + app/test/test_bitcount.c | 93 ++++++++++++++++++++++++ lib/eal/include/rte_bitops.h | 168 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 263 insertions(+) create mode 100644 app/test/test_bitcount.c diff --git a/app/test/meson.build b/app/test/meson.build index f34d19e..d1277bc 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -13,6 +13,7 @@ test_sources = files( 'test_alarm.c', 'test_atomic.c', 'test_barrier.c', + 'test_bitcount.c', 'test_bitops.c', 'test_bitmap.c', 'test_bpf.c', @@ -160,6 +161,7 @@ test_deps += ['bus_pci', 'bus_vdev'] fast_tests = [ ['acl_autotest', true, true], ['atomic_autotest', false, true], + ['bitcount_autotest', true, true], ['bitmap_autotest', true, true], ['bpf_autotest', true, true], ['bpf_convert_autotest', true, true], diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c new file mode 100644 index 0000000..a3ef2a5 --- /dev/null +++ b/app/test/test_bitcount.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#include <string.h> + +#include <rte_bitops.h> +#include <rte_debug.h> + +#include "test.h" + +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); + +static int +test_clz32(void) +{ + size_t leading; + uint32_t v = 0xffffffff; + + for (leading = 0; v; leading++) { + RTE_TEST_ASSERT(rte_clz32(v) == leading, + "Unexpected count."); + v >>= 1; + } + + return 0; +} + +static int +test_clz64(void) +{ + size_t leading; + uint64_t v = 0xffffffffffffffff; + + for (leading = 0; v; leading++) { + RTE_TEST_ASSERT(rte_clz64(v) == leading, + "Unexpected count."); + v >>= 1; + } + + return 0; +} + +static int +test_ctz32(void) +{ + size_t trailing; + uint32_t v = 1; + + for (trailing = 0; v; trailing++) { + RTE_TEST_ASSERT(rte_ctz32(v) == trailing, + "Unexpected count."); + v <<= 1; + } + + return 0; +} + +static int +test_ctz64(void) +{ + size_t trailing; + uint64_t v = 1; + + for (trailing = 0; v; trailing++) { + RTE_TEST_ASSERT(rte_ctz64(v) == trailing, + "Unexpected count."); + v <<= 1; + } + + return 0; +} + +static struct unit_test_suite bitcount_test_suite = { + .suite_name = "bitcount autotest", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + TEST_CASE(test_clz32), + TEST_CASE(test_clz64), + TEST_CASE(test_ctz32), + TEST_CASE(test_ctz64), + TEST_CASES_END() + } +}; + +static int +test_bitcount(void) +{ + return unit_test_suite_runner(&bitcount_test_suite); +} + +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index 531479e..e578fc1 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2020 Arm Limited + * Copyright(c) 2010-2019 Intel Corporation + * Copyright(c) 2023 Microsoft Corporation */ #ifndef _RTE_BITOPS_H_ @@ -275,6 +277,172 @@ return val & mask; } +#ifdef RTE_TOOLCHAIN_MSVC + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanReverse64(&rv, v); + + return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanForward64(&rv, v); + + return (unsigned int)rv; +} + +#else + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + return (unsigned int)__builtin_clz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + return (unsigned int)__builtin_clzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + return (unsigned int)__builtin_ctz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + return (unsigned int)__builtin_ctzll(v); +} + +#endif + /** * Combines 32b inputs most significant set bits into the least * significant bits to construct a value with the same MSBs as x -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v6 0/2] eal: provide leading and trailing zero bit count abstraction 2023-01-10 19:46 ` [PATCH v6 0/2] " Tyler Retzlaff 2023-01-10 19:46 ` [PATCH v6 1/2] eal: move bit operation common to bitops header Tyler Retzlaff 2023-01-10 19:46 ` [PATCH v6 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff @ 2023-01-20 22:14 ` Tyler Retzlaff 2023-02-02 9:14 ` David Marchand 2 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-01-20 22:14 UTC (permalink / raw) To: dev; +Cc: thomas, mb, bruce.richardson, ferruh.yigit, david.marchand hi folks, i think this one can probably be merged? Series-acked-by: Morten Brørup <mb@smartsharesystems.com> Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> patch 1/2 Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> thanks! On Tue, Jan 10, 2023 at 11:46:39AM -0800, Tyler Retzlaff wrote: > v6: > * remove stray #include <stdio.h> > > v5: > * fix implementation of msvc versions of rte_clz{32,64} > incorrect use of _BitscanReverse{,64} index. > * fix and expand unit test to exercise full range of counting > over uint{32,64}_t input values. (which would have caught > above mistake). > * reduce commit title length > * correct commit author > > v4: > * combine unit test commit into function addition commit > > v3: > * rename to use 32/64 instead of l/ll suffixes > * add new functions to rte_bitops.h instead of new header > * move other bit functions from rte_common.h to rte_bitops.h > > v2: > * use unsigned int instead of unsigned (checkpatches) > * match multiple include guard naming convention to rte_common.h > * add explicit extern "C" linkage to rte_bitcount.h > note: not really needed but checkpatches required > * add missing space around '-' > > Tyler Retzlaff (2): > eal: move bit operation common to bitops header > eal: provide leading and trailing zero bit count abstraction > > app/test/meson.build | 2 + > app/test/test_bitcount.c | 93 ++++++++ > app/test/test_common.c | 1 + > lib/eal/common/rte_reciprocal.c | 1 + > lib/eal/include/rte_bitops.h | 460 ++++++++++++++++++++++++++++++++++++++++ > lib/eal/include/rte_common.h | 293 ------------------------- > 6 files changed, 557 insertions(+), 293 deletions(-) > create mode 100644 app/test/test_bitcount.c > > -- > > Series-acked-by: Morten Brørup <mb@smartsharesystems.com> > Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v6 0/2] eal: provide leading and trailing zero bit count abstraction 2023-01-20 22:14 ` [PATCH v6 0/2] " Tyler Retzlaff @ 2023-02-02 9:14 ` David Marchand 2023-02-02 10:56 ` David Marchand 2023-02-02 15:56 ` Tyler Retzlaff 0 siblings, 2 replies; 81+ messages in thread From: David Marchand @ 2023-02-02 9:14 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: dev, thomas, mb, bruce.richardson, ferruh.yigit Hello Tyler, On Fri, Jan 20, 2023 at 11:14 PM Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > hi folks, > > i think this one can probably be merged? > > Series-acked-by: Morten Brørup <mb@smartsharesystems.com> > Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> > patch 1/2 Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> I like the cleanup of rte_common.h and additional unit tests, but the MSVC bits don't belong here. Please move them in your MSVC enablement series https://patchwork.dpdk.org/project/dpdk/list/?series=26662&state=%2A&archive=both. Thanks. -- David Marchand ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v6 0/2] eal: provide leading and trailing zero bit count abstraction 2023-02-02 9:14 ` David Marchand @ 2023-02-02 10:56 ` David Marchand 2023-02-02 15:57 ` Tyler Retzlaff 2023-02-02 15:56 ` Tyler Retzlaff 1 sibling, 1 reply; 81+ messages in thread From: David Marchand @ 2023-02-02 10:56 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: dev, thomas, mb, bruce.richardson, ferruh.yigit On Thu, Feb 2, 2023 at 10:14 AM David Marchand <david.marchand@redhat.com> wrote: > > Hello Tyler, > > On Fri, Jan 20, 2023 at 11:14 PM Tyler Retzlaff > <roretzla@linux.microsoft.com> wrote: > > > > hi folks, > > > > i think this one can probably be merged? > > > > Series-acked-by: Morten Brørup <mb@smartsharesystems.com> > > Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> > > patch 1/2 Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> > > I like the cleanup of rte_common.h and additional unit tests, but the > MSVC bits don't belong here. > Please move them in your MSVC enablement series > https://patchwork.dpdk.org/project/dpdk/list/?series=26662&state=%2A&archive=both. Addendum, running the series through my checks, I can see that test_bitcount.c is left unattended wrt the MAINTAINERS file. app/test/test_bitcount.c must be put under the "EAL API and common code" section. Thanks. -- David Marchand ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v6 0/2] eal: provide leading and trailing zero bit count abstraction 2023-02-02 10:56 ` David Marchand @ 2023-02-02 15:57 ` Tyler Retzlaff 2023-02-03 9:14 ` David Marchand 0 siblings, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-02-02 15:57 UTC (permalink / raw) To: David Marchand; +Cc: dev, thomas, mb, bruce.richardson, ferruh.yigit On Thu, Feb 02, 2023 at 11:56:41AM +0100, David Marchand wrote: > On Thu, Feb 2, 2023 at 10:14 AM David Marchand > <david.marchand@redhat.com> wrote: > > > > Hello Tyler, > > > > On Fri, Jan 20, 2023 at 11:14 PM Tyler Retzlaff > > <roretzla@linux.microsoft.com> wrote: > > > > > > hi folks, > > > > > > i think this one can probably be merged? > > > > > > Series-acked-by: Morten Brørup <mb@smartsharesystems.com> > > > Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> > > > patch 1/2 Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> > > > > I like the cleanup of rte_common.h and additional unit tests, but the > > MSVC bits don't belong here. > > Please move them in your MSVC enablement series > > https://patchwork.dpdk.org/project/dpdk/list/?series=26662&state=%2A&archive=both. > > Addendum, running the series through my checks, I can see that > test_bitcount.c is left unattended wrt the MAINTAINERS file. > app/test/test_bitcount.c must be put under the "EAL API and common > code" section. is this an automated check i should have run prior to submission? either way i'll fix that up, sorry for the mistake. > > Thanks. > -- > David Marchand ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v6 0/2] eal: provide leading and trailing zero bit count abstraction 2023-02-02 15:57 ` Tyler Retzlaff @ 2023-02-03 9:14 ` David Marchand 0 siblings, 0 replies; 81+ messages in thread From: David Marchand @ 2023-02-03 9:14 UTC (permalink / raw) To: Tyler Retzlaff, thomas; +Cc: dev, mb, bruce.richardson, ferruh.yigit On Thu, Feb 2, 2023 at 4:57 PM Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > > I like the cleanup of rte_common.h and additional unit tests, but the > > > MSVC bits don't belong here. > > > Please move them in your MSVC enablement series > > > https://patchwork.dpdk.org/project/dpdk/list/?series=26662&state=%2A&archive=both. > > > > Addendum, running the series through my checks, I can see that > > test_bitcount.c is left unattended wrt the MAINTAINERS file. > > app/test/test_bitcount.c must be put under the "EAL API and common > > code" section. > > is this an automated check i should have run prior to submission? The script is devtools/check-maintainers.sh. But unfortunately it is not run in the CI as its author never made it reliable enough: it has false positives / known issues / accepted issues. Users (I guess Thomas and I, maybe some subtree maintainers) keep a local reference of this script output, and compare against it. This is something that is rarely needed: in general additions are done as a single component in MAINTAINERS, so people naturally add themselves with the top level directory, and that's it. So I guess our current check is good enough. > > either way i'll fix that up, sorry for the mistake. No worries, this is not something you could easily find unless grepping and looking how things were done for other unit tests. -- David Marchand ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v6 0/2] eal: provide leading and trailing zero bit count abstraction 2023-02-02 9:14 ` David Marchand 2023-02-02 10:56 ` David Marchand @ 2023-02-02 15:56 ` Tyler Retzlaff 2023-02-03 9:21 ` David Marchand 1 sibling, 1 reply; 81+ messages in thread From: Tyler Retzlaff @ 2023-02-02 15:56 UTC (permalink / raw) To: David Marchand; +Cc: dev, thomas, mb, bruce.richardson, ferruh.yigit On Thu, Feb 02, 2023 at 10:14:41AM +0100, David Marchand wrote: > Hello Tyler, > > On Fri, Jan 20, 2023 at 11:14 PM Tyler Retzlaff > <roretzla@linux.microsoft.com> wrote: > > > > hi folks, > > > > i think this one can probably be merged? > > > > Series-acked-by: Morten Brørup <mb@smartsharesystems.com> > > Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> > > patch 1/2 Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> > > I like the cleanup of rte_common.h and additional unit tests, but the > MSVC bits don't belong here. > Please move them in your MSVC enablement series hm, the way i'm approaching this is to keep specific features together similar to if i added new platform functionality for threads i add windows or linux in the same series. similarly, in this case i'm adding msvc and gcc in the same series. the msvc enablement series introduces the changes for the build system so it's about enabling a compiler not adding functionality to dpdk so this change/API really aren't related to the other, but i agree the other series is part of converging on the platform, toolchain combination being enabled overall. reconsider? if not i guess i'll just withdraw the actual API for now and have to resubmit and review later since i don't think it belongs mixed in with the compiler enablement. > https://patchwork.dpdk.org/project/dpdk/list/?series=26662&state=%2A&archive=both. if the msvc series were just merged, i think the above discussion would be moot no? anyway, i'll abide by whatever decision you go with. thanks! ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v6 0/2] eal: provide leading and trailing zero bit count abstraction 2023-02-02 15:56 ` Tyler Retzlaff @ 2023-02-03 9:21 ` David Marchand 0 siblings, 0 replies; 81+ messages in thread From: David Marchand @ 2023-02-03 9:21 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: dev, thomas, mb, bruce.richardson, ferruh.yigit On Thu, Feb 2, 2023 at 4:56 PM Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > On Thu, Feb 02, 2023 at 10:14:41AM +0100, David Marchand wrote: > > Hello Tyler, > > > > On Fri, Jan 20, 2023 at 11:14 PM Tyler Retzlaff > > <roretzla@linux.microsoft.com> wrote: > > > > > > hi folks, > > > > > > i think this one can probably be merged? > > > > > > Series-acked-by: Morten Brørup <mb@smartsharesystems.com> > > > Series-acked-by: Bruce Richardson <bruce.richardson@intel.com> > > > patch 1/2 Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> > > > > I like the cleanup of rte_common.h and additional unit tests, but the > > MSVC bits don't belong here. > > Please move them in your MSVC enablement series > > hm, the way i'm approaching this is to keep specific features together > similar to if i added new platform functionality for threads i add > windows or linux in the same series. similarly, in this case i'm adding > msvc and gcc in the same series. > > the msvc enablement series introduces the changes for the build system > so it's about enabling a compiler not adding functionality to dpdk so > this change/API really aren't related to the other, but i agree the other > series is part of converging on the platform, toolchain combination > being enabled overall. > > reconsider? if not i guess i'll just withdraw the actual API for now > and have to resubmit and review later since i don't think it belongs > mixed in with the compiler enablement. > > > https://patchwork.dpdk.org/project/dpdk/list/?series=26662&state=%2A&archive=both. > > if the msvc series were just merged, i think the above discussion would be > moot no? Indeed, but until we have support for MSVC, this part of the patch is putting dead (untested) code in the tree. It is also confusing to see references to MSVC in the tree while we have nothing setting this config item, and no documentation explaining how/when this will be actually usable. -- David Marchand ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v7 0/4] eal: provide abstracted bit counting functions 2022-11-23 22:14 [PATCH 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff ` (5 preceding siblings ...) 2023-01-10 19:46 ` [PATCH v6 0/2] " Tyler Retzlaff @ 2023-04-01 0:45 ` Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 1/4] eal: move bit count functions to bitops header Tyler Retzlaff ` (4 more replies) 2023-04-04 0:11 ` [PATCH v8 0/3] " Tyler Retzlaff 7 siblings, 5 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-01 0:45 UTC (permalink / raw) To: dev Cc: thomas, stephen, mb, bruce.richardson, ferruh.yigit, david.marchand, Tyler Retzlaff As discussed technical board meeting 2023-02-22 http://mails.dpdk.org/archives/dev/2023-February/263516.html We will bring support in pieces for the MSVC compiler, there will be some abstractions and functions introduced before the compiler is capable of compiling DPDK in order to make parallel progress while waiting for standard atomics in 23.07. A higher level plan / order of work is available in the Microsoft roadmap for 23.07 and 23.11. note: Morten Brørup and Bruce Richardson previous acks have been preserved but be aware of the two additional functions introduced in v7. If you wish to withdraw your ack, please let me know but I believe the 2 additions are consistent with previous. v7: * add 2 additional counting functions rte_popcount{32,64} including basic unit tests * fix patch 1 title link (CI complained too long) * add test_bitcount.c entry to MAINTAINERS file v6: * remove stray #include <stdio.h> v5: * fix implementation of msvc versions of rte_clz{32,64} incorrect use of _BitscanReverse{,64} index. * fix and expand unit test to exercise full range of counting over uint{32,64}_t input values. (which would have caught above mistake). * reduce commit title length * correct commit author v4: * combine unit test commit into function addition commit v3: * rename to use 32/64 instead of l/ll suffixes * add new functions to rte_bitops.h instead of new header * move other bit functions from rte_common.h to rte_bitops.h v2: * use unsigned int instead of unsigned (checkpatches) * match multiple include guard naming convention to rte_common.h * add explicit extern "C" linkage to rte_bitcount.h note: not really needed but checkpatches required * add missing space around '-' Tyler Retzlaff (4): eal: move bit count functions to bitops header eal: provide abstracted bit count functions pipeline: add include of bitops maintainers: add bitcount test under EAL API and common code MAINTAINERS | 1 + app/test/meson.build | 2 + app/test/test_bitcount.c | 136 ++++++++ app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 532 +++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ----------------- lib/pipeline/rte_swx_pipeline_internal.h | 1 + 8 files changed, 674 insertions(+), 293 deletions(-) create mode 100644 app/test/test_bitcount.c -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v7 1/4] eal: move bit count functions to bitops header 2023-04-01 0:45 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Tyler Retzlaff @ 2023-04-01 0:45 ` Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 2/4] eal: provide abstracted bit count functions Tyler Retzlaff ` (3 subsequent siblings) 4 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-01 0:45 UTC (permalink / raw) To: dev Cc: thomas, stephen, mb, bruce.richardson, ferruh.yigit, david.marchand, Tyler Retzlaff Move the following inline functions from rte_common.h to rte_bitops.h rte_combine32ms1b rte_combine64ms1b rte_bsf32 rte_bsf32_safe rte_bsf64 rte_bsf64_safe rte_fls_u32 rte_fls_u64 rte_is_power_of_2 rte_align32pow2 rte_align32prevpow2 rte_align64pow2 rte_align64prevpow2 rte_log2_u32 rte_log2_u64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> Acked-by: Morten Brørup <mb@smartsharesystems.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com> --- app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 292 +++++++++++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ---------------------------------------- 4 files changed, 294 insertions(+), 293 deletions(-) diff --git a/app/test/test_common.c b/app/test/test_common.c index f89e1eb..cf4a2c7 100644 --- a/app/test/test_common.c +++ b/app/test/test_common.c @@ -7,6 +7,7 @@ #include <string.h> #include <math.h> #include <rte_common.h> +#include <rte_bitops.h> #include <rte_hexdump.h> #include <rte_pause.h> diff --git a/lib/eal/common/rte_reciprocal.c b/lib/eal/common/rte_reciprocal.c index 42dfa44..d47dc47 100644 --- a/lib/eal/common/rte_reciprocal.c +++ b/lib/eal/common/rte_reciprocal.c @@ -8,6 +8,7 @@ #include <stdint.h> #include <rte_common.h> +#include <rte_bitops.h> #include "rte_reciprocal.h" diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index f50dbe4..531479e 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -275,6 +275,298 @@ return val & mask; } +/** + * Combines 32b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param x + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint32_t +rte_combine32ms1b(uint32_t x) +{ + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return x; +} + +/** + * Combines 64b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param v + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint64_t +rte_combine64ms1b(uint64_t v) +{ + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + + return v; +} + +/** + * 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 uint32_t +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(uint32_t v, uint32_t *pos) +{ + if (v == 0) + return 0; + + *pos = rte_bsf32(v); + return 1; +} + +/** + * 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 uint32_t +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 32. + * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 + * + * @param x + * The input parameter. + * @return + * The last (most-significant) bit set, or 0 if the input is 0. + */ +static inline uint32_t +rte_fls_u32(uint32_t x) +{ + return (x == 0) ? 0 : 32 - __builtin_clz(x); +} + +/** + * 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 uint32_t +rte_fls_u64(uint64_t x) +{ + return (x == 0) ? 0 : 64 - __builtin_clzll(x); +} + +/*********** Macros to work with powers of 2 ********/ + +/** + * Macro to return 1 if n is a power of 2, 0 otherwise + */ +#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) + +/** + * Returns true if n is a power of 2 + * @param n + * Number to check + * @return 1 if true, 0 otherwise + */ +static inline int +rte_is_power_of_2(uint32_t n) +{ + return n && !(n & (n - 1)); +} + +/** + * Aligns input parameter to the next power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint32_t +rte_align32pow2(uint32_t x) +{ + x--; + x = rte_combine32ms1b(x); + + return x + 1; +} + +/** + * Aligns input parameter to the previous power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint32_t +rte_align32prevpow2(uint32_t x) +{ + x = rte_combine32ms1b(x); + + return x - (x >> 1); +} + +/** + * Aligns 64b input parameter to the next power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint64_t +rte_align64pow2(uint64_t v) +{ + v--; + v = rte_combine64ms1b(v); + + return v + 1; +} + +/** + * Aligns 64b input parameter to the previous power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint64_t +rte_align64prevpow2(uint64_t v) +{ + v = rte_combine64ms1b(v); + + return v - (v >> 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 + * The rounded-up log2 of the input, or 0 if the input is 0. + */ +static inline uint32_t +rte_log2_u32(uint32_t v) +{ + if (v == 0) + return 0; + v = rte_align32pow2(v); + return rte_bsf32(v); +} + +/** + * 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); +} + #ifdef __cplusplus } #endif diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h index 15765b4..c5ad69c 100644 --- a/lib/eal/include/rte_common.h +++ b/lib/eal/include/rte_common.h @@ -471,140 +471,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /** Marker for 8B alignment in a structure. */ __extension__ typedef uint64_t RTE_MARKER64[0]; -/** - * Combines 32b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param x - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint32_t -rte_combine32ms1b(uint32_t x) -{ - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - - return x; -} - -/** - * Combines 64b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param v - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint64_t -rte_combine64ms1b(uint64_t v) -{ - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - - return v; -} - -/*********** Macros to work with powers of 2 ********/ - -/** - * Macro to return 1 if n is a power of 2, 0 otherwise - */ -#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) - -/** - * Returns true if n is a power of 2 - * @param n - * Number to check - * @return 1 if true, 0 otherwise - */ -static inline int -rte_is_power_of_2(uint32_t n) -{ - return n && !(n & (n - 1)); -} - -/** - * Aligns input parameter to the next power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint32_t -rte_align32pow2(uint32_t x) -{ - x--; - x = rte_combine32ms1b(x); - - return x + 1; -} - -/** - * Aligns input parameter to the previous power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint32_t -rte_align32prevpow2(uint32_t x) -{ - x = rte_combine32ms1b(x); - - return x - (x >> 1); -} - -/** - * Aligns 64b input parameter to the next power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint64_t -rte_align64pow2(uint64_t v) -{ - v--; - v = rte_combine64ms1b(v); - - return v + 1; -} - -/** - * Aligns 64b input parameter to the previous power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint64_t -rte_align64prevpow2(uint64_t v) -{ - v = rte_combine64ms1b(v); - - return v - (v >> 1); -} - /*********** Macros for calculating min and max **********/ /** @@ -629,165 +495,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /*********** Other general functions / macros ********/ -/** - * 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 uint32_t -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(uint32_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 - * The rounded-up log2 of the input, or 0 if the input is 0. - */ -static inline uint32_t -rte_log2_u32(uint32_t v) -{ - if (v == 0) - return 0; - v = rte_align32pow2(v); - return rte_bsf32(v); -} - - -/** - * Return the last (most-significant) bit set. - * - * @note The last (most significant) bit is at position 32. - * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 - * - * @param x - * The input parameter. - * @return - * The last (most-significant) bit set, or 0 if the input is 0. - */ -static inline uint32_t -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 uint32_t -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 uint32_t -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. */ #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v7 2/4] eal: provide abstracted bit count functions 2023-04-01 0:45 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 1/4] eal: move bit count functions to bitops header Tyler Retzlaff @ 2023-04-01 0:45 ` Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 3/4] pipeline: add include of bitops Tyler Retzlaff ` (2 subsequent siblings) 4 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-01 0:45 UTC (permalink / raw) To: dev Cc: thomas, stephen, mb, bruce.richardson, ferruh.yigit, david.marchand, Tyler Retzlaff Provide abstracted bit counting functions for count, leading and trailing bits in v to hide compiler specific intrinsics and builtins. Include basic unit test of following functions added. rte_clz32 rte_clz64 rte_ctz32 rte_ctz64 rte_popcount32 rte_popcount64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> Acked-by: Morten Brørup <mb@smartsharesystems.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com> --- app/test/meson.build | 2 + app/test/test_bitcount.c | 136 ++++++++++++++++++++++++ lib/eal/include/rte_bitops.h | 240 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 378 insertions(+) create mode 100644 app/test/test_bitcount.c diff --git a/app/test/meson.build b/app/test/meson.build index b9b5432..dafd509 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -13,6 +13,7 @@ test_sources = files( 'test_alarm.c', 'test_atomic.c', 'test_barrier.c', + 'test_bitcount.c', 'test_bitops.c', 'test_bitmap.c', 'test_bpf.c', @@ -161,6 +162,7 @@ test_deps += ['bus_pci', 'bus_vdev'] fast_tests = [ ['acl_autotest', true, true], ['atomic_autotest', false, true], + ['bitcount_autotest', true, true], ['bitmap_autotest', true, true], ['bpf_autotest', true, true], ['bpf_convert_autotest', true, true], diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c new file mode 100644 index 0000000..5287ef7 --- /dev/null +++ b/app/test/test_bitcount.c @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#include <limits.h> +#include <string.h> + +#include <rte_bitops.h> +#include <rte_debug.h> + +#include "test.h" + +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); + +static int +test_clz32(void) +{ + size_t leading; + uint32_t v = 0xffffffff; + + for (leading = 0; v; leading++) { + RTE_TEST_ASSERT(rte_clz32(v) == leading, + "Unexpected count."); + v >>= 1; + } + + return 0; +} + +static int +test_clz64(void) +{ + size_t leading; + uint64_t v = 0xffffffffffffffff; + + for (leading = 0; v; leading++) { + RTE_TEST_ASSERT(rte_clz64(v) == leading, + "Unexpected count."); + v >>= 1; + } + + return 0; +} + +static int +test_ctz32(void) +{ + size_t trailing; + uint32_t v = 1; + + for (trailing = 0; v; trailing++) { + RTE_TEST_ASSERT(rte_ctz32(v) == trailing, + "Unexpected count."); + v <<= 1; + } + + return 0; +} + +static int +test_ctz64(void) +{ + size_t trailing; + uint64_t v = 1; + + for (trailing = 0; v; trailing++) { + RTE_TEST_ASSERT(rte_ctz64(v) == trailing, + "Unexpected count."); + v <<= 1; + } + + return 0; +} + +static int +test_popcount32(void) +{ + size_t shift; + uint32_t v = 0; + const size_t bits = sizeof(v) * CHAR_BIT; + + for (shift = 0; shift < bits; shift++) { + RTE_TEST_ASSERT(rte_popcount32(v) == shift, + "Unexpected count."); + v <<= 1; + v |= 1; + } + + RTE_TEST_ASSERT(rte_popcount32(v) == bits, + "Unexpected count."); + + return 0; +} + +static int +test_popcount64(void) +{ + size_t shift; + uint64_t v = 0; + const size_t bits = sizeof(v) * CHAR_BIT; + + for (shift = 0; shift < bits; shift++) { + RTE_TEST_ASSERT(rte_popcount64(v) == shift, + "Unexpected count."); + v <<= 1; + v |= 1; + } + + RTE_TEST_ASSERT(rte_popcount64(v) == bits, + "Unexpected count."); + + return 0; +} + +static struct unit_test_suite bitcount_test_suite = { + .suite_name = "bitcount autotest", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + TEST_CASE(test_clz32), + TEST_CASE(test_clz64), + TEST_CASE(test_ctz32), + TEST_CASE(test_ctz64), + TEST_CASE(test_popcount32), + TEST_CASE(test_popcount64), + TEST_CASES_END() + } +}; + +static int +test_bitcount(void) +{ + return unit_test_suite_runner(&bitcount_test_suite); +} + +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index 531479e..d45aa54 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2020 Arm Limited + * Copyright(c) 2010-2019 Intel Corporation + * Copyright(c) 2023 Microsoft Corporation */ #ifndef _RTE_BITOPS_H_ @@ -275,6 +277,244 @@ return val & mask; } +#ifdef RTE_TOOLCHAIN_MSVC + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanReverse64(&rv, v); + + return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanForward64(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of 1-bits in v. + * + * @param v + * The value. + * @return + * The count of 1-bits. + */ +__rte_experimental +static inline unsigned int +rte_popcount32(uint32_t v) +{ + return (unsigned int)__popcnt(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of 1-bits in v. + * + * @param v + * The value. + * @return + * The count of 1-bits. + */ +__rte_experimental +static inline unsigned int +rte_popcount64(uint64_t v) +{ + return (unsigned int)__popcnt64(v); +} + +#else + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + return (unsigned int)__builtin_clz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + return (unsigned int)__builtin_clzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + return (unsigned int)__builtin_ctz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + return (unsigned int)__builtin_ctzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of 1-bits in v. + * + * @param v + * The value. + * @return + * The count of 1-bits. + */ +__rte_experimental +static inline unsigned int +rte_popcount32(uint32_t v) +{ + return (unsigned int)__builtin_popcount(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of 1-bits in v. + * + * @param v + * The value. + * @return + * The count of 1-bits. + */ +__rte_experimental +static inline unsigned int +rte_popcount64(uint64_t v) +{ + return (unsigned int)__builtin_popcountll(v); +} + +#endif + /** * Combines 32b inputs most significant set bits into the least * significant bits to construct a value with the same MSBs as x -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v7 3/4] pipeline: add include of bitops 2023-04-01 0:45 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 1/4] eal: move bit count functions to bitops header Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 2/4] eal: provide abstracted bit count functions Tyler Retzlaff @ 2023-04-01 0:45 ` Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 4/4] maintainers: add bitcount test under EAL API and common code Tyler Retzlaff 2023-04-01 7:08 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Morten Brørup 4 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-01 0:45 UTC (permalink / raw) To: dev Cc: thomas, stephen, mb, bruce.richardson, ferruh.yigit, david.marchand, Tyler Retzlaff Include rte_bitops.h with the inline functions moving this include is now needed. Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- lib/pipeline/rte_swx_pipeline_internal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pipeline/rte_swx_pipeline_internal.h b/lib/pipeline/rte_swx_pipeline_internal.h index 2f24e1a..a67b6e9 100644 --- a/lib/pipeline/rte_swx_pipeline_internal.h +++ b/lib/pipeline/rte_swx_pipeline_internal.h @@ -8,6 +8,7 @@ #include <string.h> #include <sys/queue.h> +#include <rte_bitops.h> #include <rte_byteorder.h> #include <rte_common.h> #include <rte_cycles.h> -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v7 4/4] maintainers: add bitcount test under EAL API and common code 2023-04-01 0:45 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Tyler Retzlaff ` (2 preceding siblings ...) 2023-04-01 0:45 ` [PATCH v7 3/4] pipeline: add include of bitops Tyler Retzlaff @ 2023-04-01 0:45 ` Tyler Retzlaff 2023-04-01 7:08 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Morten Brørup 4 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-01 0:45 UTC (permalink / raw) To: dev Cc: thomas, stephen, mb, bruce.richardson, ferruh.yigit, david.marchand, Tyler Retzlaff List app/test/test_bitcount.c under EAL API and common code. Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8df23e5..c2995bb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -155,6 +155,7 @@ F: doc/guides/prog_guide/env_abstraction_layer.rst F: app/test/test_alarm.c F: app/test/test_atomic.c F: app/test/test_barrier.c +F: app/test/test_bitcount.c F: app/test/test_byteorder.c F: app/test/test_common.c F: app/test/test_cpuflags.c -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* RE: [PATCH v7 0/4] eal: provide abstracted bit counting functions 2023-04-01 0:45 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Tyler Retzlaff ` (3 preceding siblings ...) 2023-04-01 0:45 ` [PATCH v7 4/4] maintainers: add bitcount test under EAL API and common code Tyler Retzlaff @ 2023-04-01 7:08 ` Morten Brørup 4 siblings, 0 replies; 81+ messages in thread From: Morten Brørup @ 2023-04-01 7:08 UTC (permalink / raw) To: Tyler Retzlaff, dev Cc: thomas, stephen, bruce.richardson, ferruh.yigit, david.marchand > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com] > Sent: Saturday, 1 April 2023 02.45 [...] > > note: > Morten Brørup and Bruce Richardson previous acks have been preserved > but be aware of the two additional functions introduced in v7. If you > wish to withdraw your ack, please let me know but I believe the 2 > additions are consistent with previous. The additions check out OK. My Ack remains. :-) ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v8 0/3] eal: provide abstracted bit counting functions 2022-11-23 22:14 [PATCH 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff ` (6 preceding siblings ...) 2023-04-01 0:45 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Tyler Retzlaff @ 2023-04-04 0:11 ` Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 1/3] eal: move bit count functions to bitops header Tyler Retzlaff ` (4 more replies) 7 siblings, 5 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-04 0:11 UTC (permalink / raw) To: dev Cc: thomas, stephen, mb, bruce.richardson, ferruh.yigit, david.marchand, Tyler Retzlaff As discussed technical board meeting 2023-02-22 http://mails.dpdk.org/archives/dev/2023-February/263516.html We will bring support in pieces for the MSVC compiler, there will be some abstractions and functions introduced before the compiler is capable of compiling DPDK in order to make parallel progress while waiting for standard atomics in 23.07. A higher level plan / order of work is available in the Microsoft roadmap for 23.07 and 23.11. note: Bruce Richardson previous acks have been preserved but be aware of the two additional functions introduced in v7. If you wish to withdraw your ack, please let me know but I believe the 2 additions are consistent with previous. v8: * squish patch including rte_bitops.h in lib/pipeline into first patch. v7: * add 2 additional counting functions rte_popcount{32,64} including basic unit tests * fix patch 1 title link (CI complained too long) * add test_bitcount.c entry to MAINTAINERS file v6: * remove stray #include <stdio.h> v5: * fix implementation of msvc versions of rte_clz{32,64} incorrect use of _BitscanReverse{,64} index. * fix and expand unit test to exercise full range of counting over uint{32,64}_t input values. (which would have caught above mistake). * reduce commit title length * correct commit author v4: * combine unit test commit into function addition commit v3: * rename to use 32/64 instead of l/ll suffixes * add new functions to rte_bitops.h instead of new header * move other bit functions from rte_common.h to rte_bitops.h v2: * use unsigned int instead of unsigned (checkpatches) * match multiple include guard naming convention to rte_common.h * add explicit extern "C" linkage to rte_bitcount.h note: not really needed but checkpatches required * add missing space around '-' Tyler Retzlaff (3): eal: move bit count functions to bitops header eal: provide abstracted bit count functions maintainers: add bitcount test under EAL API and common code MAINTAINERS | 1 + app/test/meson.build | 2 + app/test/test_bitcount.c | 136 ++++++++ app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 532 +++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ----------------- lib/pipeline/rte_swx_pipeline_internal.h | 1 + 8 files changed, 674 insertions(+), 293 deletions(-) create mode 100644 app/test/test_bitcount.c -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v8 1/3] eal: move bit count functions to bitops header 2023-04-04 0:11 ` [PATCH v8 0/3] " Tyler Retzlaff @ 2023-04-04 0:11 ` Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 2/3] eal: provide abstracted bit count functions Tyler Retzlaff ` (3 subsequent siblings) 4 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-04 0:11 UTC (permalink / raw) To: dev Cc: thomas, stephen, mb, bruce.richardson, ferruh.yigit, david.marchand, Tyler Retzlaff Move the following inline functions from rte_common.h to rte_bitops.h rte_combine32ms1b rte_combine64ms1b rte_bsf32 rte_bsf32_safe rte_bsf64 rte_bsf64_safe rte_fls_u32 rte_fls_u64 rte_is_power_of_2 rte_align32pow2 rte_align32prevpow2 rte_align64pow2 rte_align64prevpow2 rte_log2_u32 rte_log2_u64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> Acked-by: Ferruh Yigit <ferruh.yigit@amd.com> Acked-by: Morten Brørup <mb@smartsharesystems.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com> --- app/test/test_common.c | 1 + lib/eal/common/rte_reciprocal.c | 1 + lib/eal/include/rte_bitops.h | 292 ++++++++++++++++++++++++++++++ lib/eal/include/rte_common.h | 293 ------------------------------- lib/pipeline/rte_swx_pipeline_internal.h | 1 + 5 files changed, 295 insertions(+), 293 deletions(-) diff --git a/app/test/test_common.c b/app/test/test_common.c index f89e1eb..cf4a2c7 100644 --- a/app/test/test_common.c +++ b/app/test/test_common.c @@ -7,6 +7,7 @@ #include <string.h> #include <math.h> #include <rte_common.h> +#include <rte_bitops.h> #include <rte_hexdump.h> #include <rte_pause.h> diff --git a/lib/eal/common/rte_reciprocal.c b/lib/eal/common/rte_reciprocal.c index 42dfa44..d47dc47 100644 --- a/lib/eal/common/rte_reciprocal.c +++ b/lib/eal/common/rte_reciprocal.c @@ -8,6 +8,7 @@ #include <stdint.h> #include <rte_common.h> +#include <rte_bitops.h> #include "rte_reciprocal.h" diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index f50dbe4..531479e 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -275,6 +275,298 @@ return val & mask; } +/** + * Combines 32b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param x + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint32_t +rte_combine32ms1b(uint32_t x) +{ + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return x; +} + +/** + * Combines 64b inputs most significant set bits into the least + * significant bits to construct a value with the same MSBs as x + * but all 1's under it. + * + * @param v + * The integer whose MSBs need to be combined with its LSBs + * @return + * The combined value. + */ +static inline uint64_t +rte_combine64ms1b(uint64_t v) +{ + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + + return v; +} + +/** + * 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 uint32_t +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(uint32_t v, uint32_t *pos) +{ + if (v == 0) + return 0; + + *pos = rte_bsf32(v); + return 1; +} + +/** + * 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 uint32_t +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 32. + * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 + * + * @param x + * The input parameter. + * @return + * The last (most-significant) bit set, or 0 if the input is 0. + */ +static inline uint32_t +rte_fls_u32(uint32_t x) +{ + return (x == 0) ? 0 : 32 - __builtin_clz(x); +} + +/** + * 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 uint32_t +rte_fls_u64(uint64_t x) +{ + return (x == 0) ? 0 : 64 - __builtin_clzll(x); +} + +/*********** Macros to work with powers of 2 ********/ + +/** + * Macro to return 1 if n is a power of 2, 0 otherwise + */ +#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) + +/** + * Returns true if n is a power of 2 + * @param n + * Number to check + * @return 1 if true, 0 otherwise + */ +static inline int +rte_is_power_of_2(uint32_t n) +{ + return n && !(n & (n - 1)); +} + +/** + * Aligns input parameter to the next power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint32_t +rte_align32pow2(uint32_t x) +{ + x--; + x = rte_combine32ms1b(x); + + return x + 1; +} + +/** + * Aligns input parameter to the previous power of 2 + * + * @param x + * The integer value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint32_t +rte_align32prevpow2(uint32_t x) +{ + x = rte_combine32ms1b(x); + + return x - (x >> 1); +} + +/** + * Aligns 64b input parameter to the next power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the next power of 2 + */ +static inline uint64_t +rte_align64pow2(uint64_t v) +{ + v--; + v = rte_combine64ms1b(v); + + return v + 1; +} + +/** + * Aligns 64b input parameter to the previous power of 2 + * + * @param v + * The 64b value to align + * + * @return + * Input parameter aligned to the previous power of 2 + */ +static inline uint64_t +rte_align64prevpow2(uint64_t v) +{ + v = rte_combine64ms1b(v); + + return v - (v >> 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 + * The rounded-up log2 of the input, or 0 if the input is 0. + */ +static inline uint32_t +rte_log2_u32(uint32_t v) +{ + if (v == 0) + return 0; + v = rte_align32pow2(v); + return rte_bsf32(v); +} + +/** + * 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); +} + #ifdef __cplusplus } #endif diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h index 15765b4..c5ad69c 100644 --- a/lib/eal/include/rte_common.h +++ b/lib/eal/include/rte_common.h @@ -471,140 +471,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /** Marker for 8B alignment in a structure. */ __extension__ typedef uint64_t RTE_MARKER64[0]; -/** - * Combines 32b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param x - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint32_t -rte_combine32ms1b(uint32_t x) -{ - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - - return x; -} - -/** - * Combines 64b inputs most significant set bits into the least - * significant bits to construct a value with the same MSBs as x - * but all 1's under it. - * - * @param v - * The integer whose MSBs need to be combined with its LSBs - * @return - * The combined value. - */ -static inline uint64_t -rte_combine64ms1b(uint64_t v) -{ - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v |= v >> 32; - - return v; -} - -/*********** Macros to work with powers of 2 ********/ - -/** - * Macro to return 1 if n is a power of 2, 0 otherwise - */ -#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n))) - -/** - * Returns true if n is a power of 2 - * @param n - * Number to check - * @return 1 if true, 0 otherwise - */ -static inline int -rte_is_power_of_2(uint32_t n) -{ - return n && !(n & (n - 1)); -} - -/** - * Aligns input parameter to the next power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint32_t -rte_align32pow2(uint32_t x) -{ - x--; - x = rte_combine32ms1b(x); - - return x + 1; -} - -/** - * Aligns input parameter to the previous power of 2 - * - * @param x - * The integer value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint32_t -rte_align32prevpow2(uint32_t x) -{ - x = rte_combine32ms1b(x); - - return x - (x >> 1); -} - -/** - * Aligns 64b input parameter to the next power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the next power of 2 - */ -static inline uint64_t -rte_align64pow2(uint64_t v) -{ - v--; - v = rte_combine64ms1b(v); - - return v + 1; -} - -/** - * Aligns 64b input parameter to the previous power of 2 - * - * @param v - * The 64b value to align - * - * @return - * Input parameter aligned to the previous power of 2 - */ -static inline uint64_t -rte_align64prevpow2(uint64_t v) -{ - v = rte_combine64ms1b(v); - - return v - (v >> 1); -} - /*********** Macros for calculating min and max **********/ /** @@ -629,165 +495,6 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) /*********** Other general functions / macros ********/ -/** - * 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 uint32_t -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(uint32_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 - * The rounded-up log2 of the input, or 0 if the input is 0. - */ -static inline uint32_t -rte_log2_u32(uint32_t v) -{ - if (v == 0) - return 0; - v = rte_align32pow2(v); - return rte_bsf32(v); -} - - -/** - * Return the last (most-significant) bit set. - * - * @note The last (most significant) bit is at position 32. - * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 - * - * @param x - * The input parameter. - * @return - * The last (most-significant) bit set, or 0 if the input is 0. - */ -static inline uint32_t -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 uint32_t -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 uint32_t -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. */ #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) diff --git a/lib/pipeline/rte_swx_pipeline_internal.h b/lib/pipeline/rte_swx_pipeline_internal.h index 2f24e1a..a67b6e9 100644 --- a/lib/pipeline/rte_swx_pipeline_internal.h +++ b/lib/pipeline/rte_swx_pipeline_internal.h @@ -8,6 +8,7 @@ #include <string.h> #include <sys/queue.h> +#include <rte_bitops.h> #include <rte_byteorder.h> #include <rte_common.h> #include <rte_cycles.h> -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v8 2/3] eal: provide abstracted bit count functions 2023-04-04 0:11 ` [PATCH v8 0/3] " Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 1/3] eal: move bit count functions to bitops header Tyler Retzlaff @ 2023-04-04 0:11 ` Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 3/3] maintainers: add bitcount test under EAL API and common code Tyler Retzlaff ` (2 subsequent siblings) 4 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-04 0:11 UTC (permalink / raw) To: dev Cc: thomas, stephen, mb, bruce.richardson, ferruh.yigit, david.marchand, Tyler Retzlaff Provide abstracted bit counting functions for count, leading and trailing bits in v to hide compiler specific intrinsics and builtins. Include basic unit test of following functions added. rte_clz32 rte_clz64 rte_ctz32 rte_ctz64 rte_popcount32 rte_popcount64 Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> Acked-by: Morten Brørup <mb@smartsharesystems.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com> --- app/test/meson.build | 2 + app/test/test_bitcount.c | 136 ++++++++++++++++++++++++ lib/eal/include/rte_bitops.h | 240 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 378 insertions(+) create mode 100644 app/test/test_bitcount.c diff --git a/app/test/meson.build b/app/test/meson.build index b9b5432..dafd509 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -13,6 +13,7 @@ test_sources = files( 'test_alarm.c', 'test_atomic.c', 'test_barrier.c', + 'test_bitcount.c', 'test_bitops.c', 'test_bitmap.c', 'test_bpf.c', @@ -161,6 +162,7 @@ test_deps += ['bus_pci', 'bus_vdev'] fast_tests = [ ['acl_autotest', true, true], ['atomic_autotest', false, true], + ['bitcount_autotest', true, true], ['bitmap_autotest', true, true], ['bpf_autotest', true, true], ['bpf_convert_autotest', true, true], diff --git a/app/test/test_bitcount.c b/app/test/test_bitcount.c new file mode 100644 index 0000000..5287ef7 --- /dev/null +++ b/app/test/test_bitcount.c @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2022 Microsoft Corporation + */ + +#include <limits.h> +#include <string.h> + +#include <rte_bitops.h> +#include <rte_debug.h> + +#include "test.h" + +RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); + +static int +test_clz32(void) +{ + size_t leading; + uint32_t v = 0xffffffff; + + for (leading = 0; v; leading++) { + RTE_TEST_ASSERT(rte_clz32(v) == leading, + "Unexpected count."); + v >>= 1; + } + + return 0; +} + +static int +test_clz64(void) +{ + size_t leading; + uint64_t v = 0xffffffffffffffff; + + for (leading = 0; v; leading++) { + RTE_TEST_ASSERT(rte_clz64(v) == leading, + "Unexpected count."); + v >>= 1; + } + + return 0; +} + +static int +test_ctz32(void) +{ + size_t trailing; + uint32_t v = 1; + + for (trailing = 0; v; trailing++) { + RTE_TEST_ASSERT(rte_ctz32(v) == trailing, + "Unexpected count."); + v <<= 1; + } + + return 0; +} + +static int +test_ctz64(void) +{ + size_t trailing; + uint64_t v = 1; + + for (trailing = 0; v; trailing++) { + RTE_TEST_ASSERT(rte_ctz64(v) == trailing, + "Unexpected count."); + v <<= 1; + } + + return 0; +} + +static int +test_popcount32(void) +{ + size_t shift; + uint32_t v = 0; + const size_t bits = sizeof(v) * CHAR_BIT; + + for (shift = 0; shift < bits; shift++) { + RTE_TEST_ASSERT(rte_popcount32(v) == shift, + "Unexpected count."); + v <<= 1; + v |= 1; + } + + RTE_TEST_ASSERT(rte_popcount32(v) == bits, + "Unexpected count."); + + return 0; +} + +static int +test_popcount64(void) +{ + size_t shift; + uint64_t v = 0; + const size_t bits = sizeof(v) * CHAR_BIT; + + for (shift = 0; shift < bits; shift++) { + RTE_TEST_ASSERT(rte_popcount64(v) == shift, + "Unexpected count."); + v <<= 1; + v |= 1; + } + + RTE_TEST_ASSERT(rte_popcount64(v) == bits, + "Unexpected count."); + + return 0; +} + +static struct unit_test_suite bitcount_test_suite = { + .suite_name = "bitcount autotest", + .setup = NULL, + .teardown = NULL, + .unit_test_cases = { + TEST_CASE(test_clz32), + TEST_CASE(test_clz64), + TEST_CASE(test_ctz32), + TEST_CASE(test_ctz64), + TEST_CASE(test_popcount32), + TEST_CASE(test_popcount64), + TEST_CASES_END() + } +}; + +static int +test_bitcount(void) +{ + return unit_test_suite_runner(&bitcount_test_suite); +} + +REGISTER_TEST_COMMAND(bitcount_autotest, test_bitcount); diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index 531479e..d45aa54 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2020 Arm Limited + * Copyright(c) 2010-2019 Intel Corporation + * Copyright(c) 2023 Microsoft Corporation */ #ifndef _RTE_BITOPS_H_ @@ -275,6 +277,244 @@ return val & mask; } +#ifdef RTE_TOOLCHAIN_MSVC + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanReverse(&rv, v); + + return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanReverse64(&rv, v); + + return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + unsigned long rv; + + (void)_BitScanForward(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + unsigned long rv; + + (void)_BitScanForward64(&rv, v); + + return (unsigned int)rv; +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of 1-bits in v. + * + * @param v + * The value. + * @return + * The count of 1-bits. + */ +__rte_experimental +static inline unsigned int +rte_popcount32(uint32_t v) +{ + return (unsigned int)__popcnt(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of 1-bits in v. + * + * @param v + * The value. + * @return + * The count of 1-bits. + */ +__rte_experimental +static inline unsigned int +rte_popcount64(uint64_t v) +{ + return (unsigned int)__popcnt64(v); +} + +#else + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz32(uint32_t v) +{ + return (unsigned int)__builtin_clz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of leading 0-bits in v. + * + * @param v + * The value. + * @return + * The count of leading zero bits. + */ +__rte_experimental +static inline unsigned int +rte_clz64(uint64_t v) +{ + return (unsigned int)__builtin_clzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz32(uint32_t v) +{ + return (unsigned int)__builtin_ctz(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of trailing 0-bits in v. + * + * @param v + * The value. + * @return + * The count of trailing zero bits. + */ +__rte_experimental +static inline unsigned int +rte_ctz64(uint64_t v) +{ + return (unsigned int)__builtin_ctzll(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of 1-bits in v. + * + * @param v + * The value. + * @return + * The count of 1-bits. + */ +__rte_experimental +static inline unsigned int +rte_popcount32(uint32_t v) +{ + return (unsigned int)__builtin_popcount(v); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Get the count of 1-bits in v. + * + * @param v + * The value. + * @return + * The count of 1-bits. + */ +__rte_experimental +static inline unsigned int +rte_popcount64(uint64_t v) +{ + return (unsigned int)__builtin_popcountll(v); +} + +#endif + /** * Combines 32b inputs most significant set bits into the least * significant bits to construct a value with the same MSBs as x -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v8 3/3] maintainers: add bitcount test under EAL API and common code 2023-04-04 0:11 ` [PATCH v8 0/3] " Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 1/3] eal: move bit count functions to bitops header Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 2/3] eal: provide abstracted bit count functions Tyler Retzlaff @ 2023-04-04 0:11 ` Tyler Retzlaff 2023-04-04 8:27 ` [PATCH v8 0/3] eal: provide abstracted bit counting functions Bruce Richardson 2023-08-25 8:41 ` David Marchand 4 siblings, 0 replies; 81+ messages in thread From: Tyler Retzlaff @ 2023-04-04 0:11 UTC (permalink / raw) To: dev Cc: thomas, stephen, mb, bruce.richardson, ferruh.yigit, david.marchand, Tyler Retzlaff List app/test/test_bitcount.c under EAL API and common code. Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com> --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8df23e5..c2995bb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -155,6 +155,7 @@ F: doc/guides/prog_guide/env_abstraction_layer.rst F: app/test/test_alarm.c F: app/test/test_atomic.c F: app/test/test_barrier.c +F: app/test/test_bitcount.c F: app/test/test_byteorder.c F: app/test/test_common.c F: app/test/test_cpuflags.c -- 1.8.3.1 ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v8 0/3] eal: provide abstracted bit counting functions 2023-04-04 0:11 ` [PATCH v8 0/3] " Tyler Retzlaff ` (2 preceding siblings ...) 2023-04-04 0:11 ` [PATCH v8 3/3] maintainers: add bitcount test under EAL API and common code Tyler Retzlaff @ 2023-04-04 8:27 ` Bruce Richardson 2023-08-25 8:41 ` David Marchand 4 siblings, 0 replies; 81+ messages in thread From: Bruce Richardson @ 2023-04-04 8:27 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: dev, thomas, stephen, mb, ferruh.yigit, david.marchand On Mon, Apr 03, 2023 at 05:11:55PM -0700, Tyler Retzlaff wrote: > As discussed technical board meeting 2023-02-22 > http://mails.dpdk.org/archives/dev/2023-February/263516.html > > We will bring support in pieces for the MSVC compiler, there will be > some abstractions and functions introduced before the compiler is > capable of compiling DPDK in order to make parallel progress > while waiting for standard atomics in 23.07. > > A higher level plan / order of work is available in the Microsoft > roadmap for 23.07 and 23.11. > > note: > Bruce Richardson previous acks have been preserved but be aware of > the two additional functions introduced in v7. If you wish to withdraw > your ack, please let me know but I believe the 2 additions are consistent > with previous. > All good, keeping them is fine. Thanks, /Bruce ^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v8 0/3] eal: provide abstracted bit counting functions 2023-04-04 0:11 ` [PATCH v8 0/3] " Tyler Retzlaff ` (3 preceding siblings ...) 2023-04-04 8:27 ` [PATCH v8 0/3] eal: provide abstracted bit counting functions Bruce Richardson @ 2023-08-25 8:41 ` David Marchand 4 siblings, 0 replies; 81+ messages in thread From: David Marchand @ 2023-08-25 8:41 UTC (permalink / raw) To: Tyler Retzlaff; +Cc: dev, thomas, stephen, mb, bruce.richardson, ferruh.yigit On Tue, Apr 4, 2023 at 2:12 AM Tyler Retzlaff <roretzla@linux.microsoft.com> wrote: > > As discussed technical board meeting 2023-02-22 > http://mails.dpdk.org/archives/dev/2023-February/263516.html > > We will bring support in pieces for the MSVC compiler, there will be > some abstractions and functions introduced before the compiler is > capable of compiling DPDK in order to make parallel progress > while waiting for standard atomics in 23.07. > > A higher level plan / order of work is available in the Microsoft > roadmap for 23.07 and 23.11. I rebased this series following Bruce rework on app/test/ and applied it. Thanks. -- David Marchand ^ permalink raw reply [flat|nested] 81+ messages in thread
end of thread, other threads:[~2023-08-25 8:41 UTC | newest] Thread overview: 81+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-11-23 22:14 [PATCH 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff 2022-11-23 22:14 ` [PATCH 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-04-03 21:46 ` Mattias Rönnblom 2022-11-23 22:14 ` [PATCH 2/2] test/bitcount: add bitcount tests Tyler Retzlaff 2022-11-23 23:43 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff 2022-11-23 23:43 ` [PATCH v2 1/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2022-11-24 10:17 ` Morten Brørup 2022-11-28 17:13 ` Tyler Retzlaff 2022-11-28 17:22 ` Morten Brørup 2022-11-28 17:27 ` Tyler Retzlaff 2023-01-05 9:04 ` Thomas Monjalon 2023-01-05 17:23 ` Tyler Retzlaff 2023-01-05 17:27 ` Tyler Retzlaff 2023-01-05 20:57 ` Tyler Retzlaff 2023-01-05 21:34 ` Morten Brørup 2023-01-05 22:06 ` Tyler Retzlaff 2023-01-05 23:10 ` Morten Brørup 2023-01-06 1:04 ` Tyler Retzlaff 2023-01-06 10:09 ` Thomas Monjalon 2023-01-06 10:00 ` Thomas Monjalon 2023-01-05 7:09 ` Morten Brørup 2023-01-05 9:01 ` Thomas Monjalon 2023-01-05 17:21 ` Tyler Retzlaff 2023-01-06 0:32 ` Stephen Hemminger 2023-01-06 11:48 ` Bruce Richardson 2023-01-06 12:41 ` Morten Brørup 2023-01-06 13:40 ` Thomas Monjalon 2023-01-06 18:58 ` Tyler Retzlaff 2023-01-06 20:51 ` Thomas Monjalon 2023-01-10 9:18 ` Ferruh Yigit 2023-01-06 18:47 ` Tyler Retzlaff 2023-01-09 8:50 ` Bruce Richardson 2023-04-04 21:23 ` Tyler Retzlaff 2023-04-05 8:44 ` Bruce Richardson 2023-04-05 15:22 ` Tyler Retzlaff 2023-04-05 15:51 ` Bruce Richardson 2023-04-05 17:25 ` Tyler Retzlaff 2022-11-23 23:43 ` [PATCH v2 2/2] test/bitcount: add bitcount tests Tyler Retzlaff 2023-01-04 23:46 ` [PATCH v2 0/2] eal: provide leading and trailing zero bit count Tyler Retzlaff 2023-01-09 17:36 ` [PATCH v4 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-09 17:36 ` [PATCH v4 1/2] eal: move bit operation functions from common to bitops header Tyler Retzlaff 2023-01-10 13:56 ` Ferruh Yigit 2023-01-09 17:36 ` [PATCH v4 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-10 13:55 ` Ferruh Yigit 2023-01-10 17:34 ` Tyler Retzlaff 2023-01-10 18:37 ` Tyler Retzlaff 2023-01-10 13:56 ` [PATCH v4 0/2] " Ferruh Yigit 2023-01-06 22:01 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Tyler Retzlaff 2023-01-06 22:01 ` [PATCH v3 1/3] eal: move bit functions from common to bitops header Tyler Retzlaff 2023-01-06 22:01 ` [PATCH v3 2/3] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-06 22:01 ` [PATCH v3 3/3] test/bitcount: add bitcount tests Tyler Retzlaff 2023-01-07 8:15 ` Thomas Monjalon 2023-01-09 16:57 ` Tyler Retzlaff 2023-01-09 17:26 ` Tyler Retzlaff 2023-01-07 13:40 ` Morten Brørup 2023-01-09 8:51 ` [PATCH v3 0/3] eal: provide leading and trailing zero bit count Bruce Richardson 2023-01-10 19:38 ` [PATCH v5 0/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-10 19:38 ` [PATCH v5 1/2] eal: move bit operation common to bitops header Tyler Retzlaff 2023-01-10 19:38 ` [PATCH v5 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-10 19:46 ` [PATCH v6 0/2] " Tyler Retzlaff 2023-01-10 19:46 ` [PATCH v6 1/2] eal: move bit operation common to bitops header Tyler Retzlaff 2023-01-10 19:46 ` [PATCH v6 2/2] eal: provide leading and trailing zero bit count abstraction Tyler Retzlaff 2023-01-20 22:14 ` [PATCH v6 0/2] " Tyler Retzlaff 2023-02-02 9:14 ` David Marchand 2023-02-02 10:56 ` David Marchand 2023-02-02 15:57 ` Tyler Retzlaff 2023-02-03 9:14 ` David Marchand 2023-02-02 15:56 ` Tyler Retzlaff 2023-02-03 9:21 ` David Marchand 2023-04-01 0:45 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 1/4] eal: move bit count functions to bitops header Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 2/4] eal: provide abstracted bit count functions Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 3/4] pipeline: add include of bitops Tyler Retzlaff 2023-04-01 0:45 ` [PATCH v7 4/4] maintainers: add bitcount test under EAL API and common code Tyler Retzlaff 2023-04-01 7:08 ` [PATCH v7 0/4] eal: provide abstracted bit counting functions Morten Brørup 2023-04-04 0:11 ` [PATCH v8 0/3] " Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 1/3] eal: move bit count functions to bitops header Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 2/3] eal: provide abstracted bit count functions Tyler Retzlaff 2023-04-04 0:11 ` [PATCH v8 3/3] maintainers: add bitcount test under EAL API and common code Tyler Retzlaff 2023-04-04 8:27 ` [PATCH v8 0/3] eal: provide abstracted bit counting functions Bruce Richardson 2023-08-25 8:41 ` David Marchand
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).