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 * 271da177e4SLinus Torvalds * bitmap_zero(dst, nbits) *dst = 0UL 281da177e4SLinus Torvalds * bitmap_fill(dst, nbits) *dst = ~0UL 291da177e4SLinus Torvalds * bitmap_copy(dst, src, nbits) *dst = *src 301da177e4SLinus Torvalds * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2 311da177e4SLinus Torvalds * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2 321da177e4SLinus Torvalds * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2 331da177e4SLinus Torvalds * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2) 341da177e4SLinus Torvalds * bitmap_complement(dst, src, nbits) *dst = ~(*src) 351da177e4SLinus Torvalds * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal? 361da177e4SLinus Torvalds * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap? 371da177e4SLinus Torvalds * bitmap_subset(src1, src2, nbits) Is *src1 a subset of *src2? 381da177e4SLinus Torvalds * bitmap_empty(src, nbits) Are all bits zero in *src? 391da177e4SLinus Torvalds * bitmap_full(src, nbits) Are all bits set in *src? 401da177e4SLinus Torvalds * bitmap_weight(src, nbits) Hamming Weight: number set bits 411da177e4SLinus Torvalds * bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n 421da177e4SLinus Torvalds * bitmap_shift_left(dst, src, n, nbits) *dst = *src << n 43*fb5eeeeeSPaul Jackson * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src) 44*fb5eeeeeSPaul Jackson * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit) 451da177e4SLinus Torvalds * bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf 461da177e4SLinus Torvalds * bitmap_parse(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf 471da177e4SLinus Torvalds * bitmap_scnlistprintf(buf, len, src, nbits) Print bitmap src as list to buf 481da177e4SLinus Torvalds * bitmap_parselist(buf, dst, nbits) Parse bitmap dst from list 491da177e4SLinus Torvalds */ 501da177e4SLinus Torvalds 511da177e4SLinus Torvalds /* 521da177e4SLinus Torvalds * Also the following operations in asm/bitops.h apply to bitmaps. 531da177e4SLinus Torvalds * 541da177e4SLinus Torvalds * set_bit(bit, addr) *addr |= bit 551da177e4SLinus Torvalds * clear_bit(bit, addr) *addr &= ~bit 561da177e4SLinus Torvalds * change_bit(bit, addr) *addr ^= bit 571da177e4SLinus Torvalds * test_bit(bit, addr) Is bit set in *addr? 581da177e4SLinus Torvalds * test_and_set_bit(bit, addr) Set bit and return old value 591da177e4SLinus Torvalds * test_and_clear_bit(bit, addr) Clear bit and return old value 601da177e4SLinus Torvalds * test_and_change_bit(bit, addr) Change bit and return old value 611da177e4SLinus Torvalds * find_first_zero_bit(addr, nbits) Position first zero bit in *addr 621da177e4SLinus Torvalds * find_first_bit(addr, nbits) Position first set bit in *addr 631da177e4SLinus Torvalds * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit 641da177e4SLinus Torvalds * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit 651da177e4SLinus Torvalds */ 661da177e4SLinus Torvalds 671da177e4SLinus Torvalds /* 681da177e4SLinus Torvalds * The DECLARE_BITMAP(name,bits) macro, in linux/types.h, can be used 691da177e4SLinus Torvalds * to declare an array named 'name' of just enough unsigned longs to 701da177e4SLinus Torvalds * contain all bit positions from 0 to 'bits' - 1. 711da177e4SLinus Torvalds */ 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds /* 741da177e4SLinus Torvalds * lib/bitmap.c provides these functions: 751da177e4SLinus Torvalds */ 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds extern int __bitmap_empty(const unsigned long *bitmap, int bits); 781da177e4SLinus Torvalds extern int __bitmap_full(const unsigned long *bitmap, int bits); 791da177e4SLinus Torvalds extern int __bitmap_equal(const unsigned long *bitmap1, 801da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 811da177e4SLinus Torvalds extern void __bitmap_complement(unsigned long *dst, const unsigned long *src, 821da177e4SLinus Torvalds int bits); 831da177e4SLinus Torvalds extern void __bitmap_shift_right(unsigned long *dst, 841da177e4SLinus Torvalds const unsigned long *src, int shift, int bits); 851da177e4SLinus Torvalds extern void __bitmap_shift_left(unsigned long *dst, 861da177e4SLinus Torvalds const unsigned long *src, int shift, int bits); 871da177e4SLinus Torvalds extern void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, 881da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 891da177e4SLinus Torvalds extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, 901da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 911da177e4SLinus Torvalds extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, 921da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 931da177e4SLinus Torvalds extern void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, 941da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 951da177e4SLinus Torvalds extern int __bitmap_intersects(const unsigned long *bitmap1, 961da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 971da177e4SLinus Torvalds extern int __bitmap_subset(const unsigned long *bitmap1, 981da177e4SLinus Torvalds const unsigned long *bitmap2, int bits); 991da177e4SLinus Torvalds extern int __bitmap_weight(const unsigned long *bitmap, int bits); 1001da177e4SLinus Torvalds 1011da177e4SLinus Torvalds extern int bitmap_scnprintf(char *buf, unsigned int len, 1021da177e4SLinus Torvalds const unsigned long *src, int nbits); 1031da177e4SLinus Torvalds extern int bitmap_parse(const char __user *ubuf, unsigned int ulen, 1041da177e4SLinus Torvalds unsigned long *dst, int nbits); 1051da177e4SLinus Torvalds extern int bitmap_scnlistprintf(char *buf, unsigned int len, 1061da177e4SLinus Torvalds const unsigned long *src, int nbits); 1071da177e4SLinus Torvalds extern int bitmap_parselist(const char *buf, unsigned long *maskp, 1081da177e4SLinus Torvalds int nmaskbits); 109*fb5eeeeeSPaul Jackson extern void bitmap_remap(unsigned long *dst, const unsigned long *src, 110*fb5eeeeeSPaul Jackson const unsigned long *old, const unsigned long *new, int bits); 111*fb5eeeeeSPaul Jackson extern int bitmap_bitremap(int oldbit, 112*fb5eeeeeSPaul Jackson const unsigned long *old, const unsigned long *new, int bits); 1131da177e4SLinus Torvalds extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order); 1141da177e4SLinus Torvalds extern void bitmap_release_region(unsigned long *bitmap, int pos, int order); 1151da177e4SLinus Torvalds extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order); 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds #define BITMAP_LAST_WORD_MASK(nbits) \ 1181da177e4SLinus Torvalds ( \ 1191da177e4SLinus Torvalds ((nbits) % BITS_PER_LONG) ? \ 1201da177e4SLinus Torvalds (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ 1211da177e4SLinus Torvalds ) 1221da177e4SLinus Torvalds 1231da177e4SLinus Torvalds static inline void bitmap_zero(unsigned long *dst, int nbits) 1241da177e4SLinus Torvalds { 1251da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1261da177e4SLinus Torvalds *dst = 0UL; 1271da177e4SLinus Torvalds else { 1281da177e4SLinus Torvalds int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); 1291da177e4SLinus Torvalds memset(dst, 0, len); 1301da177e4SLinus Torvalds } 1311da177e4SLinus Torvalds } 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds static inline void bitmap_fill(unsigned long *dst, int nbits) 1341da177e4SLinus Torvalds { 1351da177e4SLinus Torvalds size_t nlongs = BITS_TO_LONGS(nbits); 1361da177e4SLinus Torvalds if (nlongs > 1) { 1371da177e4SLinus Torvalds int len = (nlongs - 1) * sizeof(unsigned long); 1381da177e4SLinus Torvalds memset(dst, 0xff, len); 1391da177e4SLinus Torvalds } 1401da177e4SLinus Torvalds dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); 1411da177e4SLinus Torvalds } 1421da177e4SLinus Torvalds 1431da177e4SLinus Torvalds static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, 1441da177e4SLinus Torvalds int nbits) 1451da177e4SLinus Torvalds { 1461da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1471da177e4SLinus Torvalds *dst = *src; 1481da177e4SLinus Torvalds else { 1491da177e4SLinus Torvalds int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); 1501da177e4SLinus Torvalds memcpy(dst, src, len); 1511da177e4SLinus Torvalds } 1521da177e4SLinus Torvalds } 1531da177e4SLinus Torvalds 1541da177e4SLinus Torvalds static inline void bitmap_and(unsigned long *dst, const unsigned long *src1, 1551da177e4SLinus Torvalds const unsigned long *src2, int nbits) 1561da177e4SLinus Torvalds { 1571da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1581da177e4SLinus Torvalds *dst = *src1 & *src2; 1591da177e4SLinus Torvalds else 1601da177e4SLinus Torvalds __bitmap_and(dst, src1, src2, nbits); 1611da177e4SLinus Torvalds } 1621da177e4SLinus Torvalds 1631da177e4SLinus Torvalds static inline void bitmap_or(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_or(dst, src1, src2, nbits); 1701da177e4SLinus Torvalds } 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds static inline void bitmap_xor(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_xor(dst, src1, src2, nbits); 1791da177e4SLinus Torvalds } 1801da177e4SLinus Torvalds 1811da177e4SLinus Torvalds static inline void bitmap_andnot(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_andnot(dst, src1, src2, nbits); 1881da177e4SLinus Torvalds } 1891da177e4SLinus Torvalds 1901da177e4SLinus Torvalds static inline void bitmap_complement(unsigned long *dst, const unsigned long *src, 1911da177e4SLinus Torvalds int nbits) 1921da177e4SLinus Torvalds { 1931da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 1941da177e4SLinus Torvalds *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits); 1951da177e4SLinus Torvalds else 1961da177e4SLinus Torvalds __bitmap_complement(dst, src, nbits); 1971da177e4SLinus Torvalds } 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds static inline int bitmap_equal(const unsigned long *src1, 2001da177e4SLinus Torvalds const unsigned long *src2, int nbits) 2011da177e4SLinus Torvalds { 2021da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2031da177e4SLinus Torvalds return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits)); 2041da177e4SLinus Torvalds else 2051da177e4SLinus Torvalds return __bitmap_equal(src1, src2, nbits); 2061da177e4SLinus Torvalds } 2071da177e4SLinus Torvalds 2081da177e4SLinus Torvalds static inline int bitmap_intersects(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)) != 0; 2131da177e4SLinus Torvalds else 2141da177e4SLinus Torvalds return __bitmap_intersects(src1, src2, nbits); 2151da177e4SLinus Torvalds } 2161da177e4SLinus Torvalds 2171da177e4SLinus Torvalds static inline int bitmap_subset(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)); 2221da177e4SLinus Torvalds else 2231da177e4SLinus Torvalds return __bitmap_subset(src1, src2, nbits); 2241da177e4SLinus Torvalds } 2251da177e4SLinus Torvalds 2261da177e4SLinus Torvalds static inline int bitmap_empty(const unsigned long *src, int nbits) 2271da177e4SLinus Torvalds { 2281da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2291da177e4SLinus Torvalds return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); 2301da177e4SLinus Torvalds else 2311da177e4SLinus Torvalds return __bitmap_empty(src, nbits); 2321da177e4SLinus Torvalds } 2331da177e4SLinus Torvalds 2341da177e4SLinus Torvalds static inline int bitmap_full(const unsigned long *src, int nbits) 2351da177e4SLinus Torvalds { 2361da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2371da177e4SLinus Torvalds return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); 2381da177e4SLinus Torvalds else 2391da177e4SLinus Torvalds return __bitmap_full(src, nbits); 2401da177e4SLinus Torvalds } 2411da177e4SLinus Torvalds 2421da177e4SLinus Torvalds static inline int bitmap_weight(const unsigned long *src, int nbits) 2431da177e4SLinus Torvalds { 2441da177e4SLinus Torvalds return __bitmap_weight(src, nbits); 2451da177e4SLinus Torvalds } 2461da177e4SLinus Torvalds 2471da177e4SLinus Torvalds static inline void bitmap_shift_right(unsigned long *dst, 2481da177e4SLinus Torvalds const unsigned long *src, int n, int nbits) 2491da177e4SLinus Torvalds { 2501da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2511da177e4SLinus Torvalds *dst = *src >> n; 2521da177e4SLinus Torvalds else 2531da177e4SLinus Torvalds __bitmap_shift_right(dst, src, n, nbits); 2541da177e4SLinus Torvalds } 2551da177e4SLinus Torvalds 2561da177e4SLinus Torvalds static inline void bitmap_shift_left(unsigned long *dst, 2571da177e4SLinus Torvalds const unsigned long *src, int n, int nbits) 2581da177e4SLinus Torvalds { 2591da177e4SLinus Torvalds if (nbits <= BITS_PER_LONG) 2601da177e4SLinus Torvalds *dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits); 2611da177e4SLinus Torvalds else 2621da177e4SLinus Torvalds __bitmap_shift_left(dst, src, n, nbits); 2631da177e4SLinus Torvalds } 2641da177e4SLinus Torvalds 2651da177e4SLinus Torvalds #endif /* __ASSEMBLY__ */ 2661da177e4SLinus Torvalds 2671da177e4SLinus Torvalds #endif /* __LINUX_BITMAP_H */ 268