summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'include/cutils/bitops.h')
-rw-r--r--include/cutils/bitops.h120
1 files changed, 120 insertions, 0 deletions
diff --git a/include/cutils/bitops.h b/include/cutils/bitops.h
new file mode 100644
index 000000000..045830d90
--- /dev/null
+++ b/include/cutils/bitops.h
@@ -0,0 +1,120 @@
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef __CUTILS_BITOPS_H
18#define __CUTILS_BITOPS_H
19
20#include <stdbool.h>
21#include <string.h>
22#include <strings.h>
23#include <sys/cdefs.h>
24
25__BEGIN_DECLS
26
27/*
28 * Bitmask Operations
29 *
30 * Note this doesn't provide any locking/exclusion, and isn't atomic.
31 * Additionally no bounds checking is done on the bitmask array.
32 *
33 * Example:
34 *
35 * int num_resources;
36 * unsigned int resource_bits[BITS_TO_WORDS(num_resources)];
37 * bitmask_init(resource_bits, num_resources);
38 * ...
39 * int bit = bitmask_ffz(resource_bits, num_resources);
40 * bitmask_set(resource_bits, bit);
41 * ...
42 * if (bitmask_test(resource_bits, bit)) { ... }
43 * ...
44 * bitmask_clear(resource_bits, bit);
45 *
46 */
47
48#define BITS_PER_WORD (sizeof(unsigned int) * 8)
49#define BITS_TO_WORDS(x) (((x) + BITS_PER_WORD - 1) / BITS_PER_WORD)
50#define BIT_IN_WORD(x) ((x) % BITS_PER_WORD)
51#define BIT_WORD(x) ((x) / BITS_PER_WORD)
52#define BIT_MASK(x) (1 << BIT_IN_WORD(x))
53
54static inline void bitmask_init(unsigned int *bitmask, int num_bits)
55{
56 memset(bitmask, 0, BITS_TO_WORDS(num_bits)*sizeof(unsigned int));
57}
58
59static inline int bitmask_ffz(unsigned int *bitmask, int num_bits)
60{
61 int bit, result;
62 size_t i;
63
64 for (i = 0; i < BITS_TO_WORDS(num_bits); i++) {
65 bit = ffs(~bitmask[i]);
66 if (bit) {
67 // ffs is 1-indexed, return 0-indexed result
68 bit--;
69 result = BITS_PER_WORD * i + bit;
70 if (result >= num_bits)
71 return -1;
72 return result;
73 }
74 }
75 return -1;
76}
77
78static inline int bitmask_weight(unsigned int *bitmask, int num_bits)
79{
80 size_t i;
81 int weight = 0;
82
83 for (i = 0; i < BITS_TO_WORDS(num_bits); i++)
84 weight += __builtin_popcount(bitmask[i]);
85 return weight;
86}
87
88static inline void bitmask_set(unsigned int *bitmask, int bit)
89{
90 bitmask[BIT_WORD(bit)] |= BIT_MASK(bit);
91}
92
93static inline void bitmask_clear(unsigned int *bitmask, int bit)
94{
95 bitmask[BIT_WORD(bit)] &= ~BIT_MASK(bit);
96}
97
98static inline bool bitmask_test(unsigned int *bitmask, int bit)
99{
100 return bitmask[BIT_WORD(bit)] & BIT_MASK(bit);
101}
102
103static inline int popcount(unsigned int x)
104{
105 return __builtin_popcount(x);
106}
107
108static inline int popcountl(unsigned long x)
109{
110 return __builtin_popcountl(x);
111}
112
113static inline int popcountll(unsigned long long x)
114{
115 return __builtin_popcountll(x);
116}
117
118__END_DECLS
119
120#endif /* __CUTILS_BITOPS_H */