11da177e4SLinus Torvalds #ifndef __LINUX_BITMAP_H 21da177e4SLinus Torvalds #define __LINUX_BITMAP_H 31da177e4SLinus Torvalds 41da177e4SLinus Torvalds #ifndef __ASSEMBLY__ 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds #include <linux/types.h> 71da177e4SLinus Torvalds #include <linux/bitops.h> 81da177e4SLinus Torvalds #include <linux/string.h> 91da177e4SLinus Torvalds 101da177e4SLinus Torvalds /* 111da177e4SLinus Torvalds * bitmaps provide bit arrays that consume one or more unsigned 121da177e4SLinus Torvalds * longs. The bitmap interface and available operations are listed 131da177e4SLinus Torvalds * here, in bitmap.h 141da177e4SLinus Torvalds * 151da177e4SLinus Torvalds * Function implementations generic to all architectures are in 161da177e4SLinus Torvalds * lib/bitmap.c. Functions implementations that are architecture 171da177e4SLinus Torvalds * specific are in various include/asm-<arch>/bitops.h headers 181da177e4SLinus Torvalds * and other arch/<arch> specific files. 191da177e4SLinus Torvalds * 201da177e4SLinus Torvalds * See lib/bitmap.c for more details. 211da177e4SLinus Torvalds */ 221da177e4SLinus Torvalds 231da177e4SLinus Torvalds /* 241da177e4SLinus Torvalds * The available bitmap operations and their rough meaning in the 251da177e4SLinus Torvalds * case that the bitmap is a single unsigned long are thus: 261da177e4SLinus Torvalds * 2708cd3657SAndi Kleen * Note that nbits should be always a compile time evaluable constant. 2808cd3657SAndi Kleen * Otherwise many inlines will generate horrible code. 2908cd3657SAndi Kleen * 301da177e4SLinus Torvalds * bitmap_zero(dst, nbits) *dst = 0UL 311da177e4SLinus Torvalds * bitmap_fill(dst, nbits) *dst = ~0UL 321da177e4SLinus Torvalds * bitmap_copy(dst, src, nbits) *dst = *src 331da177e4SLinus Torvalds * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2 341da177e4SLinus Torvalds * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2 351da177e4SLinus Torvalds * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2 361da177e4SLinus Torvalds * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2) 371da177e4SLinus Torvalds * bitmap_complement(dst, src, nbits) *dst = ~(*src) 381da177e4SLinus Torvalds * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal? 391da177e4SLinus Torvalds * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap? 401da177e4SLinus Torvalds * bitmap_subset(src1, src2, nbits) Is *src1 a subset of *src2? 411da177e4SLinus Torvalds * bitmap_empty(src, nbits) Are all bits zero in *src? 421da177e4SLinus Torvalds * bitmap_full(src, nbits) Are all bits set in *src? 431da177e4SLinus Torvalds * bitmap_weight(src, nbits) Hamming Weight: number set bits 441da177e4SLinus Torvalds * bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n 451da177e4SLinus Torvalds * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n 46fb5eeeeeSPaul Jackson * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src) 47fb5eeeeeSPaul Jackson * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit) 481da177e4SLinus Torvalds * bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf 49*01a3ee2bSReinette Chatre * bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf 50*01a3ee2bSReinette Chatre * bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf 511da177e4SLinus Torvalds * bitmap_scnlistprintf(buf, len, src, nbits) Print bitmap src as list to buf 521da177e4SLinus Torvalds * bitmap_parselist(buf, dst, nbits) Parse bitmap dst from list 5387e24802SPaul Jackson * bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region 5487e24802SPaul Jackson * bitmap_release_region(bitmap, pos, order) Free specified bit region 5587e24802SPaul Jackson * bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region 561da177e4SLinus Torvalds */ 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds /* 591da177e4SLinus Torvalds * Also the following operations in asm/bitops.h apply to bitmaps. 601da177e4SLinus Torvalds * 611da177e4SLinus Torvalds * set_bit(bit, addr) *addr |= bit 621da177e4SLinus Torvalds * clear_bit(bit, addr) *addr &= ~bit 631da177e4SLinus Torvalds * change_bit(bit, addr) *addr ^= bit 641da177e4SLinus Torvalds * test_bit(bit, addr) Is bit set in *addr? 651da177e4SLinus Torvalds * test_and_set_bit(bit, addr) Set bit and return old value 661da177e4SLinus Torvalds * test_and_clear_bit(bit, addr) Clear bit and return old value 671da177e4SLinus Torvalds * test_and_change_bit(bit, addr) Change bit and return old value 681da177e4SLinus Torvalds * find_first_zero_bit(addr, nbits) Position first zero bit in *addr 691da177e4SLinus Torvalds * find_first_bit(addr, nbits) Position first set bit in *addr 701da177e4SLinus Torvalds * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit 711da177e4SLinus Torvalds * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit 721da177e4SLinus Torvalds */ 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds /* 751da177e4SLinus Torvalds * The DECLARE_BITMAP(name,bits) macro, in linux/types.h, can be used 761da177e4SLinus Torvalds * to declare an array named 'name' of just enough unsigned longs to 771da177e4SLinus Torvalds * contain all bit positions from 0 to 'bits' - 1. 781da177e4SLinus Torvalds */ 791da177e4SLinus Torvalds 801da177e4SLinus Torvalds /* 811da177e4SLinus Torvalds * lib/bitmap.c provides these functions: 821da177e4SLinus Torvalds */ 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds extern int __bitmap_empty(const unsigned long *bitmap, int bits); 851da177e4SLinus Torvalds extern int __bitmap_full(const unsigned long *bitmap, int bits); 861da177e4SLinus Torvalds extern int __bitmap_equal(const unsigned long *bitmap1, 871da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 881da177e4SLinus Torvalds extern void __bitmap_complement(unsigned long *dst, const unsigned long *src, 891da177e4SLinus Torvalds int bits); 901da177e4SLinus Torvalds extern void __bitmap_shift_right(unsigned long *dst, 911da177e4SLinus Torvalds const unsigned long *src, int shift, int bits); 921da177e4SLinus Torvalds extern void __bitmap_shift_left(unsigned long *dst, 931da177e4SLinus Torvalds const unsigned long *src, int shift, int bits); 941da177e4SLinus Torvalds extern void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, 951da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 961da177e4SLinus Torvalds extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, 971da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 981da177e4SLinus Torvalds extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, 991da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 1001da177e4SLinus Torvalds extern void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, 1011da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 1021da177e4SLinus Torvalds extern int __bitmap_intersects(const unsigned long *bitmap1, 1031da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 1041da177e4SLinus Torvalds extern int __bitmap_subset(const unsigned long *bitmap1, 1051da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 1061da177e4SLinus Torvalds extern int __bitmap_weight(const unsigned long *bitmap, int bits); 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds extern int bitmap_scnprintf(char *buf, unsigned int len, 1091da177e4SLinus Torvalds const unsigned long *src, int nbits); 110*01a3ee2bSReinette Chatre extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user, 111*01a3ee2bSReinette Chatre unsigned long *dst, int nbits); 112*01a3ee2bSReinette Chatre extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen, 1131da177e4SLinus Torvalds unsigned long *dst, int nbits); 1141da177e4SLinus Torvalds extern int bitmap_scnlistprintf(char *buf, unsigned int len, 1151da177e4SLinus Torvalds const unsigned long *src, int nbits); 1161da177e4SLinus Torvalds extern int bitmap_parselist(const char *buf, unsigned long *maskp, 1171da177e4SLinus Torvalds int nmaskbits); 118fb5eeeeeSPaul Jackson extern void bitmap_remap(unsigned long *dst, const unsigned long *src, 119fb5eeeeeSPaul Jackson const unsigned long *old, const unsigned long *new, int bits); 120fb5eeeeeSPaul Jackson extern int bitmap_bitremap(int oldbit, 121fb5eeeeeSPaul Jackson const unsigned long *old, const unsigned long *new, int bits); 1221da177e4SLinus Torvalds extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order); 1231da177e4SLinus Torvalds extern void bitmap_release_region(unsigned long *bitmap, int pos, int order); 1241da177e4SLinus Torvalds extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order); 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds #define BITMAP_LAST_WORD_MASK(nbits) \ 1271da177e4SLinus Torvalds ( \ 1281da177e4SLinus Torvalds ((nbits) % BITS_PER_LONG) ? \ 1291da177e4SLinus Torvalds (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ 1301da177e4SLinus Torvalds ) 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds static inline void bitmap_zero(unsigned long *dst, int nbits) 1331da177e4SLinus Torvalds { 1341da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1351da177e4SLinus Torvalds *dst = 0UL; 1361da177e4SLinus Torvalds else { 1371da177e4SLinus Torvalds int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); 1381da177e4SLinus Torvalds memset(dst, 0, len); 1391da177e4SLinus Torvalds } 1401da177e4SLinus Torvalds } 1411da177e4SLinus Torvalds 1421da177e4SLinus Torvalds static inline void bitmap_fill(unsigned long *dst, int nbits) 1431da177e4SLinus Torvalds { 1441da177e4SLinus Torvalds size_t nlongs = BITS_TO_LONGS(nbits); 1451da177e4SLinus Torvalds if (nlongs > 1) { 1461da177e4SLinus Torvalds int len = (nlongs - 1) * sizeof(unsigned long); 1471da177e4SLinus Torvalds memset(dst, 0xff, len); 1481da177e4SLinus Torvalds } 1491da177e4SLinus Torvalds dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); 1501da177e4SLinus Torvalds } 1511da177e4SLinus Torvalds 1521da177e4SLinus Torvalds static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, 1531da177e4SLinus Torvalds int nbits) 1541da177e4SLinus Torvalds { 1551da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1561da177e4SLinus Torvalds *dst = *src; 1571da177e4SLinus Torvalds else { 1581da177e4SLinus Torvalds int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); 1591da177e4SLinus Torvalds memcpy(dst, src, len); 1601da177e4SLinus Torvalds } 1611da177e4SLinus Torvalds } 1621da177e4SLinus Torvalds 1631da177e4SLinus Torvalds static inline void bitmap_and(unsigned long *dst, const unsigned long *src1, 1641da177e4SLinus Torvalds const unsigned long *src2, int nbits) 1651da177e4SLinus Torvalds { 1661da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1671da177e4SLinus Torvalds *dst = *src1 & *src2; 1681da177e4SLinus Torvalds else 1691da177e4SLinus Torvalds __bitmap_and(dst, src1, src2, nbits); 1701da177e4SLinus Torvalds } 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, 1731da177e4SLinus Torvalds const unsigned long *src2, int nbits) 1741da177e4SLinus Torvalds { 1751da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1761da177e4SLinus Torvalds *dst = *src1 | *src2; 1771da177e4SLinus Torvalds else 1781da177e4SLinus Torvalds __bitmap_or(dst, src1, src2, nbits); 1791da177e4SLinus Torvalds } 1801da177e4SLinus Torvalds 1811da177e4SLinus Torvalds static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1, 1821da177e4SLinus Torvalds const unsigned long *src2, int nbits) 1831da177e4SLinus Torvalds { 1841da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1851da177e4SLinus Torvalds *dst = *src1 ^ *src2; 1861da177e4SLinus Torvalds else 1871da177e4SLinus Torvalds __bitmap_xor(dst, src1, src2, nbits); 1881da177e4SLinus Torvalds } 1891da177e4SLinus Torvalds 1901da177e4SLinus Torvalds static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1, 1911da177e4SLinus Torvalds const unsigned long *src2, int nbits) 1921da177e4SLinus Torvalds { 1931da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1941da177e4SLinus Torvalds *dst = *src1 & ~(*src2); 1951da177e4SLinus Torvalds else 1961da177e4SLinus Torvalds __bitmap_andnot(dst, src1, src2, nbits); 1971da177e4SLinus Torvalds } 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, 2001da177e4SLinus Torvalds int nbits) 2011da177e4SLinus Torvalds { 2021da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2031da177e4SLinus Torvalds *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits); 2041da177e4SLinus Torvalds else 2051da177e4SLinus Torvalds __bitmap_complement(dst, src, nbits); 2061da177e4SLinus Torvalds } 2071da177e4SLinus Torvalds 2081da177e4SLinus Torvalds static inline int bitmap_equal(const unsigned long *src1, 2091da177e4SLinus Torvalds const unsigned long *src2, int nbits) 2101da177e4SLinus Torvalds { 2111da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2121da177e4SLinus Torvalds return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); 2131da177e4SLinus Torvalds else 2141da177e4SLinus Torvalds return __bitmap_equal(src1, src2, nbits); 2151da177e4SLinus Torvalds } 2161da177e4SLinus Torvalds 2171da177e4SLinus Torvalds static inline int bitmap_intersects(const unsigned long *src1, 2181da177e4SLinus Torvalds const unsigned long *src2, int nbits) 2191da177e4SLinus Torvalds { 2201da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2211da177e4SLinus Torvalds return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; 2221da177e4SLinus Torvalds else 2231da177e4SLinus Torvalds return __bitmap_intersects(src1, src2, nbits); 2241da177e4SLinus Torvalds } 2251da177e4SLinus Torvalds 2261da177e4SLinus Torvalds static inline int bitmap_subset(const unsigned long *src1, 2271da177e4SLinus Torvalds const unsigned long *src2, int nbits) 2281da177e4SLinus Torvalds { 2291da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2301da177e4SLinus Torvalds return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits)); 2311da177e4SLinus Torvalds else 2321da177e4SLinus Torvalds return __bitmap_subset(src1, src2, nbits); 2331da177e4SLinus Torvalds } 2341da177e4SLinus Torvalds 2351da177e4SLinus Torvalds static inline int bitmap_empty(const unsigned long *src, int nbits) 2361da177e4SLinus Torvalds { 2371da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2381da177e4SLinus Torvalds return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); 2391da177e4SLinus Torvalds else 2401da177e4SLinus Torvalds return __bitmap_empty(src, nbits); 2411da177e4SLinus Torvalds } 2421da177e4SLinus Torvalds 2431da177e4SLinus Torvalds static inline int bitmap_full(const unsigned long *src, int nbits) 2441da177e4SLinus Torvalds { 2451da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2461da177e4SLinus Torvalds return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); 2471da177e4SLinus Torvalds else 2481da177e4SLinus Torvalds return __bitmap_full(src, nbits); 2491da177e4SLinus Torvalds } 2501da177e4SLinus Torvalds 2511da177e4SLinus Torvalds static inline int bitmap_weight(const unsigned long *src, int nbits) 2521da177e4SLinus Torvalds { 25308cd3657SAndi Kleen if (nbits <= BITS_PER_LONG) 25408cd3657SAndi Kleen return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)); 2551da177e4SLinus Torvalds return __bitmap_weight(src, nbits); 2561da177e4SLinus Torvalds } 2571da177e4SLinus Torvalds 2581da177e4SLinus Torvalds static inline void bitmap_shift_right(unsigned long *dst, 2591da177e4SLinus Torvalds const unsigned long *src, int n, int nbits) 2601da177e4SLinus Torvalds { 2611da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2621da177e4SLinus Torvalds *dst = *src >> n; 2631da177e4SLinus Torvalds else 2641da177e4SLinus Torvalds __bitmap_shift_right(dst, src, n, nbits); 2651da177e4SLinus Torvalds } 2661da177e4SLinus Torvalds 2671da177e4SLinus Torvalds static inline void bitmap_shift_left(unsigned long *dst, 2681da177e4SLinus Torvalds const unsigned long *src, int n, int nbits) 2691da177e4SLinus Torvalds { 2701da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2711da177e4SLinus Torvalds *dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits); 2721da177e4SLinus Torvalds else 2731da177e4SLinus Torvalds __bitmap_shift_left(dst, src, n, nbits); 2741da177e4SLinus Torvalds } 2751da177e4SLinus Torvalds 276*01a3ee2bSReinette Chatre static inline int bitmap_parse(const char *buf, unsigned int buflen, 277*01a3ee2bSReinette Chatre unsigned long *maskp, int nmaskbits) 278*01a3ee2bSReinette Chatre { 279*01a3ee2bSReinette Chatre return __bitmap_parse(buf, buflen, 0, maskp, nmaskbits); 280*01a3ee2bSReinette Chatre } 281*01a3ee2bSReinette Chatre 2821da177e4SLinus Torvalds #endif /* __ASSEMBLY__ */ 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds #endif /* __LINUX_BITMAP_H */ 285