linux/include/asm-generic/bitops/find.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _ASM_GENERIC_BITOPS_FIND_H_
   3#define _ASM_GENERIC_BITOPS_FIND_H_
   4
   5extern unsigned long _find_next_bit(const unsigned long *addr1,
   6                const unsigned long *addr2, unsigned long nbits,
   7                unsigned long start, unsigned long invert, unsigned long le);
   8extern unsigned long _find_first_bit(const unsigned long *addr, unsigned long size);
   9extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size);
  10extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long size);
  11
  12#ifndef find_next_bit
  13/**
  14 * find_next_bit - find the next set bit in a memory region
  15 * @addr: The address to base the search on
  16 * @offset: The bitnumber to start searching at
  17 * @size: The bitmap size in bits
  18 *
  19 * Returns the bit number for the next set bit
  20 * If no bits are set, returns @size.
  21 */
  22static inline
  23unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
  24                            unsigned long offset)
  25{
  26        if (small_const_nbits(size)) {
  27                unsigned long val;
  28
  29                if (unlikely(offset >= size))
  30                        return size;
  31
  32                val = *addr & GENMASK(size - 1, offset);
  33                return val ? __ffs(val) : size;
  34        }
  35
  36        return _find_next_bit(addr, NULL, size, offset, 0UL, 0);
  37}
  38#endif
  39
  40#ifndef find_next_and_bit
  41/**
  42 * find_next_and_bit - find the next set bit in both memory regions
  43 * @addr1: The first address to base the search on
  44 * @addr2: The second address to base the search on
  45 * @offset: The bitnumber to start searching at
  46 * @size: The bitmap size in bits
  47 *
  48 * Returns the bit number for the next set bit
  49 * If no bits are set, returns @size.
  50 */
  51static inline
  52unsigned long find_next_and_bit(const unsigned long *addr1,
  53                const unsigned long *addr2, unsigned long size,
  54                unsigned long offset)
  55{
  56        if (small_const_nbits(size)) {
  57                unsigned long val;
  58
  59                if (unlikely(offset >= size))
  60                        return size;
  61
  62                val = *addr1 & *addr2 & GENMASK(size - 1, offset);
  63                return val ? __ffs(val) : size;
  64        }
  65
  66        return _find_next_bit(addr1, addr2, size, offset, 0UL, 0);
  67}
  68#endif
  69
  70#ifndef find_next_zero_bit
  71/**
  72 * find_next_zero_bit - find the next cleared bit in a memory region
  73 * @addr: The address to base the search on
  74 * @offset: The bitnumber to start searching at
  75 * @size: The bitmap size in bits
  76 *
  77 * Returns the bit number of the next zero bit
  78 * If no bits are zero, returns @size.
  79 */
  80static inline
  81unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
  82                                 unsigned long offset)
  83{
  84        if (small_const_nbits(size)) {
  85                unsigned long val;
  86
  87                if (unlikely(offset >= size))
  88                        return size;
  89
  90                val = *addr | ~GENMASK(size - 1, offset);
  91                return val == ~0UL ? size : ffz(val);
  92        }
  93
  94        return _find_next_bit(addr, NULL, size, offset, ~0UL, 0);
  95}
  96#endif
  97
  98#ifdef CONFIG_GENERIC_FIND_FIRST_BIT
  99
 100/**
 101 * find_first_bit - find the first set bit in a memory region
 102 * @addr: The address to start the search at
 103 * @size: The maximum number of bits to search
 104 *
 105 * Returns the bit number of the first set bit.
 106 * If no bits are set, returns @size.
 107 */
 108static inline
 109unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
 110{
 111        if (small_const_nbits(size)) {
 112                unsigned long val = *addr & GENMASK(size - 1, 0);
 113
 114                return val ? __ffs(val) : size;
 115        }
 116
 117        return _find_first_bit(addr, size);
 118}
 119
 120/**
 121 * find_first_zero_bit - find the first cleared bit in a memory region
 122 * @addr: The address to start the search at
 123 * @size: The maximum number of bits to search
 124 *
 125 * Returns the bit number of the first cleared bit.
 126 * If no bits are zero, returns @size.
 127 */
 128static inline
 129unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
 130{
 131        if (small_const_nbits(size)) {
 132                unsigned long val = *addr | ~GENMASK(size - 1, 0);
 133
 134                return val == ~0UL ? size : ffz(val);
 135        }
 136
 137        return _find_first_zero_bit(addr, size);
 138}
 139#else /* CONFIG_GENERIC_FIND_FIRST_BIT */
 140
 141#ifndef find_first_bit
 142#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
 143#endif
 144#ifndef find_first_zero_bit
 145#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
 146#endif
 147
 148#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
 149
 150#ifndef find_last_bit
 151/**
 152 * find_last_bit - find the last set bit in a memory region
 153 * @addr: The address to start the search at
 154 * @size: The number of bits to search
 155 *
 156 * Returns the bit number of the last set bit, or size.
 157 */
 158static inline
 159unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
 160{
 161        if (small_const_nbits(size)) {
 162                unsigned long val = *addr & GENMASK(size - 1, 0);
 163
 164                return val ? __fls(val) : size;
 165        }
 166
 167        return _find_last_bit(addr, size);
 168}
 169#endif
 170
 171/**
 172 * find_next_clump8 - find next 8-bit clump with set bits in a memory region
 173 * @clump: location to store copy of found clump
 174 * @addr: address to base the search on
 175 * @size: bitmap size in number of bits
 176 * @offset: bit offset at which to start searching
 177 *
 178 * Returns the bit offset for the next set clump; the found clump value is
 179 * copied to the location pointed by @clump. If no bits are set, returns @size.
 180 */
 181extern unsigned long find_next_clump8(unsigned long *clump,
 182                                      const unsigned long *addr,
 183                                      unsigned long size, unsigned long offset);
 184
 185#define find_first_clump8(clump, bits, size) \
 186        find_next_clump8((clump), (bits), (size), 0)
 187
 188#endif /*_ASM_GENERIC_BITOPS_FIND_H_ */
 189