|
@@ -271,6 +271,87 @@ int __bitmap_weight(const unsigned long *bitmap, int bits)
|
|
|
}
|
|
|
EXPORT_SYMBOL(__bitmap_weight);
|
|
|
|
|
|
+#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))
|
|
|
+
|
|
|
+void bitmap_set(unsigned long *map, int start, int nr)
|
|
|
+{
|
|
|
+ unsigned long *p = map + BIT_WORD(start);
|
|
|
+ const int size = start + nr;
|
|
|
+ int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
|
|
|
+ unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
|
|
|
+
|
|
|
+ while (nr - bits_to_set >= 0) {
|
|
|
+ *p |= mask_to_set;
|
|
|
+ nr -= bits_to_set;
|
|
|
+ bits_to_set = BITS_PER_LONG;
|
|
|
+ mask_to_set = ~0UL;
|
|
|
+ p++;
|
|
|
+ }
|
|
|
+ if (nr) {
|
|
|
+ mask_to_set &= BITMAP_LAST_WORD_MASK(size);
|
|
|
+ *p |= mask_to_set;
|
|
|
+ }
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(bitmap_set);
|
|
|
+
|
|
|
+void bitmap_clear(unsigned long *map, int start, int nr)
|
|
|
+{
|
|
|
+ unsigned long *p = map + BIT_WORD(start);
|
|
|
+ const int size = start + nr;
|
|
|
+ int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
|
|
|
+ unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
|
|
|
+
|
|
|
+ while (nr - bits_to_clear >= 0) {
|
|
|
+ *p &= ~mask_to_clear;
|
|
|
+ nr -= bits_to_clear;
|
|
|
+ bits_to_clear = BITS_PER_LONG;
|
|
|
+ mask_to_clear = ~0UL;
|
|
|
+ p++;
|
|
|
+ }
|
|
|
+ if (nr) {
|
|
|
+ mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
|
|
|
+ *p &= ~mask_to_clear;
|
|
|
+ }
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(bitmap_clear);
|
|
|
+
|
|
|
+/*
|
|
|
+ * bitmap_find_next_zero_area - find a contiguous aligned zero area
|
|
|
+ * @map: The address to base the search on
|
|
|
+ * @size: The bitmap size in bits
|
|
|
+ * @start: The bitnumber to start searching at
|
|
|
+ * @nr: The number of zeroed bits we're looking for
|
|
|
+ * @align_mask: Alignment mask for zero area
|
|
|
+ *
|
|
|
+ * The @align_mask should be one less than a power of 2; the effect is that
|
|
|
+ * the bit offset of all zero areas this function finds is multiples of that
|
|
|
+ * power of 2. A @align_mask of 0 means no alignment is required.
|
|
|
+ */
|
|
|
+unsigned long bitmap_find_next_zero_area(unsigned long *map,
|
|
|
+ unsigned long size,
|
|
|
+ unsigned long start,
|
|
|
+ unsigned int nr,
|
|
|
+ unsigned long align_mask)
|
|
|
+{
|
|
|
+ unsigned long index, end, i;
|
|
|
+again:
|
|
|
+ index = find_next_zero_bit(map, size, start);
|
|
|
+
|
|
|
+ /* Align allocation */
|
|
|
+ index = __ALIGN_MASK(index, align_mask);
|
|
|
+
|
|
|
+ end = index + nr;
|
|
|
+ if (end > size)
|
|
|
+ return end;
|
|
|
+ i = find_next_bit(map, end, index);
|
|
|
+ if (i < end) {
|
|
|
+ start = i + 1;
|
|
|
+ goto again;
|
|
|
+ }
|
|
|
+ return index;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(bitmap_find_next_zero_area);
|
|
|
+
|
|
|
/*
|
|
|
* Bitmap printing & parsing functions: first version by Bill Irwin,
|
|
|
* second version by Paul Jackson, third by Joe Korty.
|