Blame view
include/linux/bitmap.h
10.6 KB
1da177e4c
|
1 2 3 4 5 6 7 8 |
#ifndef __LINUX_BITMAP_H #define __LINUX_BITMAP_H #ifndef __ASSEMBLY__ #include <linux/types.h> #include <linux/bitops.h> #include <linux/string.h> |
14ed9d23a
|
9 |
#include <linux/kernel.h> |
1da177e4c
|
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/* * bitmaps provide bit arrays that consume one or more unsigned * longs. The bitmap interface and available operations are listed * here, in bitmap.h * * Function implementations generic to all architectures are in * lib/bitmap.c. Functions implementations that are architecture * specific are in various include/asm-<arch>/bitops.h headers * and other arch/<arch> specific files. * * See lib/bitmap.c for more details. */ /* * The available bitmap operations and their rough meaning in the * case that the bitmap is a single unsigned long are thus: * |
08cd36570
|
28 29 30 |
* Note that nbits should be always a compile time evaluable constant. * Otherwise many inlines will generate horrible code. * |
1da177e4c
|
31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
* bitmap_zero(dst, nbits) *dst = 0UL * bitmap_fill(dst, nbits) *dst = ~0UL * bitmap_copy(dst, src, nbits) *dst = *src * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2 * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2 * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2 * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2) * bitmap_complement(dst, src, nbits) *dst = ~(*src) * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal? * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap? * bitmap_subset(src1, src2, nbits) Is *src1 a subset of *src2? * bitmap_empty(src, nbits) Are all bits zero in *src? * bitmap_full(src, nbits) Are all bits set in *src? * bitmap_weight(src, nbits) Hamming Weight: number set bits |
c1a2a962a
|
45 46 47 |
* bitmap_set(dst, pos, nbits) Set specified bit area * bitmap_clear(dst, pos, nbits) Clear specified bit area * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area |
1da177e4c
|
48 49 |
* bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n |
fb5eeeee4
|
50 51 |
* bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src) * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit) |
7ea931c9f
|
52 53 |
* bitmap_onto(dst, orig, relmap, nbits) *dst = orig relative to relmap * bitmap_fold(dst, orig, sz, nbits) dst bits = orig bits mod sz |
1da177e4c
|
54 |
* bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf |
01a3ee2b2
|
55 56 |
* bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf * bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf |
1da177e4c
|
57 58 |
* bitmap_scnlistprintf(buf, len, src, nbits) Print bitmap src as list to buf * bitmap_parselist(buf, dst, nbits) Parse bitmap dst from list |
87e248025
|
59 60 61 |
* bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region * bitmap_release_region(bitmap, pos, order) Free specified bit region * bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region |
1da177e4c
|
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
*/ /* * Also the following operations in asm/bitops.h apply to bitmaps. * * set_bit(bit, addr) *addr |= bit * clear_bit(bit, addr) *addr &= ~bit * change_bit(bit, addr) *addr ^= bit * test_bit(bit, addr) Is bit set in *addr? * test_and_set_bit(bit, addr) Set bit and return old value * test_and_clear_bit(bit, addr) Clear bit and return old value * test_and_change_bit(bit, addr) Change bit and return old value * find_first_zero_bit(addr, nbits) Position first zero bit in *addr * find_first_bit(addr, nbits) Position first set bit in *addr * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit */ /* * The DECLARE_BITMAP(name,bits) macro, in linux/types.h, can be used * to declare an array named 'name' of just enough unsigned longs to * contain all bit positions from 0 to 'bits' - 1. */ /* * lib/bitmap.c provides these functions: */ extern int __bitmap_empty(const unsigned long *bitmap, int bits); extern int __bitmap_full(const unsigned long *bitmap, int bits); extern int __bitmap_equal(const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); extern void __bitmap_complement(unsigned long *dst, const unsigned long *src, int bits); extern void __bitmap_shift_right(unsigned long *dst, const unsigned long *src, int shift, int bits); extern void __bitmap_shift_left(unsigned long *dst, const unsigned long *src, int shift, int bits); |
f4b0373b2
|
100 |
extern int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, |
1da177e4c
|
101 102 103 104 105 |
const unsigned long *bitmap2, int bits); extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); |
f4b0373b2
|
106 |
extern int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, |
1da177e4c
|
107 108 109 110 111 112 |
const unsigned long *bitmap2, int bits); extern int __bitmap_intersects(const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); extern int __bitmap_subset(const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); extern int __bitmap_weight(const unsigned long *bitmap, int bits); |
c1a2a962a
|
113 114 115 116 117 118 119 |
extern void bitmap_set(unsigned long *map, int i, int len); extern void bitmap_clear(unsigned long *map, int start, int nr); extern unsigned long bitmap_find_next_zero_area(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, unsigned long align_mask); |
1da177e4c
|
120 121 |
extern int bitmap_scnprintf(char *buf, unsigned int len, const unsigned long *src, int nbits); |
01a3ee2b2
|
122 123 124 |
extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user, unsigned long *dst, int nbits); extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen, |
1da177e4c
|
125 126 127 128 129 |
unsigned long *dst, int nbits); extern int bitmap_scnlistprintf(char *buf, unsigned int len, const unsigned long *src, int nbits); extern int bitmap_parselist(const char *buf, unsigned long *maskp, int nmaskbits); |
fb5eeeee4
|
130 131 132 133 |
extern void bitmap_remap(unsigned long *dst, const unsigned long *src, const unsigned long *old, const unsigned long *new, int bits); extern int bitmap_bitremap(int oldbit, const unsigned long *old, const unsigned long *new, int bits); |
7ea931c9f
|
134 135 136 137 |
extern void bitmap_onto(unsigned long *dst, const unsigned long *orig, const unsigned long *relmap, int bits); extern void bitmap_fold(unsigned long *dst, const unsigned long *orig, int sz, int bits); |
1da177e4c
|
138 139 140 |
extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order); extern void bitmap_release_region(unsigned long *bitmap, int pos, int order); extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order); |
ccbe329bc
|
141 |
extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits); |
1da177e4c
|
142 143 144 145 146 147 |
#define BITMAP_LAST_WORD_MASK(nbits) \ ( \ ((nbits) % BITS_PER_LONG) ? \ (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ ) |
4b0bc0bca
|
148 149 |
#define small_const_nbits(nbits) \ (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) |
1da177e4c
|
150 151 |
static inline void bitmap_zero(unsigned long *dst, int nbits) { |
4b0bc0bca
|
152 |
if (small_const_nbits(nbits)) |
1da177e4c
|
153 154 155 156 157 158 159 160 161 162 |
*dst = 0UL; else { int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); memset(dst, 0, len); } } static inline void bitmap_fill(unsigned long *dst, int nbits) { size_t nlongs = BITS_TO_LONGS(nbits); |
4b0bc0bca
|
163 |
if (!small_const_nbits(nbits)) { |
1da177e4c
|
164 165 166 167 168 169 170 171 172 |
int len = (nlongs - 1) * sizeof(unsigned long); memset(dst, 0xff, len); } dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); } static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, int nbits) { |
4b0bc0bca
|
173 |
if (small_const_nbits(nbits)) |
1da177e4c
|
174 175 176 177 178 179 |
*dst = *src; else { int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); memcpy(dst, src, len); } } |
f4b0373b2
|
180 |
static inline int bitmap_and(unsigned long *dst, const unsigned long *src1, |
1da177e4c
|
181 182 |
const unsigned long *src2, int nbits) { |
4b0bc0bca
|
183 |
if (small_const_nbits(nbits)) |
f4b0373b2
|
184 185 |
return (*dst = *src1 & *src2) != 0; return __bitmap_and(dst, src1, src2, nbits); |
1da177e4c
|
186 187 188 189 190 |
} static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, const unsigned long *src2, int nbits) { |
4b0bc0bca
|
191 |
if (small_const_nbits(nbits)) |
1da177e4c
|
192 193 194 195 196 197 198 199 |
*dst = *src1 | *src2; else __bitmap_or(dst, src1, src2, nbits); } static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1, const unsigned long *src2, int nbits) { |
4b0bc0bca
|
200 |
if (small_const_nbits(nbits)) |
1da177e4c
|
201 202 203 204 |
*dst = *src1 ^ *src2; else __bitmap_xor(dst, src1, src2, nbits); } |
f4b0373b2
|
205 |
static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1, |
1da177e4c
|
206 207 |
const unsigned long *src2, int nbits) { |
4b0bc0bca
|
208 |
if (small_const_nbits(nbits)) |
f4b0373b2
|
209 210 |
return (*dst = *src1 & ~(*src2)) != 0; return __bitmap_andnot(dst, src1, src2, nbits); |
1da177e4c
|
211 212 213 214 215 |
} static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, int nbits) { |
4b0bc0bca
|
216 |
if (small_const_nbits(nbits)) |
1da177e4c
|
217 218 219 220 221 222 223 224 |
*dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits); else __bitmap_complement(dst, src, nbits); } static inline int bitmap_equal(const unsigned long *src1, const unsigned long *src2, int nbits) { |
4b0bc0bca
|
225 |
if (small_const_nbits(nbits)) |
1da177e4c
|
226 227 228 229 230 231 232 233 |
return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); else return __bitmap_equal(src1, src2, nbits); } static inline int bitmap_intersects(const unsigned long *src1, const unsigned long *src2, int nbits) { |
4b0bc0bca
|
234 |
if (small_const_nbits(nbits)) |
1da177e4c
|
235 236 237 238 239 240 241 242 |
return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; else return __bitmap_intersects(src1, src2, nbits); } static inline int bitmap_subset(const unsigned long *src1, const unsigned long *src2, int nbits) { |
4b0bc0bca
|
243 |
if (small_const_nbits(nbits)) |
1da177e4c
|
244 245 246 247 248 249 250 |
return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits)); else return __bitmap_subset(src1, src2, nbits); } static inline int bitmap_empty(const unsigned long *src, int nbits) { |
4b0bc0bca
|
251 |
if (small_const_nbits(nbits)) |
1da177e4c
|
252 253 254 255 256 257 258 |
return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); else return __bitmap_empty(src, nbits); } static inline int bitmap_full(const unsigned long *src, int nbits) { |
4b0bc0bca
|
259 |
if (small_const_nbits(nbits)) |
1da177e4c
|
260 261 262 263 264 265 266 |
return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); else return __bitmap_full(src, nbits); } static inline int bitmap_weight(const unsigned long *src, int nbits) { |
4b0bc0bca
|
267 |
if (small_const_nbits(nbits)) |
08cd36570
|
268 |
return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)); |
1da177e4c
|
269 270 271 272 273 274 |
return __bitmap_weight(src, nbits); } static inline void bitmap_shift_right(unsigned long *dst, const unsigned long *src, int n, int nbits) { |
4b0bc0bca
|
275 |
if (small_const_nbits(nbits)) |
1da177e4c
|
276 277 278 279 280 281 282 283 |
*dst = *src >> n; else __bitmap_shift_right(dst, src, n, nbits); } static inline void bitmap_shift_left(unsigned long *dst, const unsigned long *src, int n, int nbits) { |
4b0bc0bca
|
284 |
if (small_const_nbits(nbits)) |
1da177e4c
|
285 286 287 288 |
*dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits); else __bitmap_shift_left(dst, src, n, nbits); } |
01a3ee2b2
|
289 290 291 292 293 |
static inline int bitmap_parse(const char *buf, unsigned int buflen, unsigned long *maskp, int nmaskbits) { return __bitmap_parse(buf, buflen, 0, maskp, nmaskbits); } |
1da177e4c
|
294 295 296 |
#endif /* __ASSEMBLY__ */ #endif /* __LINUX_BITMAP_H */ |