aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/bitmap.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/bitmap.h')
-rw-r--r--include/linux/bitmap.h63
1 files changed, 47 insertions, 16 deletions
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 3489253e38fc..5f11fbdc27f8 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -64,9 +64,14 @@
64 * bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region 64 * bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region
65 * bitmap_release_region(bitmap, pos, order) Free specified bit region 65 * bitmap_release_region(bitmap, pos, order) Free specified bit region
66 * bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region 66 * bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region
67 * bitmap_from_u32array(dst, nbits, buf, nwords) *dst = *buf (nwords 32b words) 67 * bitmap_from_arr32(dst, buf, nbits) Copy nbits from u32[] buf to dst
68 * bitmap_to_u32array(buf, nwords, src, nbits) *buf = *dst (nwords 32b words) 68 * bitmap_to_arr32(buf, src, nbits) Copy nbits from buf to u32[] dst
69 * 69 *
70 * Note, bitmap_zero() and bitmap_fill() operate over the region of
71 * unsigned longs, that is, bits behind bitmap till the unsigned long
72 * boundary will be zeroed or filled as well. Consider to use
73 * bitmap_clear() or bitmap_set() to make explicit zeroing or filling
74 * respectively.
70 */ 75 */
71 76
72/** 77/**
@@ -83,8 +88,12 @@
83 * test_and_change_bit(bit, addr) Change bit and return old value 88 * test_and_change_bit(bit, addr) Change bit and return old value
84 * find_first_zero_bit(addr, nbits) Position first zero bit in *addr 89 * find_first_zero_bit(addr, nbits) Position first zero bit in *addr
85 * find_first_bit(addr, nbits) Position first set bit in *addr 90 * find_first_bit(addr, nbits) Position first set bit in *addr
86 * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit 91 * find_next_zero_bit(addr, nbits, bit)
92 * Position next zero bit in *addr >= bit
87 * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit 93 * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit
94 * find_next_and_bit(addr1, addr2, nbits, bit)
95 * Same as find_next_bit, but in
96 * (*addr1 & *addr2)
88 * 97 *
89 */ 98 */
90 99
@@ -174,14 +183,7 @@ extern void bitmap_fold(unsigned long *dst, const unsigned long *orig,
174extern int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order); 183extern int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order);
175extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order); 184extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order);
176extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order); 185extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order);
177extern unsigned int bitmap_from_u32array(unsigned long *bitmap, 186
178 unsigned int nbits,
179 const u32 *buf,
180 unsigned int nwords);
181extern unsigned int bitmap_to_u32array(u32 *buf,
182 unsigned int nwords,
183 const unsigned long *bitmap,
184 unsigned int nbits);
185#ifdef __BIG_ENDIAN 187#ifdef __BIG_ENDIAN
186extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits); 188extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits);
187#else 189#else
@@ -209,12 +211,12 @@ static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
209 211
210static inline void bitmap_fill(unsigned long *dst, unsigned int nbits) 212static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
211{ 213{
212 unsigned int nlongs = BITS_TO_LONGS(nbits); 214 if (small_const_nbits(nbits))
213 if (!small_const_nbits(nbits)) { 215 *dst = ~0UL;
214 unsigned int len = (nlongs - 1) * sizeof(unsigned long); 216 else {
215 memset(dst, 0xff, len); 217 unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
218 memset(dst, 0xff, len);
216 } 219 }
217 dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
218} 220}
219 221
220static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, 222static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
@@ -228,6 +230,35 @@ static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
228 } 230 }
229} 231}
230 232
233/*
234 * Copy bitmap and clear tail bits in last word.
235 */
236static inline void bitmap_copy_clear_tail(unsigned long *dst,
237 const unsigned long *src, unsigned int nbits)
238{
239 bitmap_copy(dst, src, nbits);
240 if (nbits % BITS_PER_LONG)
241 dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits);
242}
243
244/*
245 * On 32-bit systems bitmaps are represented as u32 arrays internally, and
246 * therefore conversion is not needed when copying data from/to arrays of u32.
247 */
248#if BITS_PER_LONG == 64
249extern void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf,
250 unsigned int nbits);
251extern void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap,
252 unsigned int nbits);
253#else
254#define bitmap_from_arr32(bitmap, buf, nbits) \
255 bitmap_copy_clear_tail((unsigned long *) (bitmap), \
256 (const unsigned long *) (buf), (nbits))
257#define bitmap_to_arr32(buf, bitmap, nbits) \
258 bitmap_copy_clear_tail((unsigned long *) (buf), \
259 (const unsigned long *) (bitmap), (nbits))
260#endif
261
231static inline int bitmap_and(unsigned long *dst, const unsigned long *src1, 262static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
232 const unsigned long *src2, unsigned int nbits) 263 const unsigned long *src2, unsigned int nbits)
233{ 264{