[Libguestfs] [nbdkit PATCH 2/9] common/include: Add a function to compute log2(unsigned long)

Laszlo Ersek lersek at redhat.com
Fri Mar 3 07:51:38 UTC 2023


From: "Richard W.M. Jones" <rjones at redhat.com>

Signed-off-by: Laszlo Ersek <lersek at 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);
 }



More information about the Libguestfs mailing list