1
2
3
4
5
6
7
8
9
10
11
12#ifndef BITMAP_H
13#define BITMAP_H
14
15#include <glib.h>
16#include <string.h>
17#include <stdlib.h>
18
19#include "qemu/osdep.h"
20#include "qemu/bitops.h"
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62#define BITMAP_LAST_WORD_MASK(nbits) \
63 ( \
64 ((nbits) % BITS_PER_LONG) ? \
65 (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \
66 )
67
68#define DECLARE_BITMAP(name,bits) \
69 unsigned long name[BITS_TO_LONGS(bits)]
70
71#define small_nbits(nbits) \
72 ((nbits) <= BITS_PER_LONG)
73
74int slow_bitmap_empty(const unsigned long *bitmap, long bits);
75int slow_bitmap_full(const unsigned long *bitmap, long bits);
76int slow_bitmap_equal(const unsigned long *bitmap1,
77 const unsigned long *bitmap2, long bits);
78void slow_bitmap_complement(unsigned long *dst, const unsigned long *src,
79 long bits);
80void slow_bitmap_shift_right(unsigned long *dst,
81 const unsigned long *src, int shift, long bits);
82void slow_bitmap_shift_left(unsigned long *dst,
83 const unsigned long *src, int shift, long bits);
84int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
85 const unsigned long *bitmap2, long bits);
86void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
87 const unsigned long *bitmap2, long bits);
88void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
89 const unsigned long *bitmap2, long bits);
90int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
91 const unsigned long *bitmap2, long bits);
92int slow_bitmap_intersects(const unsigned long *bitmap1,
93 const unsigned long *bitmap2, long bits);
94
95static inline unsigned long *bitmap_try_new(long nbits)
96{
97 long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
98 return g_try_malloc0(len);
99}
100
101static inline unsigned long *bitmap_new(long nbits)
102{
103 unsigned long *ptr = bitmap_try_new(nbits);
104 if (ptr == NULL) {
105 abort();
106 }
107 return ptr;
108}
109
110static inline void bitmap_zero(unsigned long *dst, long nbits)
111{
112 if (small_nbits(nbits)) {
113 *dst = 0UL;
114 } else {
115 long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
116 memset(dst, 0, len);
117 }
118}
119
120static inline void bitmap_fill(unsigned long *dst, long nbits)
121{
122 size_t nlongs = BITS_TO_LONGS(nbits);
123 if (!small_nbits(nbits)) {
124 long len = (nlongs - 1) * sizeof(unsigned long);
125 memset(dst, 0xff, len);
126 }
127 dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
128}
129
130static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
131 long nbits)
132{
133 if (small_nbits(nbits)) {
134 *dst = *src;
135 } else {
136 long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
137 memcpy(dst, src, len);
138 }
139}
140
141static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
142 const unsigned long *src2, long nbits)
143{
144 if (small_nbits(nbits)) {
145 return (*dst = *src1 & *src2) != 0;
146 }
147 return slow_bitmap_and(dst, src1, src2, nbits);
148}
149
150static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
151 const unsigned long *src2, long nbits)
152{
153 if (small_nbits(nbits)) {
154 *dst = *src1 | *src2;
155 } else {
156 slow_bitmap_or(dst, src1, src2, nbits);
157 }
158}
159
160static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
161 const unsigned long *src2, long nbits)
162{
163 if (small_nbits(nbits)) {
164 *dst = *src1 ^ *src2;
165 } else {
166 slow_bitmap_xor(dst, src1, src2, nbits);
167 }
168}
169
170static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
171 const unsigned long *src2, long nbits)
172{
173 if (small_nbits(nbits)) {
174 return (*dst = *src1 & ~(*src2)) != 0;
175 }
176 return slow_bitmap_andnot(dst, src1, src2, nbits);
177}
178
179static inline void bitmap_complement(unsigned long *dst,
180 const unsigned long *src,
181 long nbits)
182{
183 if (small_nbits(nbits)) {
184 *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits);
185 } else {
186 slow_bitmap_complement(dst, src, nbits);
187 }
188}
189
190static inline int bitmap_equal(const unsigned long *src1,
191 const unsigned long *src2, long nbits)
192{
193 if (small_nbits(nbits)) {
194 return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
195 } else {
196 return slow_bitmap_equal(src1, src2, nbits);
197 }
198}
199
200static inline int bitmap_empty(const unsigned long *src, long nbits)
201{
202 if (small_nbits(nbits)) {
203 return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
204 } else {
205 return slow_bitmap_empty(src, nbits);
206 }
207}
208
209static inline int bitmap_full(const unsigned long *src, long nbits)
210{
211 if (small_nbits(nbits)) {
212 return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
213 } else {
214 return slow_bitmap_full(src, nbits);
215 }
216}
217
218static inline int bitmap_intersects(const unsigned long *src1,
219 const unsigned long *src2, long nbits)
220{
221 if (small_nbits(nbits)) {
222 return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
223 } else {
224 return slow_bitmap_intersects(src1, src2, nbits);
225 }
226}
227
228void bitmap_set(unsigned long *map, long i, long len);
229void bitmap_clear(unsigned long *map, long start, long nr);
230unsigned long bitmap_find_next_zero_area(unsigned long *map,
231 unsigned long size,
232 unsigned long start,
233 unsigned long nr,
234 unsigned long align_mask);
235
236static inline unsigned long *bitmap_zero_extend(unsigned long *old,
237 long old_nbits, long new_nbits)
238{
239 long new_len = BITS_TO_LONGS(new_nbits) * sizeof(unsigned long);
240 unsigned long *new = g_realloc(old, new_len);
241 bitmap_clear(new, old_nbits, new_nbits - old_nbits);
242 return new;
243}
244
245#endif
246