diff options
Diffstat (limited to 'lib/bitmap.c')
-rw-r--r-- | lib/bitmap.c | 123 |
1 files changed, 64 insertions, 59 deletions
diff --git a/lib/bitmap.c b/lib/bitmap.c index 06f7e4fe8d2d..b499ab6ada29 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
@@ -40,9 +40,9 @@ | |||
40 | * for the best explanations of this ordering. | 40 | * for the best explanations of this ordering. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | int __bitmap_empty(const unsigned long *bitmap, int bits) | 43 | int __bitmap_empty(const unsigned long *bitmap, unsigned int bits) |
44 | { | 44 | { |
45 | int k, lim = bits/BITS_PER_LONG; | 45 | unsigned int k, lim = bits/BITS_PER_LONG; |
46 | for (k = 0; k < lim; ++k) | 46 | for (k = 0; k < lim; ++k) |
47 | if (bitmap[k]) | 47 | if (bitmap[k]) |
48 | return 0; | 48 | return 0; |
@@ -55,9 +55,9 @@ int __bitmap_empty(const unsigned long *bitmap, int bits) | |||
55 | } | 55 | } |
56 | EXPORT_SYMBOL(__bitmap_empty); | 56 | EXPORT_SYMBOL(__bitmap_empty); |
57 | 57 | ||
58 | int __bitmap_full(const unsigned long *bitmap, int bits) | 58 | int __bitmap_full(const unsigned long *bitmap, unsigned int bits) |
59 | { | 59 | { |
60 | int k, lim = bits/BITS_PER_LONG; | 60 | unsigned int k, lim = bits/BITS_PER_LONG; |
61 | for (k = 0; k < lim; ++k) | 61 | for (k = 0; k < lim; ++k) |
62 | if (~bitmap[k]) | 62 | if (~bitmap[k]) |
63 | return 0; | 63 | return 0; |
@@ -71,9 +71,9 @@ int __bitmap_full(const unsigned long *bitmap, int bits) | |||
71 | EXPORT_SYMBOL(__bitmap_full); | 71 | EXPORT_SYMBOL(__bitmap_full); |
72 | 72 | ||
73 | int __bitmap_equal(const unsigned long *bitmap1, | 73 | int __bitmap_equal(const unsigned long *bitmap1, |
74 | const unsigned long *bitmap2, int bits) | 74 | const unsigned long *bitmap2, unsigned int bits) |
75 | { | 75 | { |
76 | int k, lim = bits/BITS_PER_LONG; | 76 | unsigned int k, lim = bits/BITS_PER_LONG; |
77 | for (k = 0; k < lim; ++k) | 77 | for (k = 0; k < lim; ++k) |
78 | if (bitmap1[k] != bitmap2[k]) | 78 | if (bitmap1[k] != bitmap2[k]) |
79 | return 0; | 79 | return 0; |
@@ -86,14 +86,14 @@ int __bitmap_equal(const unsigned long *bitmap1, | |||
86 | } | 86 | } |
87 | EXPORT_SYMBOL(__bitmap_equal); | 87 | EXPORT_SYMBOL(__bitmap_equal); |
88 | 88 | ||
89 | void __bitmap_complement(unsigned long *dst, const unsigned long *src, int bits) | 89 | void __bitmap_complement(unsigned long *dst, const unsigned long *src, unsigned int bits) |
90 | { | 90 | { |
91 | int k, lim = bits/BITS_PER_LONG; | 91 | unsigned int k, lim = bits/BITS_PER_LONG; |
92 | for (k = 0; k < lim; ++k) | 92 | for (k = 0; k < lim; ++k) |
93 | dst[k] = ~src[k]; | 93 | dst[k] = ~src[k]; |
94 | 94 | ||
95 | if (bits % BITS_PER_LONG) | 95 | if (bits % BITS_PER_LONG) |
96 | dst[k] = ~src[k] & BITMAP_LAST_WORD_MASK(bits); | 96 | dst[k] = ~src[k]; |
97 | } | 97 | } |
98 | EXPORT_SYMBOL(__bitmap_complement); | 98 | EXPORT_SYMBOL(__bitmap_complement); |
99 | 99 | ||
@@ -131,7 +131,9 @@ void __bitmap_shift_right(unsigned long *dst, | |||
131 | lower = src[off + k]; | 131 | lower = src[off + k]; |
132 | if (left && off + k == lim - 1) | 132 | if (left && off + k == lim - 1) |
133 | lower &= mask; | 133 | lower &= mask; |
134 | dst[k] = upper << (BITS_PER_LONG - rem) | lower >> rem; | 134 | dst[k] = lower >> rem; |
135 | if (rem) | ||
136 | dst[k] |= upper << (BITS_PER_LONG - rem); | ||
135 | if (left && k == lim - 1) | 137 | if (left && k == lim - 1) |
136 | dst[k] &= mask; | 138 | dst[k] &= mask; |
137 | } | 139 | } |
@@ -172,7 +174,9 @@ void __bitmap_shift_left(unsigned long *dst, | |||
172 | upper = src[k]; | 174 | upper = src[k]; |
173 | if (left && k == lim - 1) | 175 | if (left && k == lim - 1) |
174 | upper &= (1UL << left) - 1; | 176 | upper &= (1UL << left) - 1; |
175 | dst[k + off] = lower >> (BITS_PER_LONG - rem) | upper << rem; | 177 | dst[k + off] = upper << rem; |
178 | if (rem) | ||
179 | dst[k + off] |= lower >> (BITS_PER_LONG - rem); | ||
176 | if (left && k + off == lim - 1) | 180 | if (left && k + off == lim - 1) |
177 | dst[k + off] &= (1UL << left) - 1; | 181 | dst[k + off] &= (1UL << left) - 1; |
178 | } | 182 | } |
@@ -182,23 +186,26 @@ void __bitmap_shift_left(unsigned long *dst, | |||
182 | EXPORT_SYMBOL(__bitmap_shift_left); | 186 | EXPORT_SYMBOL(__bitmap_shift_left); |
183 | 187 | ||
184 | int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, | 188 | int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, |
185 | const unsigned long *bitmap2, int bits) | 189 | const unsigned long *bitmap2, unsigned int bits) |
186 | { | 190 | { |
187 | int k; | 191 | unsigned int k; |
188 | int nr = BITS_TO_LONGS(bits); | 192 | unsigned int lim = bits/BITS_PER_LONG; |
189 | unsigned long result = 0; | 193 | unsigned long result = 0; |
190 | 194 | ||
191 | for (k = 0; k < nr; k++) | 195 | for (k = 0; k < lim; k++) |
192 | result |= (dst[k] = bitmap1[k] & bitmap2[k]); | 196 | result |= (dst[k] = bitmap1[k] & bitmap2[k]); |
197 | if (bits % BITS_PER_LONG) | ||
198 | result |= (dst[k] = bitmap1[k] & bitmap2[k] & | ||
199 | BITMAP_LAST_WORD_MASK(bits)); | ||
193 | return result != 0; | 200 | return result != 0; |
194 | } | 201 | } |
195 | EXPORT_SYMBOL(__bitmap_and); | 202 | EXPORT_SYMBOL(__bitmap_and); |
196 | 203 | ||
197 | void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, | 204 | void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, |
198 | const unsigned long *bitmap2, int bits) | 205 | const unsigned long *bitmap2, unsigned int bits) |
199 | { | 206 | { |
200 | int k; | 207 | unsigned int k; |
201 | int nr = BITS_TO_LONGS(bits); | 208 | unsigned int nr = BITS_TO_LONGS(bits); |
202 | 209 | ||
203 | for (k = 0; k < nr; k++) | 210 | for (k = 0; k < nr; k++) |
204 | dst[k] = bitmap1[k] | bitmap2[k]; | 211 | dst[k] = bitmap1[k] | bitmap2[k]; |
@@ -206,10 +213,10 @@ void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, | |||
206 | EXPORT_SYMBOL(__bitmap_or); | 213 | EXPORT_SYMBOL(__bitmap_or); |
207 | 214 | ||
208 | void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, | 215 | void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, |
209 | const unsigned long *bitmap2, int bits) | 216 | const unsigned long *bitmap2, unsigned int bits) |
210 | { | 217 | { |
211 | int k; | 218 | unsigned int k; |
212 | int nr = BITS_TO_LONGS(bits); | 219 | unsigned int nr = BITS_TO_LONGS(bits); |
213 | 220 | ||
214 | for (k = 0; k < nr; k++) | 221 | for (k = 0; k < nr; k++) |
215 | dst[k] = bitmap1[k] ^ bitmap2[k]; | 222 | dst[k] = bitmap1[k] ^ bitmap2[k]; |
@@ -217,22 +224,25 @@ void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, | |||
217 | EXPORT_SYMBOL(__bitmap_xor); | 224 | EXPORT_SYMBOL(__bitmap_xor); |
218 | 225 | ||
219 | int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, | 226 | int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, |
220 | const unsigned long *bitmap2, int bits) | 227 | const unsigned long *bitmap2, unsigned int bits) |
221 | { | 228 | { |
222 | int k; | 229 | unsigned int k; |
223 | int nr = BITS_TO_LONGS(bits); | 230 | unsigned int lim = bits/BITS_PER_LONG; |
224 | unsigned long result = 0; | 231 | unsigned long result = 0; |
225 | 232 | ||
226 | for (k = 0; k < nr; k++) | 233 | for (k = 0; k < lim; k++) |
227 | result |= (dst[k] = bitmap1[k] & ~bitmap2[k]); | 234 | result |= (dst[k] = bitmap1[k] & ~bitmap2[k]); |
235 | if (bits % BITS_PER_LONG) | ||
236 | result |= (dst[k] = bitmap1[k] & ~bitmap2[k] & | ||
237 | BITMAP_LAST_WORD_MASK(bits)); | ||
228 | return result != 0; | 238 | return result != 0; |
229 | } | 239 | } |
230 | EXPORT_SYMBOL(__bitmap_andnot); | 240 | EXPORT_SYMBOL(__bitmap_andnot); |
231 | 241 | ||
232 | int __bitmap_intersects(const unsigned long *bitmap1, | 242 | int __bitmap_intersects(const unsigned long *bitmap1, |
233 | const unsigned long *bitmap2, int bits) | 243 | const unsigned long *bitmap2, unsigned int bits) |
234 | { | 244 | { |
235 | int k, lim = bits/BITS_PER_LONG; | 245 | unsigned int k, lim = bits/BITS_PER_LONG; |
236 | for (k = 0; k < lim; ++k) | 246 | for (k = 0; k < lim; ++k) |
237 | if (bitmap1[k] & bitmap2[k]) | 247 | if (bitmap1[k] & bitmap2[k]) |
238 | return 1; | 248 | return 1; |
@@ -245,9 +255,9 @@ int __bitmap_intersects(const unsigned long *bitmap1, | |||
245 | EXPORT_SYMBOL(__bitmap_intersects); | 255 | EXPORT_SYMBOL(__bitmap_intersects); |
246 | 256 | ||
247 | int __bitmap_subset(const unsigned long *bitmap1, | 257 | int __bitmap_subset(const unsigned long *bitmap1, |
248 | const unsigned long *bitmap2, int bits) | 258 | const unsigned long *bitmap2, unsigned int bits) |
249 | { | 259 | { |
250 | int k, lim = bits/BITS_PER_LONG; | 260 | unsigned int k, lim = bits/BITS_PER_LONG; |
251 | for (k = 0; k < lim; ++k) | 261 | for (k = 0; k < lim; ++k) |
252 | if (bitmap1[k] & ~bitmap2[k]) | 262 | if (bitmap1[k] & ~bitmap2[k]) |
253 | return 0; | 263 | return 0; |
@@ -259,9 +269,10 @@ int __bitmap_subset(const unsigned long *bitmap1, | |||
259 | } | 269 | } |
260 | EXPORT_SYMBOL(__bitmap_subset); | 270 | EXPORT_SYMBOL(__bitmap_subset); |
261 | 271 | ||
262 | int __bitmap_weight(const unsigned long *bitmap, int bits) | 272 | int __bitmap_weight(const unsigned long *bitmap, unsigned int bits) |
263 | { | 273 | { |
264 | int k, w = 0, lim = bits/BITS_PER_LONG; | 274 | unsigned int k, lim = bits/BITS_PER_LONG; |
275 | int w = 0; | ||
265 | 276 | ||
266 | for (k = 0; k < lim; k++) | 277 | for (k = 0; k < lim; k++) |
267 | w += hweight_long(bitmap[k]); | 278 | w += hweight_long(bitmap[k]); |
@@ -273,42 +284,42 @@ int __bitmap_weight(const unsigned long *bitmap, int bits) | |||
273 | } | 284 | } |
274 | EXPORT_SYMBOL(__bitmap_weight); | 285 | EXPORT_SYMBOL(__bitmap_weight); |
275 | 286 | ||
276 | void bitmap_set(unsigned long *map, int start, int nr) | 287 | void bitmap_set(unsigned long *map, unsigned int start, int len) |
277 | { | 288 | { |
278 | unsigned long *p = map + BIT_WORD(start); | 289 | unsigned long *p = map + BIT_WORD(start); |
279 | const int size = start + nr; | 290 | const unsigned int size = start + len; |
280 | int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); | 291 | int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); |
281 | unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); | 292 | unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); |
282 | 293 | ||
283 | while (nr - bits_to_set >= 0) { | 294 | while (len - bits_to_set >= 0) { |
284 | *p |= mask_to_set; | 295 | *p |= mask_to_set; |
285 | nr -= bits_to_set; | 296 | len -= bits_to_set; |
286 | bits_to_set = BITS_PER_LONG; | 297 | bits_to_set = BITS_PER_LONG; |
287 | mask_to_set = ~0UL; | 298 | mask_to_set = ~0UL; |
288 | p++; | 299 | p++; |
289 | } | 300 | } |
290 | if (nr) { | 301 | if (len) { |
291 | mask_to_set &= BITMAP_LAST_WORD_MASK(size); | 302 | mask_to_set &= BITMAP_LAST_WORD_MASK(size); |
292 | *p |= mask_to_set; | 303 | *p |= mask_to_set; |
293 | } | 304 | } |
294 | } | 305 | } |
295 | EXPORT_SYMBOL(bitmap_set); | 306 | EXPORT_SYMBOL(bitmap_set); |
296 | 307 | ||
297 | void bitmap_clear(unsigned long *map, int start, int nr) | 308 | void bitmap_clear(unsigned long *map, unsigned int start, int len) |
298 | { | 309 | { |
299 | unsigned long *p = map + BIT_WORD(start); | 310 | unsigned long *p = map + BIT_WORD(start); |
300 | const int size = start + nr; | 311 | const unsigned int size = start + len; |
301 | int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); | 312 | int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); |
302 | unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); | 313 | unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); |
303 | 314 | ||
304 | while (nr - bits_to_clear >= 0) { | 315 | while (len - bits_to_clear >= 0) { |
305 | *p &= ~mask_to_clear; | 316 | *p &= ~mask_to_clear; |
306 | nr -= bits_to_clear; | 317 | len -= bits_to_clear; |
307 | bits_to_clear = BITS_PER_LONG; | 318 | bits_to_clear = BITS_PER_LONG; |
308 | mask_to_clear = ~0UL; | 319 | mask_to_clear = ~0UL; |
309 | p++; | 320 | p++; |
310 | } | 321 | } |
311 | if (nr) { | 322 | if (len) { |
312 | mask_to_clear &= BITMAP_LAST_WORD_MASK(size); | 323 | mask_to_clear &= BITMAP_LAST_WORD_MASK(size); |
313 | *p &= ~mask_to_clear; | 324 | *p &= ~mask_to_clear; |
314 | } | 325 | } |
@@ -664,13 +675,8 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, | |||
664 | 675 | ||
665 | int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits) | 676 | int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits) |
666 | { | 677 | { |
667 | char *nl = strchr(bp, '\n'); | 678 | char *nl = strchrnul(bp, '\n'); |
668 | int len; | 679 | int len = nl - bp; |
669 | |||
670 | if (nl) | ||
671 | len = nl - bp; | ||
672 | else | ||
673 | len = strlen(bp); | ||
674 | 680 | ||
675 | return __bitmap_parselist(bp, len, 0, maskp, nmaskbits); | 681 | return __bitmap_parselist(bp, len, 0, maskp, nmaskbits); |
676 | } | 682 | } |
@@ -716,7 +722,7 @@ EXPORT_SYMBOL(bitmap_parselist_user); | |||
716 | * | 722 | * |
717 | * If for example, just bits 4 through 7 are set in @buf, then @pos | 723 | * If for example, just bits 4 through 7 are set in @buf, then @pos |
718 | * values 4 through 7 will get mapped to 0 through 3, respectively, | 724 | * values 4 through 7 will get mapped to 0 through 3, respectively, |
719 | * and other @pos values will get mapped to 0. When @pos value 7 | 725 | * and other @pos values will get mapped to -1. When @pos value 7 |
720 | * gets mapped to (returns) @ord value 3 in this example, that means | 726 | * gets mapped to (returns) @ord value 3 in this example, that means |
721 | * that bit 7 is the 3rd (starting with 0th) set bit in @buf. | 727 | * that bit 7 is the 3rd (starting with 0th) set bit in @buf. |
722 | * | 728 | * |
@@ -882,7 +888,7 @@ EXPORT_SYMBOL(bitmap_bitremap); | |||
882 | * read it, you're overqualified for your current job.) | 888 | * read it, you're overqualified for your current job.) |
883 | * | 889 | * |
884 | * In other words, @orig is mapped onto (surjectively) @dst, | 890 | * In other words, @orig is mapped onto (surjectively) @dst, |
885 | * using the the map { <n, m> | the n-th bit of @relmap is the | 891 | * using the map { <n, m> | the n-th bit of @relmap is the |
886 | * m-th set bit of @relmap }. | 892 | * m-th set bit of @relmap }. |
887 | * | 893 | * |
888 | * Any set bits in @orig above bit number W, where W is the | 894 | * Any set bits in @orig above bit number W, where W is the |
@@ -930,7 +936,7 @@ EXPORT_SYMBOL(bitmap_bitremap); | |||
930 | * | 936 | * |
931 | * Further lets say we use the following code, invoking | 937 | * Further lets say we use the following code, invoking |
932 | * bitmap_fold() then bitmap_onto, as suggested above to | 938 | * bitmap_fold() then bitmap_onto, as suggested above to |
933 | * avoid the possitility of an empty @dst result: | 939 | * avoid the possibility of an empty @dst result: |
934 | * | 940 | * |
935 | * unsigned long *tmp; // a temporary bitmap's bits | 941 | * unsigned long *tmp; // a temporary bitmap's bits |
936 | * | 942 | * |
@@ -1046,7 +1052,7 @@ enum { | |||
1046 | REG_OP_RELEASE, /* clear all bits in region */ | 1052 | REG_OP_RELEASE, /* clear all bits in region */ |
1047 | }; | 1053 | }; |
1048 | 1054 | ||
1049 | static int __reg_op(unsigned long *bitmap, int pos, int order, int reg_op) | 1055 | static int __reg_op(unsigned long *bitmap, unsigned int pos, int order, int reg_op) |
1050 | { | 1056 | { |
1051 | int nbits_reg; /* number of bits in region */ | 1057 | int nbits_reg; /* number of bits in region */ |
1052 | int index; /* index first long of region in bitmap */ | 1058 | int index; /* index first long of region in bitmap */ |
@@ -1112,11 +1118,11 @@ done: | |||
1112 | * Return the bit offset in bitmap of the allocated region, | 1118 | * Return the bit offset in bitmap of the allocated region, |
1113 | * or -errno on failure. | 1119 | * or -errno on failure. |
1114 | */ | 1120 | */ |
1115 | int bitmap_find_free_region(unsigned long *bitmap, int bits, int order) | 1121 | int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order) |
1116 | { | 1122 | { |
1117 | int pos, end; /* scans bitmap by regions of size order */ | 1123 | unsigned int pos, end; /* scans bitmap by regions of size order */ |
1118 | 1124 | ||
1119 | for (pos = 0 ; (end = pos + (1 << order)) <= bits; pos = end) { | 1125 | for (pos = 0 ; (end = pos + (1U << order)) <= bits; pos = end) { |
1120 | if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE)) | 1126 | if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE)) |
1121 | continue; | 1127 | continue; |
1122 | __reg_op(bitmap, pos, order, REG_OP_ALLOC); | 1128 | __reg_op(bitmap, pos, order, REG_OP_ALLOC); |
@@ -1137,7 +1143,7 @@ EXPORT_SYMBOL(bitmap_find_free_region); | |||
1137 | * | 1143 | * |
1138 | * No return value. | 1144 | * No return value. |
1139 | */ | 1145 | */ |
1140 | void bitmap_release_region(unsigned long *bitmap, int pos, int order) | 1146 | void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order) |
1141 | { | 1147 | { |
1142 | __reg_op(bitmap, pos, order, REG_OP_RELEASE); | 1148 | __reg_op(bitmap, pos, order, REG_OP_RELEASE); |
1143 | } | 1149 | } |
@@ -1154,12 +1160,11 @@ EXPORT_SYMBOL(bitmap_release_region); | |||
1154 | * Return 0 on success, or %-EBUSY if specified region wasn't | 1160 | * Return 0 on success, or %-EBUSY if specified region wasn't |
1155 | * free (not all bits were zero). | 1161 | * free (not all bits were zero). |
1156 | */ | 1162 | */ |
1157 | int bitmap_allocate_region(unsigned long *bitmap, int pos, int order) | 1163 | int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order) |
1158 | { | 1164 | { |
1159 | if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE)) | 1165 | if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE)) |
1160 | return -EBUSY; | 1166 | return -EBUSY; |
1161 | __reg_op(bitmap, pos, order, REG_OP_ALLOC); | 1167 | return __reg_op(bitmap, pos, order, REG_OP_ALLOC); |
1162 | return 0; | ||
1163 | } | 1168 | } |
1164 | EXPORT_SYMBOL(bitmap_allocate_region); | 1169 | EXPORT_SYMBOL(bitmap_allocate_region); |
1165 | 1170 | ||