xref: /openbmc/linux/fs/xfs/libxfs/xfs_bit.c (revision 1d4292bf)
11cfc4a9cSDave Chinner /*
21cfc4a9cSDave Chinner  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
31cfc4a9cSDave Chinner  * All Rights Reserved.
41cfc4a9cSDave Chinner  *
51cfc4a9cSDave Chinner  * This program is free software; you can redistribute it and/or
61cfc4a9cSDave Chinner  * modify it under the terms of the GNU General Public License as
71cfc4a9cSDave Chinner  * published by the Free Software Foundation.
81cfc4a9cSDave Chinner  *
91cfc4a9cSDave Chinner  * This program is distributed in the hope that it would be useful,
101cfc4a9cSDave Chinner  * but WITHOUT ANY WARRANTY; without even the implied warranty of
111cfc4a9cSDave Chinner  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
121cfc4a9cSDave Chinner  * GNU General Public License for more details.
131cfc4a9cSDave Chinner  *
141cfc4a9cSDave Chinner  * You should have received a copy of the GNU General Public License
151cfc4a9cSDave Chinner  * along with this program; if not, write the Free Software Foundation,
161cfc4a9cSDave Chinner  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
171cfc4a9cSDave Chinner  */
181cfc4a9cSDave Chinner #include "xfs.h"
191cfc4a9cSDave Chinner #include "xfs_log_format.h"
201cfc4a9cSDave Chinner #include "xfs_bit.h"
211cfc4a9cSDave Chinner 
221cfc4a9cSDave Chinner /*
231cfc4a9cSDave Chinner  * XFS bit manipulation routines, used in non-realtime code.
241cfc4a9cSDave Chinner  */
251cfc4a9cSDave Chinner 
261cfc4a9cSDave Chinner /*
271cfc4a9cSDave Chinner  * Return whether bitmap is empty.
281cfc4a9cSDave Chinner  * Size is number of words in the bitmap, which is padded to word boundary
291cfc4a9cSDave Chinner  * Returns 1 for empty, 0 for non-empty.
301cfc4a9cSDave Chinner  */
311cfc4a9cSDave Chinner int
321cfc4a9cSDave Chinner xfs_bitmap_empty(uint *map, uint size)
331cfc4a9cSDave Chinner {
341cfc4a9cSDave Chinner 	uint i;
351cfc4a9cSDave Chinner 
361cfc4a9cSDave Chinner 	for (i = 0; i < size; i++) {
371d4292bfSJia He 		if (map[i] != 0)
381d4292bfSJia He 			return 0;
391cfc4a9cSDave Chinner 	}
401cfc4a9cSDave Chinner 
411d4292bfSJia He 	return 1;
421cfc4a9cSDave Chinner }
431cfc4a9cSDave Chinner 
441cfc4a9cSDave Chinner /*
451cfc4a9cSDave Chinner  * Count the number of contiguous bits set in the bitmap starting with bit
461cfc4a9cSDave Chinner  * start_bit.  Size is the size of the bitmap in words.
471cfc4a9cSDave Chinner  */
481cfc4a9cSDave Chinner int
491cfc4a9cSDave Chinner xfs_contig_bits(uint *map, uint	size, uint start_bit)
501cfc4a9cSDave Chinner {
511cfc4a9cSDave Chinner 	uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT);
521cfc4a9cSDave Chinner 	uint result = 0;
531cfc4a9cSDave Chinner 	uint tmp;
541cfc4a9cSDave Chinner 
551cfc4a9cSDave Chinner 	size <<= BIT_TO_WORD_SHIFT;
561cfc4a9cSDave Chinner 
571cfc4a9cSDave Chinner 	ASSERT(start_bit < size);
581cfc4a9cSDave Chinner 	size -= start_bit & ~(NBWORD - 1);
591cfc4a9cSDave Chinner 	start_bit &= (NBWORD - 1);
601cfc4a9cSDave Chinner 	if (start_bit) {
611cfc4a9cSDave Chinner 		tmp = *p++;
621cfc4a9cSDave Chinner 		/* set to one first offset bits prior to start */
631cfc4a9cSDave Chinner 		tmp |= (~0U >> (NBWORD-start_bit));
641cfc4a9cSDave Chinner 		if (tmp != ~0U)
651cfc4a9cSDave Chinner 			goto found;
661cfc4a9cSDave Chinner 		result += NBWORD;
671cfc4a9cSDave Chinner 		size -= NBWORD;
681cfc4a9cSDave Chinner 	}
691cfc4a9cSDave Chinner 	while (size) {
701cfc4a9cSDave Chinner 		if ((tmp = *p++) != ~0U)
711cfc4a9cSDave Chinner 			goto found;
721cfc4a9cSDave Chinner 		result += NBWORD;
731cfc4a9cSDave Chinner 		size -= NBWORD;
741cfc4a9cSDave Chinner 	}
751cfc4a9cSDave Chinner 	return result - start_bit;
761cfc4a9cSDave Chinner found:
771cfc4a9cSDave Chinner 	return result + ffz(tmp) - start_bit;
781cfc4a9cSDave Chinner }
791cfc4a9cSDave Chinner 
801cfc4a9cSDave Chinner /*
811cfc4a9cSDave Chinner  * This takes the bit number to start looking from and
821cfc4a9cSDave Chinner  * returns the next set bit from there.  It returns -1
831cfc4a9cSDave Chinner  * if there are no more bits set or the start bit is
841cfc4a9cSDave Chinner  * beyond the end of the bitmap.
851cfc4a9cSDave Chinner  *
861cfc4a9cSDave Chinner  * Size is the number of words, not bytes, in the bitmap.
871cfc4a9cSDave Chinner  */
881cfc4a9cSDave Chinner int xfs_next_bit(uint *map, uint size, uint start_bit)
891cfc4a9cSDave Chinner {
901cfc4a9cSDave Chinner 	uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT);
911cfc4a9cSDave Chinner 	uint result = start_bit & ~(NBWORD - 1);
921cfc4a9cSDave Chinner 	uint tmp;
931cfc4a9cSDave Chinner 
941cfc4a9cSDave Chinner 	size <<= BIT_TO_WORD_SHIFT;
951cfc4a9cSDave Chinner 
961cfc4a9cSDave Chinner 	if (start_bit >= size)
971cfc4a9cSDave Chinner 		return -1;
981cfc4a9cSDave Chinner 	size -= result;
991cfc4a9cSDave Chinner 	start_bit &= (NBWORD - 1);
1001cfc4a9cSDave Chinner 	if (start_bit) {
1011cfc4a9cSDave Chinner 		tmp = *p++;
1021cfc4a9cSDave Chinner 		/* set to zero first offset bits prior to start */
1031cfc4a9cSDave Chinner 		tmp &= (~0U << start_bit);
1041cfc4a9cSDave Chinner 		if (tmp != 0U)
1051cfc4a9cSDave Chinner 			goto found;
1061cfc4a9cSDave Chinner 		result += NBWORD;
1071cfc4a9cSDave Chinner 		size -= NBWORD;
1081cfc4a9cSDave Chinner 	}
1091cfc4a9cSDave Chinner 	while (size) {
1101cfc4a9cSDave Chinner 		if ((tmp = *p++) != 0U)
1111cfc4a9cSDave Chinner 			goto found;
1121cfc4a9cSDave Chinner 		result += NBWORD;
1131cfc4a9cSDave Chinner 		size -= NBWORD;
1141cfc4a9cSDave Chinner 	}
1151cfc4a9cSDave Chinner 	return -1;
1161cfc4a9cSDave Chinner found:
1171cfc4a9cSDave Chinner 	return result + ffs(tmp) - 1;
1181cfc4a9cSDave Chinner }
119