xref: /kvmtool/include/linux/bitmap.h (revision 0febaae00bb6f8c5e694f87d6354fbcbe81e6653)
1*0febaae0SAlexandru Elisei #ifndef KVM__BITMAP_H
2*0febaae0SAlexandru Elisei #define KVM__BITMAP_H
3*0febaae0SAlexandru Elisei 
4*0febaae0SAlexandru Elisei #include <stdbool.h>
5*0febaae0SAlexandru Elisei #include <string.h>
6*0febaae0SAlexandru Elisei 
7*0febaae0SAlexandru Elisei #include "linux/bitops.h"
8*0febaae0SAlexandru Elisei 
9*0febaae0SAlexandru Elisei #define DECLARE_BITMAP(name,bits) \
10*0febaae0SAlexandru Elisei 	unsigned long name[BITS_TO_LONGS(bits)]
11*0febaae0SAlexandru Elisei 
12*0febaae0SAlexandru Elisei #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
13*0febaae0SAlexandru Elisei #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
14*0febaae0SAlexandru Elisei 
bitmap_zero(unsigned long * dst,unsigned int nbits)15*0febaae0SAlexandru Elisei static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
16*0febaae0SAlexandru Elisei {
17*0febaae0SAlexandru Elisei 	unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
18*0febaae0SAlexandru Elisei 	memset(dst, 0, len);
19*0febaae0SAlexandru Elisei }
20*0febaae0SAlexandru Elisei 
21*0febaae0SAlexandru Elisei #if __BYTE_ORDER__ ==  __ORDER_LITTLE_ENDIAN__
22*0febaae0SAlexandru Elisei #define BITMAP_MEM_ALIGNMENT 8
23*0febaae0SAlexandru Elisei #else
24*0febaae0SAlexandru Elisei #define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long))
25*0febaae0SAlexandru Elisei #endif
26*0febaae0SAlexandru Elisei #define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1)
27*0febaae0SAlexandru Elisei 
28*0febaae0SAlexandru Elisei void __bitmap_set(unsigned long *map, unsigned int start, int len);
29*0febaae0SAlexandru Elisei 
bitmap_set(unsigned long * map,unsigned int start,unsigned int nbits)30*0febaae0SAlexandru Elisei static inline void bitmap_set(unsigned long *map, unsigned int start,
31*0febaae0SAlexandru Elisei 		unsigned int nbits)
32*0febaae0SAlexandru Elisei {
33*0febaae0SAlexandru Elisei 	if (__builtin_constant_p(nbits) && nbits == 1)
34*0febaae0SAlexandru Elisei 		set_bit(start, map);
35*0febaae0SAlexandru Elisei 	else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
36*0febaae0SAlexandru Elisei 		 IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
37*0febaae0SAlexandru Elisei 		 __builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
38*0febaae0SAlexandru Elisei 		 IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
39*0febaae0SAlexandru Elisei 		memset((char *)map + start / 8, 0xff, nbits / 8);
40*0febaae0SAlexandru Elisei 	else
41*0febaae0SAlexandru Elisei 		__bitmap_set(map, start, nbits);
42*0febaae0SAlexandru Elisei }
43*0febaae0SAlexandru Elisei 
44*0febaae0SAlexandru Elisei bool __bitmap_and(unsigned long *dst, const unsigned long *src1,
45*0febaae0SAlexandru Elisei 		  const unsigned long *src2, unsigned int nbits);
46*0febaae0SAlexandru Elisei 
bitmap_and(unsigned long * dst,const unsigned long * src1,const unsigned long * src2,unsigned int nbits)47*0febaae0SAlexandru Elisei static inline bool bitmap_and(unsigned long *dst, const unsigned long *src1,
48*0febaae0SAlexandru Elisei 			      const unsigned long *src2, unsigned int nbits)
49*0febaae0SAlexandru Elisei {
50*0febaae0SAlexandru Elisei 	if (nbits >= 0 && nbits <= BITS_PER_LONG)
51*0febaae0SAlexandru Elisei 		return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0;
52*0febaae0SAlexandru Elisei 
53*0febaae0SAlexandru Elisei 	return __bitmap_and(dst, src1, src2, nbits);
54*0febaae0SAlexandru Elisei }
55*0febaae0SAlexandru Elisei 
56*0febaae0SAlexandru Elisei int bitmap_parselist(const char *buf, unsigned long *maskp, int nmaskbits);
57*0febaae0SAlexandru Elisei 
58*0febaae0SAlexandru Elisei bool __bitmap_subset(const unsigned long *bitmap1, const unsigned long *bitmap2,
59*0febaae0SAlexandru Elisei 		     unsigned int nbits);
60*0febaae0SAlexandru Elisei 
bitmap_subset(const unsigned long * src1,const unsigned long * src2,unsigned int nbits)61*0febaae0SAlexandru Elisei static inline bool bitmap_subset(const unsigned long *src1,
62*0febaae0SAlexandru Elisei 				 const unsigned long *src2, unsigned int nbits)
63*0febaae0SAlexandru Elisei {
64*0febaae0SAlexandru Elisei 	if (nbits >= 0 && nbits <= BITS_PER_LONG)
65*0febaae0SAlexandru Elisei 		return !((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits));
66*0febaae0SAlexandru Elisei 
67*0febaae0SAlexandru Elisei 	return __bitmap_subset(src1, src2, nbits);
68*0febaae0SAlexandru Elisei }
69*0febaae0SAlexandru Elisei 
70*0febaae0SAlexandru Elisei 
71*0febaae0SAlexandru Elisei #endif /* KVM__BITMAP_H */
72