diff options
author | Alex Ray <aray@google.com> | 2013-01-03 10:57:13 -0800 |
---|---|---|
committer | Alex Ray <aray@google.com> | 2013-01-07 13:02:28 -0800 |
commit | 2111bc7b28af06757fa8108bab045188d4b337fd (patch) | |
tree | 9722d9124ce7f4401d89c34238ab2dc850e5a1ed /include | |
parent | e8097be24e508f6ff6b6dfd9144bd4de1db8becc (diff) | |
download | system_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')
-rw-r--r-- | include/cutils/bitops.h | 68 |
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); |