2005-04-17 02:20:36 +04:00
/*
2005-11-02 06:58:39 +03:00
* Copyright ( c ) 2000 - 2005 Silicon Graphics , Inc .
* All Rights Reserved .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
2005-04-17 02:20:36 +04:00
* published by the Free Software Foundation .
*
2005-11-02 06:58:39 +03:00
* This program is distributed in the hope that it would be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
2005-04-17 02:20:36 +04:00
*/
# include "xfs.h"
# include "xfs_bit.h"
# include "xfs_log.h"
# include "xfs_trans.h"
# include "xfs_buf_item.h"
2005-11-02 06:58:39 +03:00
/*
* XFS bit manipulation routines , used in non - realtime code .
*/
2005-04-17 02:20:36 +04:00
/*
2007-06-28 10:43:30 +04:00
* Return whether bitmap is empty .
* Size is number of words in the bitmap , which is padded to word boundary
* Returns 1 for empty , 0 for non - empty .
2005-04-17 02:20:36 +04:00
*/
int
2007-06-28 10:43:30 +04:00
xfs_bitmap_empty ( uint * map , uint size )
2005-04-17 02:20:36 +04:00
{
2007-06-28 10:43:30 +04:00
uint i ;
uint ret = 0 ;
2005-04-17 02:20:36 +04:00
2007-06-28 10:43:30 +04:00
for ( i = 0 ; i < size ; i + + ) {
ret | = map [ i ] ;
2005-04-17 02:20:36 +04:00
}
2007-06-28 10:43:30 +04:00
return ( ret = = 0 ) ;
2005-04-17 02:20:36 +04:00
}
/*
* Count the number of contiguous bits set in the bitmap starting with bit
* start_bit . Size is the size of the bitmap in words .
*/
int
xfs_contig_bits ( uint * map , uint size , uint start_bit )
{
uint * p = ( ( unsigned int * ) map ) + ( start_bit > > BIT_TO_WORD_SHIFT ) ;
uint result = 0 ;
uint tmp ;
size < < = BIT_TO_WORD_SHIFT ;
ASSERT ( start_bit < size ) ;
size - = start_bit & ~ ( NBWORD - 1 ) ;
start_bit & = ( NBWORD - 1 ) ;
if ( start_bit ) {
tmp = * p + + ;
/* set to one first offset bits prior to start */
tmp | = ( ~ 0U > > ( NBWORD - start_bit ) ) ;
if ( tmp ! = ~ 0U )
goto found ;
result + = NBWORD ;
size - = NBWORD ;
}
while ( size ) {
if ( ( tmp = * p + + ) ! = ~ 0U )
goto found ;
result + = NBWORD ;
size - = NBWORD ;
}
return result - start_bit ;
found :
return result + ffz ( tmp ) - start_bit ;
}
/*
* This takes the bit number to start looking from and
* returns the next set bit from there . It returns - 1
* if there are no more bits set or the start bit is
* beyond the end of the bitmap .
*
* Size is the number of words , not bytes , in the bitmap .
*/
int xfs_next_bit ( uint * map , uint size , uint start_bit )
{
uint * p = ( ( unsigned int * ) map ) + ( start_bit > > BIT_TO_WORD_SHIFT ) ;
uint result = start_bit & ~ ( NBWORD - 1 ) ;
uint tmp ;
size < < = BIT_TO_WORD_SHIFT ;
if ( start_bit > = size )
return - 1 ;
size - = result ;
start_bit & = ( NBWORD - 1 ) ;
if ( start_bit ) {
tmp = * p + + ;
/* set to zero first offset bits prior to start */
tmp & = ( ~ 0U < < start_bit ) ;
if ( tmp ! = 0U )
goto found ;
result + = NBWORD ;
size - = NBWORD ;
}
while ( size ) {
if ( ( tmp = * p + + ) ! = 0U )
goto found ;
result + = NBWORD ;
size - = NBWORD ;
}
return - 1 ;
found :
return result + ffs ( tmp ) - 1 ;
}