]> Git Repo - qemu.git/blame - include/qemu/bitmap.h
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
[qemu.git] / include / qemu / bitmap.h
CommitLineData
e0e53b2f
CC
1/*
2 * Bitmap Module
3 *
4 * Copyright (C) 2010 Corentin Chary <[email protected]>
5 *
6 * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h
7 *
8 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
9 * See the COPYING.LIB file in the top-level directory.
10 */
11
12#ifndef BITMAP_H
13#define BITMAP_H
14
d6aaddfe
EH
15#include <glib.h>
16#include <string.h>
17#include <stdlib.h>
18
19#include "qemu/osdep.h"
1de7afc9 20#include "qemu/bitops.h"
e0e53b2f
CC
21
22/*
23 * The available bitmap operations and their rough meaning in the
24 * case that the bitmap is a single unsigned long are thus:
25 *
26 * Note that nbits should be always a compile time evaluable constant.
27 * Otherwise many inlines will generate horrible code.
28 *
29 * bitmap_zero(dst, nbits) *dst = 0UL
30 * bitmap_fill(dst, nbits) *dst = ~0UL
31 * bitmap_copy(dst, src, nbits) *dst = *src
32 * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2
33 * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2
34 * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2
35 * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2)
36 * bitmap_complement(dst, src, nbits) *dst = ~(*src)
37 * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal?
9c22687e 38 * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap?
e0e53b2f
CC
39 * bitmap_empty(src, nbits) Are all bits zero in *src?
40 * bitmap_full(src, nbits) Are all bits set in *src?
41 * bitmap_set(dst, pos, nbits) Set specified bit area
9f02cfc8 42 * bitmap_set_atomic(dst, pos, nbits) Set specified bit area with atomic ops
e0e53b2f 43 * bitmap_clear(dst, pos, nbits) Clear specified bit area
36546e5b 44 * bitmap_test_and_clear_atomic(dst, pos, nbits) Test and clear area
e0e53b2f
CC
45 * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
46 */
47
48/*
49 * Also the following operations apply to bitmaps.
50 *
51 * set_bit(bit, addr) *addr |= bit
52 * clear_bit(bit, addr) *addr &= ~bit
53 * change_bit(bit, addr) *addr ^= bit
54 * test_bit(bit, addr) Is bit set in *addr?
55 * test_and_set_bit(bit, addr) Set bit and return old value
56 * test_and_clear_bit(bit, addr) Clear bit and return old value
57 * test_and_change_bit(bit, addr) Change bit and return old value
58 * find_first_zero_bit(addr, nbits) Position first zero bit in *addr
59 * find_first_bit(addr, nbits) Position first set bit in *addr
60 * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit
61 * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit
62 */
63
64#define BITMAP_LAST_WORD_MASK(nbits) \
65 ( \
66 ((nbits) % BITS_PER_LONG) ? \
67 (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \
68 )
69
70#define DECLARE_BITMAP(name,bits) \
9c22687e 71 unsigned long name[BITS_TO_LONGS(bits)]
e0e53b2f
CC
72
73#define small_nbits(nbits) \
9c22687e 74 ((nbits) <= BITS_PER_LONG)
e0e53b2f 75
9c22687e
JQ
76int slow_bitmap_empty(const unsigned long *bitmap, long bits);
77int slow_bitmap_full(const unsigned long *bitmap, long bits);
e0e53b2f 78int slow_bitmap_equal(const unsigned long *bitmap1,
9c22687e 79 const unsigned long *bitmap2, long bits);
e0e53b2f 80void slow_bitmap_complement(unsigned long *dst, const unsigned long *src,
9c22687e 81 long bits);
e0e53b2f 82void slow_bitmap_shift_right(unsigned long *dst,
9c22687e 83 const unsigned long *src, int shift, long bits);
e0e53b2f 84void slow_bitmap_shift_left(unsigned long *dst,
9c22687e 85 const unsigned long *src, int shift, long bits);
e0e53b2f 86int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
9c22687e 87 const unsigned long *bitmap2, long bits);
e0e53b2f 88void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
9c22687e 89 const unsigned long *bitmap2, long bits);
e0e53b2f 90void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
9c22687e 91 const unsigned long *bitmap2, long bits);
e0e53b2f 92int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
9c22687e 93 const unsigned long *bitmap2, long bits);
e0e53b2f 94int slow_bitmap_intersects(const unsigned long *bitmap1,
9c22687e 95 const unsigned long *bitmap2, long bits);
e0e53b2f 96
be4d57c1 97static inline unsigned long *bitmap_try_new(long nbits)
e0e53b2f 98{
9c22687e 99 long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
be4d57c1
PL
100 return g_try_malloc0(len);
101}
102
103static inline unsigned long *bitmap_new(long nbits)
104{
105 unsigned long *ptr = bitmap_try_new(nbits);
106 if (ptr == NULL) {
107 abort();
108 }
109 return ptr;
e0e53b2f
CC
110}
111
9c22687e 112static inline void bitmap_zero(unsigned long *dst, long nbits)
e0e53b2f
CC
113{
114 if (small_nbits(nbits)) {
115 *dst = 0UL;
116 } else {
9c22687e 117 long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
e0e53b2f
CC
118 memset(dst, 0, len);
119 }
120}
121
9c22687e 122static inline void bitmap_fill(unsigned long *dst, long nbits)
e0e53b2f
CC
123{
124 size_t nlongs = BITS_TO_LONGS(nbits);
125 if (!small_nbits(nbits)) {
9c22687e 126 long len = (nlongs - 1) * sizeof(unsigned long);
e0e53b2f
CC
127 memset(dst, 0xff, len);
128 }
129 dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
130}
131
132static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
9c22687e 133 long nbits)
e0e53b2f
CC
134{
135 if (small_nbits(nbits)) {
136 *dst = *src;
137 } else {
9c22687e 138 long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
e0e53b2f
CC
139 memcpy(dst, src, len);
140 }
141}
142
143static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
9c22687e 144 const unsigned long *src2, long nbits)
e0e53b2f
CC
145{
146 if (small_nbits(nbits)) {
147 return (*dst = *src1 & *src2) != 0;
148 }
149 return slow_bitmap_and(dst, src1, src2, nbits);
150}
151
152static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
9c22687e 153 const unsigned long *src2, long nbits)
e0e53b2f
CC
154{
155 if (small_nbits(nbits)) {
156 *dst = *src1 | *src2;
157 } else {
158 slow_bitmap_or(dst, src1, src2, nbits);
159 }
160}
161
162static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
9c22687e 163 const unsigned long *src2, long nbits)
e0e53b2f
CC
164{
165 if (small_nbits(nbits)) {
166 *dst = *src1 ^ *src2;
167 } else {
168 slow_bitmap_xor(dst, src1, src2, nbits);
169 }
170}
171
172static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
9c22687e 173 const unsigned long *src2, long nbits)
e0e53b2f
CC
174{
175 if (small_nbits(nbits)) {
176 return (*dst = *src1 & ~(*src2)) != 0;
177 }
178 return slow_bitmap_andnot(dst, src1, src2, nbits);
179}
180
9c22687e
JQ
181static inline void bitmap_complement(unsigned long *dst,
182 const unsigned long *src,
183 long nbits)
e0e53b2f
CC
184{
185 if (small_nbits(nbits)) {
186 *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits);
187 } else {
188 slow_bitmap_complement(dst, src, nbits);
189 }
190}
191
192static inline int bitmap_equal(const unsigned long *src1,
9c22687e 193 const unsigned long *src2, long nbits)
e0e53b2f
CC
194{
195 if (small_nbits(nbits)) {
196 return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
197 } else {
198 return slow_bitmap_equal(src1, src2, nbits);
199 }
200}
201
9c22687e 202static inline int bitmap_empty(const unsigned long *src, long nbits)
e0e53b2f
CC
203{
204 if (small_nbits(nbits)) {
205 return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
206 } else {
207 return slow_bitmap_empty(src, nbits);
208 }
209}
210
9c22687e 211static inline int bitmap_full(const unsigned long *src, long nbits)
e0e53b2f
CC
212{
213 if (small_nbits(nbits)) {
214 return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
215 } else {
216 return slow_bitmap_full(src, nbits);
217 }
218}
219
220static inline int bitmap_intersects(const unsigned long *src1,
9c22687e 221 const unsigned long *src2, long nbits)
e0e53b2f
CC
222{
223 if (small_nbits(nbits)) {
224 return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
225 } else {
226 return slow_bitmap_intersects(src1, src2, nbits);
227 }
228}
229
9c22687e 230void bitmap_set(unsigned long *map, long i, long len);
9f02cfc8 231void bitmap_set_atomic(unsigned long *map, long i, long len);
9c22687e 232void bitmap_clear(unsigned long *map, long start, long nr);
36546e5b 233bool bitmap_test_and_clear_atomic(unsigned long *map, long start, long nr);
e0e53b2f 234unsigned long bitmap_find_next_zero_area(unsigned long *map,
9c22687e
JQ
235 unsigned long size,
236 unsigned long start,
237 unsigned long nr,
238 unsigned long align_mask);
e0e53b2f 239
164590a6
JQ
240static inline unsigned long *bitmap_zero_extend(unsigned long *old,
241 long old_nbits, long new_nbits)
242{
243 long new_len = BITS_TO_LONGS(new_nbits) * sizeof(unsigned long);
244 unsigned long *new = g_realloc(old, new_len);
245 bitmap_clear(new, old_nbits, new_nbits - old_nbits);
246 return new;
247}
248
e0e53b2f 249#endif /* BITMAP_H */
This page took 0.304286 seconds and 4 git commands to generate.