diff options
Diffstat (limited to 'tools/lib/find_bit.c')
-rw-r--r-- | tools/lib/find_bit.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/tools/lib/find_bit.c b/tools/lib/find_bit.c index 42c15f906aac..a88bd507091e 100644 --- a/tools/lib/find_bit.c +++ b/tools/lib/find_bit.c | |||
@@ -22,22 +22,29 @@ | |||
22 | #include <linux/bitmap.h> | 22 | #include <linux/bitmap.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | 24 | ||
25 | #if !defined(find_next_bit) | 25 | #if !defined(find_next_bit) || !defined(find_next_zero_bit) || \ |
26 | !defined(find_next_and_bit) | ||
26 | 27 | ||
27 | /* | 28 | /* |
28 | * This is a common helper function for find_next_bit and | 29 | * This is a common helper function for find_next_bit, find_next_zero_bit, and |
29 | * find_next_zero_bit. The difference is the "invert" argument, which | 30 | * find_next_and_bit. The differences are: |
30 | * is XORed with each fetched word before searching it for one bits. | 31 | * - The "invert" argument, which is XORed with each fetched word before |
32 | * searching it for one bits. | ||
33 | * - The optional "addr2", which is anded with "addr1" if present. | ||
31 | */ | 34 | */ |
32 | static unsigned long _find_next_bit(const unsigned long *addr, | 35 | static inline unsigned long _find_next_bit(const unsigned long *addr1, |
33 | unsigned long nbits, unsigned long start, unsigned long invert) | 36 | const unsigned long *addr2, unsigned long nbits, |
37 | unsigned long start, unsigned long invert) | ||
34 | { | 38 | { |
35 | unsigned long tmp; | 39 | unsigned long tmp; |
36 | 40 | ||
37 | if (unlikely(start >= nbits)) | 41 | if (unlikely(start >= nbits)) |
38 | return nbits; | 42 | return nbits; |
39 | 43 | ||
40 | tmp = addr[start / BITS_PER_LONG] ^ invert; | 44 | tmp = addr1[start / BITS_PER_LONG]; |
45 | if (addr2) | ||
46 | tmp &= addr2[start / BITS_PER_LONG]; | ||
47 | tmp ^= invert; | ||
41 | 48 | ||
42 | /* Handle 1st word. */ | 49 | /* Handle 1st word. */ |
43 | tmp &= BITMAP_FIRST_WORD_MASK(start); | 50 | tmp &= BITMAP_FIRST_WORD_MASK(start); |
@@ -48,7 +55,10 @@ static unsigned long _find_next_bit(const unsigned long *addr, | |||
48 | if (start >= nbits) | 55 | if (start >= nbits) |
49 | return nbits; | 56 | return nbits; |
50 | 57 | ||
51 | tmp = addr[start / BITS_PER_LONG] ^ invert; | 58 | tmp = addr1[start / BITS_PER_LONG]; |
59 | if (addr2) | ||
60 | tmp &= addr2[start / BITS_PER_LONG]; | ||
61 | tmp ^= invert; | ||
52 | } | 62 | } |
53 | 63 | ||
54 | return min(start + __ffs(tmp), nbits); | 64 | return min(start + __ffs(tmp), nbits); |
@@ -62,7 +72,7 @@ static unsigned long _find_next_bit(const unsigned long *addr, | |||
62 | unsigned long find_next_bit(const unsigned long *addr, unsigned long size, | 72 | unsigned long find_next_bit(const unsigned long *addr, unsigned long size, |
63 | unsigned long offset) | 73 | unsigned long offset) |
64 | { | 74 | { |
65 | return _find_next_bit(addr, size, offset, 0UL); | 75 | return _find_next_bit(addr, NULL, size, offset, 0UL); |
66 | } | 76 | } |
67 | #endif | 77 | #endif |
68 | 78 | ||
@@ -104,6 +114,15 @@ unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) | |||
104 | unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, | 114 | unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, |
105 | unsigned long offset) | 115 | unsigned long offset) |
106 | { | 116 | { |
107 | return _find_next_bit(addr, size, offset, ~0UL); | 117 | return _find_next_bit(addr, NULL, size, offset, ~0UL); |
118 | } | ||
119 | #endif | ||
120 | |||
121 | #ifndef find_next_and_bit | ||
122 | unsigned long find_next_and_bit(const unsigned long *addr1, | ||
123 | const unsigned long *addr2, unsigned long size, | ||
124 | unsigned long offset) | ||
125 | { | ||
126 | return _find_next_bit(addr1, addr2, size, offset, 0UL); | ||
108 | } | 127 | } |
109 | #endif | 128 | #endif |