xref: /kvmtool/util/find.c (revision 0febaae00bb6f8c5e694f87d6354fbcbe81e6653)
1 /*
2  * Taken from Linux kernel version v5.16.
3  */
4 #include "linux/bitmap.h"
5 #include "linux/find.h"
6 #include "linux/kernel.h"
7 
_find_next_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long nbits,unsigned long start,unsigned long invert)8 unsigned long _find_next_bit(const unsigned long *addr1,
9 		const unsigned long *addr2, unsigned long nbits,
10 		unsigned long start, unsigned long invert)
11 {
12 	unsigned long tmp, mask;
13 
14 	if (start >= nbits)
15 		return nbits;
16 
17 	tmp = addr1[start / BITS_PER_LONG];
18 	if (addr2)
19 		tmp &= addr2[start / BITS_PER_LONG];
20 	tmp ^= invert;
21 
22 	/* Handle 1st word. */
23 	mask = BITMAP_FIRST_WORD_MASK(start);
24 	tmp &= mask;
25 
26 	start = round_down(start, BITS_PER_LONG);
27 
28 	while (!tmp) {
29 		start += BITS_PER_LONG;
30 		if (start >= nbits)
31 			return nbits;
32 
33 		tmp = addr1[start / BITS_PER_LONG];
34 		if (addr2)
35 			tmp &= addr2[start / BITS_PER_LONG];
36 		tmp ^= invert;
37 	}
38 
39 	return min(start + __builtin_ctzl(tmp), nbits);
40 }
41