Calculates the position of the most significant bit in a 32 bit
word.
---
 lib/util.c |   25 +++++++++++++++++++++++++
 lib/util.h |    1 +
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/lib/util.c b/lib/util.c
index 1a42376..b3455eb 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -16,6 +16,7 @@
 
 #include <config.h>
 #include "util.h"
+#include <assert.h>
 #include <errno.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -607,3 +608,27 @@ english_list_delimiter(size_t index, size_t total)
             : total > 2 ? ", and "
             : " and ");
 }
+
+/* Given a 32 bit word 'n', calculates floor(log_2('n')).  This is equivalent
+ * to finding the bit position of the most significant one bit in 'n'.  It is
+ * an error to call this function with 'n' == 0. */
+size_t
+log_2_floor(uint32_t n)
+{
+    size_t log = 0;
+
+    assert(n);
+
+#define BIN_SEARCH_STEP(BITS) \
+    if (n >= (1 << BITS)) {   \
+        log += BITS;          \
+        n >>= BITS;           \
+    }
+    BIN_SEARCH_STEP(16);
+    BIN_SEARCH_STEP(8);
+    BIN_SEARCH_STEP(4);
+    BIN_SEARCH_STEP(2);
+    BIN_SEARCH_STEP(1);
+#undef BIN_SEARCH_STEP
+    return log;
+}
diff --git a/lib/util.h b/lib/util.h
index 7615288..f688df9 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -194,6 +194,7 @@ char *base_name(const char *file_name);
 char *abs_file_name(const char *dir, const char *file_name);
 
 void ignore(bool x OVS_UNUSED);
+size_t log_2_floor(uint32_t n);
 
 #ifdef  __cplusplus
 }
-- 
1.7.6

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to