From: "Richard W.M. Jones" <rjo...@redhat.com> Signed-off-by: Laszlo Ersek <ler...@redhat.com> (cherry picked from libnbd commit 27a9bb45c70dbb1112cab6bdc1a61b21f78bc6f4) --- configure.ac | 3 +++ common/include/ispowerof2.h | 13 +++++++++++++ common/include/test-ispowerof2.c | 10 ++++++++++ 3 files changed, 26 insertions(+)
diff --git a/configure.ac b/configure.ac index 9075b0eabda1..597097922831 100644 --- a/configure.ac +++ b/configure.ac @@ -344,6 +344,9 @@ test (void) ] ) +dnl Check sizeof long. +AC_CHECK_SIZEOF(long) + dnl Check for other headers, all optional. AC_CHECK_HEADERS([\ alloca.h \ diff --git a/common/include/ispowerof2.h b/common/include/ispowerof2.h index b9a5cc7caf01..c5bcb0c81077 100644 --- a/common/include/ispowerof2.h +++ b/common/include/ispowerof2.h @@ -46,4 +46,17 @@ is_power_of_2 (unsigned long v) return v && ((v & (v - 1)) == 0); } +/* Calculate log2(v) which is the size of the equivalent bit shift + * for a power of 2. For example log_2_bits (512) == 9. + * + * Note this is undefined for v == 0. + * + * __builtin_clzl is available in GCC and clang. + */ +static inline int +log_2_bits (unsigned long v) +{ + return SIZEOF_LONG*8 - __builtin_clzl (v) - 1; +} + #endif /* NBDKIT_ISPOWEROF2_H */ diff --git a/common/include/test-ispowerof2.c b/common/include/test-ispowerof2.c index 9f904b2fc5e8..fd880fa3b551 100644 --- a/common/include/test-ispowerof2.c +++ b/common/include/test-ispowerof2.c @@ -58,5 +58,15 @@ main (void) for (i = 4; i <= 0x80000000; i <<= 1) assert (! is_power_of_2 (i-1)); + /* Check log_2_bits on some known values. */ + assert (log_2_bits (1) == 0); + assert (log_2_bits (512) == 9); + assert (log_2_bits (4096) == 12); + assert (log_2_bits (0x80000000) == 31); +#if SIZEOF_LONG == 8 + assert (log_2_bits (0x100000000) == 32); + assert (log_2_bits (0x8000000000000000) == 63); +#endif + exit (EXIT_SUCCESS); } _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs