Rev 6082 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3391 | Serge | 1 | /* |
2 | * lib/bitmap.c |
||
3 | * Helper functions for bitmap.h. |
||
4 | * |
||
5056 | serge | 5 | * This source code is licensed under the GNU General Public License, |
3391 | Serge | 6 | * Version 2. See the file COPYING for more details. |
7 | */ |
||
8 | #include |
||
9 | #include |
||
7143 | serge | 10 | #include |
3391 | Serge | 11 | #include |
12 | #include |
||
13 | #include |
||
14 | #include |
||
15 | #include |
||
7143 | serge | 16 | #include |
17 | #include |
||
18 | |||
19 | #include |
||
3391 | Serge | 20 | //#include |
21 | |||
22 | /* |
||
23 | * bitmaps provide an array of bits, implemented using an an |
||
24 | * array of unsigned longs. The number of valid bits in a |
||
25 | * given bitmap does _not_ need to be an exact multiple of |
||
26 | * BITS_PER_LONG. |
||
27 | * |
||
28 | * The possible unused bits in the last, partially used word |
||
29 | * of a bitmap are 'don't care'. The implementation makes |
||
30 | * no particular effort to keep them zero. It ensures that |
||
31 | * their value will not affect the results of any operation. |
||
32 | * The bitmap operations that return Boolean (bitmap_empty, |
||
33 | * for example) or scalar (bitmap_weight, for example) results |
||
34 | * carefully filter out these unused bits from impacting their |
||
35 | * results. |
||
36 | * |
||
37 | * These operations actually hold to a slightly stronger rule: |
||
38 | * if you don't input any bitmaps to these ops that have some |
||
39 | * unused bits set, then they won't output any set unused bits |
||
40 | * in output bitmaps. |
||
41 | * |
||
42 | * The byte ordering of bitmaps is more natural on little |
||
43 | * endian architectures. See the big-endian headers |
||
44 | * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h |
||
45 | * for the best explanations of this ordering. |
||
46 | */ |
||
47 | |||
48 | int __bitmap_equal(const unsigned long *bitmap1, |
||
5056 | serge | 49 | const unsigned long *bitmap2, unsigned int bits) |
3391 | Serge | 50 | { |
5056 | serge | 51 | unsigned int k, lim = bits/BITS_PER_LONG; |
3391 | Serge | 52 | for (k = 0; k < lim; ++k) |
53 | if (bitmap1[k] != bitmap2[k]) |
||
54 | return 0; |
||
55 | |||
56 | if (bits % BITS_PER_LONG) |
||
57 | if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) |
||
58 | return 0; |
||
59 | |||
60 | return 1; |
||
61 | } |
||
62 | EXPORT_SYMBOL(__bitmap_equal); |
||
63 | |||
5056 | serge | 64 | void __bitmap_complement(unsigned long *dst, const unsigned long *src, unsigned int bits) |
3391 | Serge | 65 | { |
5056 | serge | 66 | unsigned int k, lim = bits/BITS_PER_LONG; |
3391 | Serge | 67 | for (k = 0; k < lim; ++k) |
68 | dst[k] = ~src[k]; |
||
69 | |||
70 | if (bits % BITS_PER_LONG) |
||
5056 | serge | 71 | dst[k] = ~src[k]; |
3391 | Serge | 72 | } |
73 | EXPORT_SYMBOL(__bitmap_complement); |
||
74 | |||
75 | /** |
||
76 | * __bitmap_shift_right - logical right shift of the bits in a bitmap |
||
77 | * @dst : destination bitmap |
||
78 | * @src : source bitmap |
||
79 | * @shift : shift by this many bits |
||
6082 | serge | 80 | * @nbits : bitmap size, in bits |
3391 | Serge | 81 | * |
82 | * Shifting right (dividing) means moving bits in the MS -> LS bit |
||
83 | * direction. Zeros are fed into the vacated MS positions and the |
||
84 | * LS bits shifted off the bottom are lost. |
||
85 | */ |
||
6082 | serge | 86 | void __bitmap_shift_right(unsigned long *dst, const unsigned long *src, |
87 | unsigned shift, unsigned nbits) |
||
3391 | Serge | 88 | { |
6082 | serge | 89 | unsigned k, lim = BITS_TO_LONGS(nbits); |
90 | unsigned off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG; |
||
91 | unsigned long mask = BITMAP_LAST_WORD_MASK(nbits); |
||
3391 | Serge | 92 | for (k = 0; off + k < lim; ++k) { |
93 | unsigned long upper, lower; |
||
94 | |||
95 | /* |
||
96 | * If shift is not word aligned, take lower rem bits of |
||
97 | * word above and make them the top rem bits of result. |
||
98 | */ |
||
99 | if (!rem || off + k + 1 >= lim) |
||
100 | upper = 0; |
||
101 | else { |
||
102 | upper = src[off + k + 1]; |
||
6082 | serge | 103 | if (off + k + 1 == lim - 1) |
3391 | Serge | 104 | upper &= mask; |
6082 | serge | 105 | upper <<= (BITS_PER_LONG - rem); |
3391 | Serge | 106 | } |
107 | lower = src[off + k]; |
||
6082 | serge | 108 | if (off + k == lim - 1) |
3391 | Serge | 109 | lower &= mask; |
6082 | serge | 110 | lower >>= rem; |
111 | dst[k] = lower | upper; |
||
3391 | Serge | 112 | } |
113 | if (off) |
||
114 | memset(&dst[lim - off], 0, off*sizeof(unsigned long)); |
||
115 | } |
||
116 | EXPORT_SYMBOL(__bitmap_shift_right); |
||
117 | |||
118 | |||
119 | /** |
||
120 | * __bitmap_shift_left - logical left shift of the bits in a bitmap |
||
121 | * @dst : destination bitmap |
||
122 | * @src : source bitmap |
||
123 | * @shift : shift by this many bits |
||
6082 | serge | 124 | * @nbits : bitmap size, in bits |
3391 | Serge | 125 | * |
126 | * Shifting left (multiplying) means moving bits in the LS -> MS |
||
127 | * direction. Zeros are fed into the vacated LS bit positions |
||
128 | * and those MS bits shifted off the top are lost. |
||
129 | */ |
||
130 | |||
6082 | serge | 131 | void __bitmap_shift_left(unsigned long *dst, const unsigned long *src, |
132 | unsigned int shift, unsigned int nbits) |
||
3391 | Serge | 133 | { |
6082 | serge | 134 | int k; |
135 | unsigned int lim = BITS_TO_LONGS(nbits); |
||
136 | unsigned int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG; |
||
3391 | Serge | 137 | for (k = lim - off - 1; k >= 0; --k) { |
138 | unsigned long upper, lower; |
||
139 | |||
140 | /* |
||
141 | * If shift is not word aligned, take upper rem bits of |
||
142 | * word below and make them the bottom rem bits of result. |
||
143 | */ |
||
144 | if (rem && k > 0) |
||
6082 | serge | 145 | lower = src[k - 1] >> (BITS_PER_LONG - rem); |
3391 | Serge | 146 | else |
147 | lower = 0; |
||
6082 | serge | 148 | upper = src[k] << rem; |
149 | dst[k + off] = lower | upper; |
||
3391 | Serge | 150 | } |
151 | if (off) |
||
152 | memset(dst, 0, off*sizeof(unsigned long)); |
||
153 | } |
||
154 | EXPORT_SYMBOL(__bitmap_shift_left); |
||
155 | |||
156 | int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, |
||
5056 | serge | 157 | const unsigned long *bitmap2, unsigned int bits) |
3391 | Serge | 158 | { |
5056 | serge | 159 | unsigned int k; |
160 | unsigned int lim = bits/BITS_PER_LONG; |
||
3391 | Serge | 161 | unsigned long result = 0; |
162 | |||
5056 | serge | 163 | for (k = 0; k < lim; k++) |
3391 | Serge | 164 | result |= (dst[k] = bitmap1[k] & bitmap2[k]); |
5056 | serge | 165 | if (bits % BITS_PER_LONG) |
166 | result |= (dst[k] = bitmap1[k] & bitmap2[k] & |
||
167 | BITMAP_LAST_WORD_MASK(bits)); |
||
3391 | Serge | 168 | return result != 0; |
169 | } |
||
170 | EXPORT_SYMBOL(__bitmap_and); |
||
171 | |||
172 | void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, |
||
5056 | serge | 173 | const unsigned long *bitmap2, unsigned int bits) |
3391 | Serge | 174 | { |
5056 | serge | 175 | unsigned int k; |
176 | unsigned int nr = BITS_TO_LONGS(bits); |
||
3391 | Serge | 177 | |
178 | for (k = 0; k < nr; k++) |
||
179 | dst[k] = bitmap1[k] | bitmap2[k]; |
||
180 | } |
||
181 | EXPORT_SYMBOL(__bitmap_or); |
||
182 | |||
183 | void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, |
||
5056 | serge | 184 | const unsigned long *bitmap2, unsigned int bits) |
3391 | Serge | 185 | { |
5056 | serge | 186 | unsigned int k; |
187 | unsigned int nr = BITS_TO_LONGS(bits); |
||
3391 | Serge | 188 | |
189 | for (k = 0; k < nr; k++) |
||
190 | dst[k] = bitmap1[k] ^ bitmap2[k]; |
||
191 | } |
||
192 | EXPORT_SYMBOL(__bitmap_xor); |
||
193 | |||
194 | int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, |
||
5056 | serge | 195 | const unsigned long *bitmap2, unsigned int bits) |
3391 | Serge | 196 | { |
5056 | serge | 197 | unsigned int k; |
198 | unsigned int lim = bits/BITS_PER_LONG; |
||
3391 | Serge | 199 | unsigned long result = 0; |
200 | |||
5056 | serge | 201 | for (k = 0; k < lim; k++) |
3391 | Serge | 202 | result |= (dst[k] = bitmap1[k] & ~bitmap2[k]); |
5056 | serge | 203 | if (bits % BITS_PER_LONG) |
204 | result |= (dst[k] = bitmap1[k] & ~bitmap2[k] & |
||
205 | BITMAP_LAST_WORD_MASK(bits)); |
||
3391 | Serge | 206 | return result != 0; |
207 | } |
||
208 | EXPORT_SYMBOL(__bitmap_andnot); |
||
209 | |||
210 | int __bitmap_intersects(const unsigned long *bitmap1, |
||
5056 | serge | 211 | const unsigned long *bitmap2, unsigned int bits) |
3391 | Serge | 212 | { |
5056 | serge | 213 | unsigned int k, lim = bits/BITS_PER_LONG; |
3391 | Serge | 214 | for (k = 0; k < lim; ++k) |
215 | if (bitmap1[k] & bitmap2[k]) |
||
216 | return 1; |
||
217 | |||
218 | if (bits % BITS_PER_LONG) |