blob: 6893985b8b700fd51b6150cbcaf728a2b1d28894 [file] [log] [blame]
Dima Zavin5a809b92011-03-10 15:06:27 -08001/*
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
Alex Ray2111bc72013-01-03 10:57:13 -080020#include <string.h>
21#include <strings.h>
Dima Zavin5a809b92011-03-10 15:06:27 -080022#include <sys/cdefs.h>
23
24__BEGIN_DECLS
25
Alex Ray2111bc72013-01-03 10:57:13 -080026/*
27 * Bitmask Operations
28 *
29 * Note this doesn't provide any locking/exclusion, and isn't atomic.
30 * Additionally no bounds checking is done on the bitmask array.
31 *
32 * Example:
33 *
34 * int num_resources;
35 * unsigned int resource_bits[BITS_TO_WORDS(num_resources)];
36 * bitmask_init(resource_bits, num_resources);
37 * ...
38 * int bit = bitmask_ffz(resource_bits, num_resources);
39 * bitmask_set(resource_bits, bit);
40 * ...
41 * if (bitmask_test(resource_bits, bit)) { ... }
42 * ...
43 * bitmask_clear(resource_bits, bit);
44 *
45 */
46
47#define BITS_PER_WORD (sizeof(unsigned int) * 8)
48#define BITS_TO_WORDS(x) (((x) + BITS_PER_WORD - 1) / BITS_PER_WORD)
49#define BIT_IN_WORD(x) ((x) % BITS_PER_WORD)
50#define BIT_WORD(x) ((x) / BITS_PER_WORD)
51#define BIT_MASK(x) (1 << BIT_IN_WORD(x))
52
53static inline void bitmask_init(unsigned int *bitmask, int num_bits)
54{
55 memset(bitmask, 0, BITS_TO_WORDS(num_bits)*sizeof(unsigned int));
56}
57
58static inline int bitmask_ffz(unsigned int *bitmask, int num_bits)
59{
60 int bit, result;
61 unsigned int i;
62
63 for (i = 0; i < BITS_TO_WORDS(num_bits); i++) {
64 bit = ffs(~bitmask[i]);
65 if (bit) {
66 // ffs is 1-indexed, return 0-indexed result
67 bit--;
68 result = BITS_PER_WORD * i + bit;
69 if (result >= num_bits)
70 return -1;
71 return result;
72 }
73 }
74 return -1;
75}
76
77static inline void bitmask_set(unsigned int *bitmask, int bit)
78{
79 bitmask[BIT_WORD(bit)] |= BIT_MASK(bit);
80}
81
82static inline void bitmask_clear(unsigned int *bitmask, int bit)
83{
84 bitmask[BIT_WORD(bit)] &= ~BIT_MASK(bit);
85}
86
87static inline bool bitmask_test(unsigned int *bitmask, int bit)
88{
89 return bitmask[BIT_WORD(bit)] & BIT_MASK(bit);
90}
91
Dima Zavin5a809b92011-03-10 15:06:27 -080092static inline int popcount(unsigned int x)
93{
94 return __builtin_popcount(x);
95}
96
97static inline int popcountl(unsigned long x)
98{
99 return __builtin_popcountl(x);
100}
101
102static inline int popcountll(unsigned long long x)
103{
104 return __builtin_popcountll(x);
105}
106
107__END_DECLS
108
109#endif /* __CUTILS_BITOPS_H */