From 9d65053761ae20e81e651ac0f0a76649e142e8e5 Mon Sep 17 00:00:00 2001 From: Anatoly Burakov Date: Thu, 20 Dec 2018 12:09:50 +0000 Subject: [PATCH] eal: add 64-bit log2 function Add missing implementation for 64-bit log2 function, and extend the unit test to test this new function. Also, remove duplicate reimplementation of this function from testpmd and memalloc. Signed-off-by: Anatoly Burakov --- app/test-pmd/testpmd.c | 11 +---------- lib/librte_eal/common/include/rte_common.h | 18 ++++++++++++++++++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 11 +---------- test/test/test_common.c | 20 +++++++++++++++++++- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index d4d22afbb4..8d584b0081 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -649,22 +649,13 @@ calc_mem_size(uint32_t nb_mbufs, uint32_t mbuf_sz, size_t pgsz, size_t *out) return 0; } -static inline uint32_t -log2_u64(uint64_t v) -{ - if (v == 0) - return 0; - v = rte_align64pow2(v); - return rte_bsf64(v); -} - static int pagesz_flags(uint64_t page_sz) { /* as per mmap() manpage, all page sizes are log2 of page size * shifted by MAP_HUGE_SHIFT */ - int log2 = log2_u64(page_sz); + int log2 = rte_log2_u64(page_sz); return (log2 << HUGE_SHIFT); } diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h index 7b50b84795..7178ba1e9d 100644 --- a/lib/librte_eal/common/include/rte_common.h +++ b/lib/librte_eal/common/include/rte_common.h @@ -565,6 +565,24 @@ rte_fls_u64(uint64_t x) return (x == 0) ? 0 : 64 - __builtin_clzll(x); } +/** + * Return the rounded-up log2 of a 64-bit integer. + * + * @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/librte_eal/linuxapp/eal/eal_memalloc.c b/lib/librte_eal/linuxapp/eal/eal_memalloc.c index 04cd813943..60a0a680f6 100644 --- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c +++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c @@ -213,22 +213,13 @@ get_file_size(int fd) return st.st_size; } -static inline uint32_t -log2_u64(uint64_t v) -{ - if (v == 0) - return 0; - v = rte_align64pow2(v); - return rte_bsf64(v); -} - static int pagesz_flags(uint64_t page_sz) { /* as per mmap() manpage, all page sizes are log2 of page size * shifted by MAP_HUGE_SHIFT */ - int log2 = log2_u64(page_sz); + int log2 = rte_log2_u64(page_sz); return log2 << RTE_MAP_HUGE_SHIFT; } diff --git a/test/test/test_common.c b/test/test/test_common.c index f6dd4c18d8..94d3674712 100644 --- a/test/test/test_common.c +++ b/test/test/test_common.c @@ -213,13 +213,31 @@ test_log2(void) const uint32_t step = 1; for (i = 0; i < max; i = i + step) { + uint64_t i64; + + /* extend range for 64-bit */ + i64 = (uint64_t)i << 32; + base = (uint32_t)ceilf(log2(i64)); + compare = rte_log2_u64(i64); + if (base != compare) { + printf("Wrong rte_log2_u64(%" PRIx64 ") val %x, expected %x\n", + i64, compare, base); + return TEST_FAILED; + } + base = (uint32_t)ceilf(log2((uint32_t)i)); - compare = rte_log2_u32(i); + compare = rte_log2_u32((uint32_t)i); if (base != compare) { printf("Wrong rte_log2_u32(%x) val %x, expected %x\n", i, compare, base); return TEST_FAILED; } + compare = rte_log2_u64((uint64_t)i); + if (base != compare) { + printf("Wrong rte_log2_u64(%x) val %x, expected %x\n", + i, compare, base); + return TEST_FAILED; + } } return 0; } -- 2.20.1