44 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2#include <linux/bitmap.h>3#include <linux/math.h>4#include <linux/minmax.h>5 6/*7 * Common helper for find_next_bit() function family8 * @FETCH: The expression that fetches and pre-processes each word of bitmap(s)9 * @MUNGE: The expression that post-processes a word containing found bit (may be empty)10 * @size: The bitmap size in bits11 * @start: The bitnumber to start searching at12 */13#define FIND_NEXT_BIT(FETCH, MUNGE, size, start) \14({ \15 unsigned long mask, idx, tmp, sz = (size), __start = (start); \16 \17 if (unlikely(__start >= sz)) \18 goto out; \19 \20 mask = MUNGE(BITMAP_FIRST_WORD_MASK(__start)); \21 idx = __start / BITS_PER_LONG; \22 \23 for (tmp = (FETCH) & mask; !tmp; tmp = (FETCH)) { \24 if ((idx + 1) * BITS_PER_LONG >= sz) \25 goto out; \26 idx++; \27 } \28 \29 sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(tmp)), sz); \30out: \31 sz; \32})33 34unsigned long _find_next_bit(const unsigned long *addr, unsigned long nbits, unsigned long start)35{36 return FIND_NEXT_BIT(addr[idx], /* nop */, nbits, start);37}38 39unsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits,40 unsigned long start)41{42 return FIND_NEXT_BIT(~addr[idx], /* nop */, nbits, start);43}44