Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

lib/find_bit: introduce FIND_FIRST_BIT() macro

Now that we have many flavors of find_first_bit(), and expect even more,
it's better to have one macro that generates optimal code for all and makes
maintaining of slightly different functions simpler.

The logic common to all versions is moved to the new macro, and all the
flavors are generated by providing an FETCH macro-parameter, like
in this example:

#define FIND_FIRST_BIT(FETCH, MUNGE, size) ...

find_first_ornot_and_bit(addr1, addr2, addr3, size)
{
return FIND_FIRST_BIT(addr1[idx] | ~addr2[idx] & addr3[idx], /* nop */, size);
}

The FETCH may be of any complexity, as soon as it only refers
the bitmap(s) and an iterator idx.

MUNGE is here to support _le code generation for BE builds. May be
empty.

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Reviewed-by: Valentin Schneider <vschneid@redhat.com>
Signed-off-by: Yury Norov <yury.norov@gmail.com>

+24 -25
+24 -25
lib/find_bit.c
··· 19 19 #include <linux/minmax.h> 20 20 #include <linux/swab.h> 21 21 22 + /* 23 + * Common helper for find_bit() function family 24 + * @FETCH: The expression that fetches and pre-processes each word of bitmap(s) 25 + * @MUNGE: The expression that post-processes a word containing found bit (may be empty) 26 + * @size: The bitmap size in bits 27 + */ 28 + #define FIND_FIRST_BIT(FETCH, MUNGE, size) \ 29 + ({ \ 30 + unsigned long idx, val, sz = (size); \ 31 + \ 32 + for (idx = 0; idx * BITS_PER_LONG < sz; idx++) { \ 33 + val = (FETCH); \ 34 + if (val) { \ 35 + sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(val)), sz); \ 36 + break; \ 37 + } \ 38 + } \ 39 + \ 40 + sz; \ 41 + }) 42 + 22 43 #if !defined(find_next_bit) || !defined(find_next_zero_bit) || \ 23 44 !defined(find_next_bit_le) || !defined(find_next_zero_bit_le) || \ 24 45 !defined(find_next_and_bit) ··· 98 77 */ 99 78 unsigned long _find_first_bit(const unsigned long *addr, unsigned long size) 100 79 { 101 - unsigned long idx; 102 - 103 - for (idx = 0; idx * BITS_PER_LONG < size; idx++) { 104 - if (addr[idx]) 105 - return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size); 106 - } 107 - 108 - return size; 80 + return FIND_FIRST_BIT(addr[idx], /* nop */, size); 109 81 } 110 82 EXPORT_SYMBOL(_find_first_bit); 111 83 #endif ··· 111 97 const unsigned long *addr2, 112 98 unsigned long size) 113 99 { 114 - unsigned long idx, val; 115 - 116 - for (idx = 0; idx * BITS_PER_LONG < size; idx++) { 117 - val = addr1[idx] & addr2[idx]; 118 - if (val) 119 - return min(idx * BITS_PER_LONG + __ffs(val), size); 120 - } 121 - 122 - return size; 100 + return FIND_FIRST_BIT(addr1[idx] & addr2[idx], /* nop */, size); 123 101 } 124 102 EXPORT_SYMBOL(_find_first_and_bit); 125 103 #endif ··· 122 116 */ 123 117 unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size) 124 118 { 125 - unsigned long idx; 126 - 127 - for (idx = 0; idx * BITS_PER_LONG < size; idx++) { 128 - if (addr[idx] != ~0UL) 129 - return min(idx * BITS_PER_LONG + ffz(addr[idx]), size); 130 - } 131 - 132 - return size; 119 + return FIND_FIRST_BIT(~addr[idx], /* nop */, size); 133 120 } 134 121 EXPORT_SYMBOL(_find_first_zero_bit); 135 122 #endif