Blame view

include/linux/bitmap.h 10.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Jiri Slaby   remove BITS_TO_TY...
9
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Andi Kleen   [PATCH] x86_64: O...
28
29
30
   * Note that nbits should be always a compile time evaluable constant.
   * Otherwise many inlines will generate horrible code.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Akinobu Mita   bitmap: introduce...
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   Linus Torvalds   Linux-2.6.12-rc2
48
49
   * bitmap_shift_right(dst, src, n, nbits)	*dst = *src >> n
   * bitmap_shift_left(dst, src, n, nbits)	*dst = *src << n
fb5eeeee4   Paul Jackson   [PATCH] cpusets: ...
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   Paul Jackson   mempolicy: add bi...
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   Linus Torvalds   Linux-2.6.12-rc2
54
   * bitmap_scnprintf(buf, len, src, nbits)	Print bitmap src to buf
01a3ee2b2   Reinette Chatre   [PATCH] bitmap: p...
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   Linus Torvalds   Linux-2.6.12-rc2
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   Paul Jackson   [PATCH] bitmap: r...
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   Linus Torvalds   Linux-2.6.12-rc2
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   Linus Torvalds   Make bitmask 'and...
100
  extern int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Linus Torvalds   Make bitmask 'and...
106
  extern int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Akinobu Mita   bitmap: introduce...
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   Linus Torvalds   Linux-2.6.12-rc2
120
121
  extern int bitmap_scnprintf(char *buf, unsigned int len,
  			const unsigned long *src, int nbits);
01a3ee2b2   Reinette Chatre   [PATCH] bitmap: p...
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   Linus Torvalds   Linux-2.6.12-rc2
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   Paul Jackson   [PATCH] cpusets: ...
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   Paul Jackson   mempolicy: add bi...
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   Linus Torvalds   Linux-2.6.12-rc2
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   David Vrabel   bitmap: add bitma...
141
  extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
146
147
  
  #define BITMAP_LAST_WORD_MASK(nbits)					\
  (									\
  	((nbits) % BITS_PER_LONG) ?					\
  		(1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL		\
  )
4b0bc0bca   Rusty Russell   bitmap: test for ...
148
149
  #define small_const_nbits(nbits) \
  	(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
151
  static inline void bitmap_zero(unsigned long *dst, int nbits)
  {
4b0bc0bca   Rusty Russell   bitmap: test for ...
152
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
163
  	if (!small_const_nbits(nbits)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
173
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
176
177
178
179
  		*dst = *src;
  	else {
  		int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
  		memcpy(dst, src, len);
  	}
  }
f4b0373b2   Linus Torvalds   Make bitmask 'and...
180
  static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
  			const unsigned long *src2, int nbits)
  {
4b0bc0bca   Rusty Russell   bitmap: test for ...
183
  	if (small_const_nbits(nbits))
f4b0373b2   Linus Torvalds   Make bitmask 'and...
184
185
  		return (*dst = *src1 & *src2) != 0;
  	return __bitmap_and(dst, src1, src2, nbits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
188
189
190
  }
  
  static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
  			const unsigned long *src2, int nbits)
  {
4b0bc0bca   Rusty Russell   bitmap: test for ...
191
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
200
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
204
  		*dst = *src1 ^ *src2;
  	else
  		__bitmap_xor(dst, src1, src2, nbits);
  }
f4b0373b2   Linus Torvalds   Make bitmask 'and...
205
  static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
207
  			const unsigned long *src2, int nbits)
  {
4b0bc0bca   Rusty Russell   bitmap: test for ...
208
  	if (small_const_nbits(nbits))
f4b0373b2   Linus Torvalds   Make bitmask 'and...
209
210
  		return (*dst = *src1 & ~(*src2)) != 0;
  	return __bitmap_andnot(dst, src1, src2, nbits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
212
213
214
215
  }
  
  static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
  			int nbits)
  {
4b0bc0bca   Rusty Russell   bitmap: test for ...
216
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
225
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
234
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
243
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
251
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
259
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
267
  	if (small_const_nbits(nbits))
08cd36570   Andi Kleen   [PATCH] x86_64: O...
268
  		return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
275
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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   Rusty Russell   bitmap: test for ...
284
  	if (small_const_nbits(nbits))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
288
  		*dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits);
  	else
  		__bitmap_shift_left(dst, src, n, nbits);
  }
01a3ee2b2   Reinette Chatre   [PATCH] bitmap: p...
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   Linus Torvalds   Linux-2.6.12-rc2
294
295
296
  #endif /* __ASSEMBLY__ */
  
  #endif /* __LINUX_BITMAP_H */