diff options
Diffstat (limited to 'lib/bitmap.c')
| -rw-r--r-- | lib/bitmap.c | 81 | 
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/bitmap.c b/lib/bitmap.c index 702565821c9..11bf4975058 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -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.  |