summaryrefslogtreecommitdiffstats
path: root/include/cutils
diff options
context:
space:
mode:
authorAlex Ray <aray@google.com>2013-01-03 10:57:13 -0800
committerAlex Ray <aray@google.com>2013-01-07 13:02:28 -0800
commit2111bc7b28af06757fa8108bab045188d4b337fd (patch)
tree9722d9124ce7f4401d89c34238ab2dc850e5a1ed /include/cutils
parente8097be24e508f6ff6b6dfd9144bd4de1db8becc (diff)
downloadsystem_core-2111bc7b28af06757fa8108bab045188d4b337fd.zip
system_core-2111bc7b28af06757fa8108bab045188d4b337fd.tar.gz
system_core-2111bc7b28af06757fa8108bab045188d4b337fd.tar.bz2
cutils: Add bitmask utilities to bitops
Bitmask utils handle resource tracking using a (multi-word) bitmask. Change-Id: I2ae45df1ac8c665c29ea9cae32a757168686b96c
Diffstat (limited to 'include/cutils')
-rw-r--r--include/cutils/bitops.h68
1 files changed, 68 insertions, 0 deletions
diff --git a/include/cutils/bitops.h b/include/cutils/bitops.h
index 1b3b762..6893985 100644
--- a/include/cutils/bitops.h
+++ b/include/cutils/bitops.h
@@ -17,10 +17,78 @@
#ifndef __CUTILS_BITOPS_H
#define __CUTILS_BITOPS_H
+#include <string.h>
+#include <strings.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
+/*
+ * Bitmask Operations
+ *
+ * Note this doesn't provide any locking/exclusion, and isn't atomic.
+ * Additionally no bounds checking is done on the bitmask array.
+ *
+ * Example:
+ *
+ * int num_resources;
+ * unsigned int resource_bits[BITS_TO_WORDS(num_resources)];
+ * bitmask_init(resource_bits, num_resources);
+ * ...
+ * int bit = bitmask_ffz(resource_bits, num_resources);
+ * bitmask_set(resource_bits, bit);
+ * ...
+ * if (bitmask_test(resource_bits, bit)) { ... }
+ * ...
+ * bitmask_clear(resource_bits, bit);
+ *
+ */
+
+#define BITS_PER_WORD (sizeof(unsigned int) * 8)
+#define BITS_TO_WORDS(x) (((x) + BITS_PER_WORD - 1) / BITS_PER_WORD)
+#define BIT_IN_WORD(x) ((x) % BITS_PER_WORD)
+#define BIT_WORD(x) ((x) / BITS_PER_WORD)
+#define BIT_MASK(x) (1 << BIT_IN_WORD(x))
+
+static inline void bitmask_init(unsigned int *bitmask, int num_bits)
+{
+ memset(bitmask, 0, BITS_TO_WORDS(num_bits)*sizeof(unsigned int));
+}
+
+static inline int bitmask_ffz(unsigned int *bitmask, int num_bits)
+{
+ int bit, result;
+ unsigned int i;
+
+ for (i = 0; i < BITS_TO_WORDS(num_bits); i++) {
+ bit = ffs(~bitmask[i]);
+ if (bit) {
+ // ffs is 1-indexed, return 0-indexed result
+ bit--;
+ result = BITS_PER_WORD * i + bit;
+ if (result >= num_bits)
+ return -1;
+ return result;
+ }
+ }
+ return -1;
+}
+
+static inline void bitmask_set(unsigned int *bitmask, int bit)
+{
+ bitmask[BIT_WORD(bit)] |= BIT_MASK(bit);
+}
+
+static inline void bitmask_clear(unsigned int *bitmask, int bit)
+{
+ bitmask[BIT_WORD(bit)] &= ~BIT_MASK(bit);
+}
+
+static inline bool bitmask_test(unsigned int *bitmask, int bit)
+{
+ return bitmask[BIT_WORD(bit)] & BIT_MASK(bit);
+}
+
static inline int popcount(unsigned int x)
{
return __builtin_popcount(x);