2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2016-01-08 17:26:43 +03:00
/* bit search implementation
2014-12-16 01:50:12 +03:00
*
2016-01-08 17:26:43 +03:00
* Copied from lib / find_bit . c to tools / lib / find_bit . c
2014-12-16 01:50:12 +03:00
*
* Copyright ( C ) 2004 Red Hat , Inc . All Rights Reserved .
* Written by David Howells ( dhowells @ redhat . com )
*
2016-01-08 17:26:43 +03:00
* Copyright ( C ) 2008 IBM Corporation
* ' find_last_bit ' is written by Rusty Russell < rusty @ rustcorp . com . au >
* ( Inspired by David Howell ' s find_next_bit implementation )
*
* Rewritten by Yury Norov < yury . norov @ gmail . com > to decrease
* size and improve performance , 2015.
2014-12-16 01:50:12 +03:00
*/
# include <linux/bitops.h>
2016-01-08 17:26:43 +03:00
# include <linux/bitmap.h>
# include <linux/kernel.h>
2014-12-16 01:50:12 +03:00
/*
2022-09-15 05:07:30 +03:00
* Common helper for find_bit ( ) function family
* @ FETCH : The expression that fetches and pre - processes each word of bitmap ( s )
* @ MUNGE : The expression that post - processes a word containing found bit ( may be empty )
* @ size : The bitmap size in bits
2014-12-16 01:50:12 +03:00
*/
2022-09-15 05:07:30 +03:00
# define FIND_FIRST_BIT(FETCH, MUNGE, size) \
( { \
unsigned long idx , val , sz = ( size ) ; \
\
for ( idx = 0 ; idx * BITS_PER_LONG < sz ; idx + + ) { \
val = ( FETCH ) ; \
if ( val ) { \
sz = min ( idx * BITS_PER_LONG + __ffs ( MUNGE ( val ) ) , sz ) ; \
break ; \
} \
} \
\
sz ; \
} )
2021-05-07 04:03:07 +03:00
2022-09-15 05:07:30 +03:00
/*
* Common helper for find_next_bit ( ) function family
* @ FETCH : The expression that fetches and pre - processes each word of bitmap ( s )
* @ MUNGE : The expression that post - processes a word containing found bit ( may be empty )
* @ size : The bitmap size in bits
* @ start : The bitnumber to start searching at
*/
# define FIND_NEXT_BIT(FETCH, MUNGE, size, start) \
( { \
unsigned long mask , idx , tmp , sz = ( size ) , __start = ( start ) ; \
\
if ( unlikely ( __start > = sz ) ) \
goto out ; \
\
mask = MUNGE ( BITMAP_FIRST_WORD_MASK ( __start ) ) ; \
idx = __start / BITS_PER_LONG ; \
\
for ( tmp = ( FETCH ) & mask ; ! tmp ; tmp = ( FETCH ) ) { \
if ( ( idx + 1 ) * BITS_PER_LONG > = sz ) \
goto out ; \
idx + + ; \
} \
\
sz = min ( idx * BITS_PER_LONG + __ffs ( MUNGE ( tmp ) ) , sz ) ; \
out : \
sz ; \
} )
2014-12-16 01:50:12 +03:00
# ifndef find_first_bit
/*
* Find the first set bit in a memory region .
*/
2021-05-07 04:03:18 +03:00
unsigned long _find_first_bit ( const unsigned long * addr , unsigned long size )
2014-12-16 01:50:12 +03:00
{
2022-09-15 05:07:30 +03:00
return FIND_FIRST_BIT ( addr [ idx ] , /* nop */ , size ) ;
2014-12-16 01:50:12 +03:00
}
# endif
2016-10-10 10:26:33 +03:00
2021-08-15 00:17:04 +03:00
# ifndef find_first_and_bit
/*
* Find the first set bit in two memory regions .
*/
unsigned long _find_first_and_bit ( const unsigned long * addr1 ,
const unsigned long * addr2 ,
unsigned long size )
{
2022-09-15 05:07:30 +03:00
return FIND_FIRST_BIT ( addr1 [ idx ] & addr2 [ idx ] , /* nop */ , size ) ;
2021-08-15 00:17:04 +03:00
}
# endif
2016-10-10 10:26:33 +03:00
# ifndef find_first_zero_bit
/*
* Find the first cleared bit in a memory region .
*/
2021-05-07 04:03:18 +03:00
unsigned long _find_first_zero_bit ( const unsigned long * addr , unsigned long size )
2016-10-10 10:26:33 +03:00
{
2022-09-15 05:07:30 +03:00
return FIND_FIRST_BIT ( ~ addr [ idx ] , /* nop */ , size ) ;
}
# endif
2016-10-10 10:26:33 +03:00
2022-09-15 05:07:30 +03:00
# ifndef find_next_bit
unsigned long _find_next_bit ( const unsigned long * addr , unsigned long nbits , unsigned long start )
{
return FIND_NEXT_BIT ( addr [ idx ] , /* nop */ , nbits , start ) ;
}
# endif
2016-10-10 10:26:33 +03:00
2022-09-15 05:07:30 +03:00
# ifndef find_next_and_bit
unsigned long _find_next_and_bit ( const unsigned long * addr1 , const unsigned long * addr2 ,
unsigned long nbits , unsigned long start )
{
return FIND_NEXT_BIT ( addr1 [ idx ] & addr2 [ idx ] , /* nop */ , nbits , start ) ;
}
# endif
# ifndef find_next_zero_bit
unsigned long _find_next_zero_bit ( const unsigned long * addr , unsigned long nbits ,
unsigned long start )
{
return FIND_NEXT_BIT ( ~ addr [ idx ] , /* nop */ , nbits , start ) ;
2016-10-10 10:26:33 +03:00
}
# endif