bitmap patches for 5.17-rc1
-----BEGIN PGP SIGNATURE-----
iQHJBAABCgAzFiEEi8GdvG6xMhdgpu/4sUSA/TofvsgFAmHi+xgVHHl1cnkubm9y
b3ZAZ21haWwuY29tAAoJELFEgP06H77IxdoMAMf3E+L51Ys/4iAiyJQNVoT3aIBC
A8ZVOB9he1OA3o3wBNIRKmICHk+ovnfCWcXTr9fG/Ade2wJz88NAsGPQ1Phywb+s
iGlpySllFN72RT9ZqtJhLEzgoHHOL0CzTW07TN9GJy4gQA2h2G9CTP+OmsQdnVqE
m9Fn3PSlJ5lhzePlKfnln8rGZFgrriJakfEFPC79n/7an4+2Hvkb5rWigo7KQc4Z
9YNqYUcHWZFUgq80adxEb9LlbMXdD+Z/8fCjOrAatuwVkD4RDt6iKD0mFGjHXGL7
MZ9KRS8AfZXawmetk3jjtsV+/QkeS+Deuu7k0FoO0Th2QV7BGSDhsLXAS5By/MOC
nfSyHhnXHzCsBMyVNrJHmNhEZoN29+tRwI84JX9lWcf/OLANcCofnP6f2UIX7tZY
CAZAgVELp+0YQXdybrfzTQ8BT3TinjS/aZtCrYijRendI1GwUXcyl69vdOKqAHuk
5jy8k/xHyp+ZWu6v+PyAAAEGowY++qhL0fmszA==
=RKW4
-----END PGP SIGNATURE-----
Merge tag 'bitmap-5.17-rc1' of git://github.com/norov/linux
Pull bitmap updates from Yury Norov:
- introduce for_each_set_bitrange()
- use find_first_*_bit() instead of find_next_*_bit() where possible
- unify for_each_bit() macros
* tag 'bitmap-5.17-rc1' of git://github.com/norov/linux:
vsprintf: rework bitmap_list_string
lib: bitmap: add performance test for bitmap_print_to_pagebuf
bitmap: unify find_bit operations
mm/percpu: micro-optimize pcpu_is_populated()
Replace for_each_*_bit_from() with for_each_*_bit() where appropriate
find: micro-optimize for_each_{set,clear}_bit()
include/linux: move for_each_bit() macros from bitops.h to find.h
cpumask: replace cpumask_next_* with cpumask_first_* where appropriate
tools: sync tools/bitmap with mother linux
all: replace find_next{,_zero}_bit with find_first{,_zero}_bit where appropriate
cpumask: use find_first_and_bit()
lib: add find_first_and_bit()
arch: remove GENERIC_FIND_FIRST_BIT entirely
include: move find.h from asm_generic to linux
bitops: move find_bit_*_le functions from le.h to find.h
bitops: protect find_first_{,zero}_bit properly
This commit is contained in:
commit
3689f9f8b0
73 changed files with 635 additions and 438 deletions
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <linux/align.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/find.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
|
@ -54,12 +55,6 @@ struct device;
|
|||
* bitmap_clear(dst, pos, nbits) Clear specified bit area
|
||||
* bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
|
||||
* bitmap_find_next_zero_area_off(buf, len, pos, n, mask, mask_off) as above
|
||||
* bitmap_next_clear_region(map, &start, &end, nbits) Find next clear region
|
||||
* bitmap_next_set_region(map, &start, &end, nbits) Find next set region
|
||||
* bitmap_for_each_clear_region(map, rs, re, start, end)
|
||||
* Iterate over all clear regions
|
||||
* bitmap_for_each_set_region(map, rs, re, start, end)
|
||||
* Iterate over all set regions
|
||||
* bitmap_shift_right(dst, src, n, nbits) *dst = *src >> n
|
||||
* bitmap_shift_left(dst, src, n, nbits) *dst = *src << n
|
||||
* bitmap_cut(dst, src, first, n, nbits) Cut n bits from first, copy rest
|
||||
|
|
@ -466,14 +461,6 @@ static inline void bitmap_replace(unsigned long *dst,
|
|||
__bitmap_replace(dst, old, new, mask, nbits);
|
||||
}
|
||||
|
||||
static inline void bitmap_next_clear_region(unsigned long *bitmap,
|
||||
unsigned int *rs, unsigned int *re,
|
||||
unsigned int end)
|
||||
{
|
||||
*rs = find_next_zero_bit(bitmap, end, *rs);
|
||||
*re = find_next_bit(bitmap, end, *rs + 1);
|
||||
}
|
||||
|
||||
static inline void bitmap_next_set_region(unsigned long *bitmap,
|
||||
unsigned int *rs, unsigned int *re,
|
||||
unsigned int end)
|
||||
|
|
@ -482,25 +469,6 @@ static inline void bitmap_next_set_region(unsigned long *bitmap,
|
|||
*re = find_next_zero_bit(bitmap, end, *rs + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitmap region iterators. Iterates over the bitmap between [@start, @end).
|
||||
* @rs and @re should be integer variables and will be set to start and end
|
||||
* index of the current clear or set region.
|
||||
*/
|
||||
#define bitmap_for_each_clear_region(bitmap, rs, re, start, end) \
|
||||
for ((rs) = (start), \
|
||||
bitmap_next_clear_region((bitmap), &(rs), &(re), (end)); \
|
||||
(rs) < (re); \
|
||||
(rs) = (re) + 1, \
|
||||
bitmap_next_clear_region((bitmap), &(rs), &(re), (end)))
|
||||
|
||||
#define bitmap_for_each_set_region(bitmap, rs, re, start, end) \
|
||||
for ((rs) = (start), \
|
||||
bitmap_next_set_region((bitmap), &(rs), &(re), (end)); \
|
||||
(rs) < (re); \
|
||||
(rs) = (re) + 1, \
|
||||
bitmap_next_set_region((bitmap), &(rs), &(re), (end)))
|
||||
|
||||
/**
|
||||
* BITMAP_FROM_U64() - Represent u64 value in the format suitable for bitmap.
|
||||
* @n: u64 value
|
||||
|
|
|
|||
|
|
@ -32,40 +32,6 @@ extern unsigned long __sw_hweight64(__u64 w);
|
|||
*/
|
||||
#include <asm/bitops.h>
|
||||
|
||||
#define for_each_set_bit(bit, addr, size) \
|
||||
for ((bit) = find_first_bit((addr), (size)); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
||||
|
||||
/* same as for_each_set_bit() but use bit as value to start with */
|
||||
#define for_each_set_bit_from(bit, addr, size) \
|
||||
for ((bit) = find_next_bit((addr), (size), (bit)); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
||||
|
||||
#define for_each_clear_bit(bit, addr, size) \
|
||||
for ((bit) = find_first_zero_bit((addr), (size)); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_zero_bit((addr), (size), (bit) + 1))
|
||||
|
||||
/* same as for_each_clear_bit() but use bit as value to start with */
|
||||
#define for_each_clear_bit_from(bit, addr, size) \
|
||||
for ((bit) = find_next_zero_bit((addr), (size), (bit)); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_zero_bit((addr), (size), (bit) + 1))
|
||||
|
||||
/**
|
||||
* for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits
|
||||
* @start: bit offset to start search and to store the current iteration offset
|
||||
* @clump: location to store copy of current 8-bit clump
|
||||
* @bits: bitmap address to base the search on
|
||||
* @size: bitmap size in number of bits
|
||||
*/
|
||||
#define for_each_set_clump8(start, clump, bits, size) \
|
||||
for ((start) = find_first_clump8(&(clump), (bits), (size)); \
|
||||
(start) < (size); \
|
||||
(start) = find_next_clump8(&(clump), (bits), (size), (start) + 8))
|
||||
|
||||
static inline int get_bitmask_order(unsigned int count)
|
||||
{
|
||||
int order;
|
||||
|
|
|
|||
|
|
@ -123,6 +123,17 @@ static inline unsigned int cpumask_first(const struct cpumask *srcp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned int cpumask_first_zero(const struct cpumask *srcp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned int cpumask_first_and(const struct cpumask *srcp1,
|
||||
const struct cpumask *srcp2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned int cpumask_last(const struct cpumask *srcp)
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -167,7 +178,7 @@ static inline unsigned int cpumask_local_spread(unsigned int i, int node)
|
|||
|
||||
static inline int cpumask_any_and_distribute(const struct cpumask *src1p,
|
||||
const struct cpumask *src2p) {
|
||||
return cpumask_next_and(-1, src1p, src2p);
|
||||
return cpumask_first_and(src1p, src2p);
|
||||
}
|
||||
|
||||
static inline int cpumask_any_distribute(const struct cpumask *srcp)
|
||||
|
|
@ -195,6 +206,30 @@ static inline unsigned int cpumask_first(const struct cpumask *srcp)
|
|||
return find_first_bit(cpumask_bits(srcp), nr_cpumask_bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpumask_first_zero - get the first unset cpu in a cpumask
|
||||
* @srcp: the cpumask pointer
|
||||
*
|
||||
* Returns >= nr_cpu_ids if all cpus are set.
|
||||
*/
|
||||
static inline unsigned int cpumask_first_zero(const struct cpumask *srcp)
|
||||
{
|
||||
return find_first_zero_bit(cpumask_bits(srcp), nr_cpumask_bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpumask_first_and - return the first cpu from *srcp1 & *srcp2
|
||||
* @src1p: the first input
|
||||
* @src2p: the second input
|
||||
*
|
||||
* Returns >= nr_cpu_ids if no cpus set in both. See also cpumask_next_and().
|
||||
*/
|
||||
static inline
|
||||
unsigned int cpumask_first_and(const struct cpumask *srcp1, const struct cpumask *srcp2)
|
||||
{
|
||||
return find_first_and_bit(cpumask_bits(srcp1), cpumask_bits(srcp2), nr_cpumask_bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpumask_last - get the last CPU in a cpumask
|
||||
* @srcp: - the cpumask pointer
|
||||
|
|
@ -585,15 +620,6 @@ static inline void cpumask_copy(struct cpumask *dstp,
|
|||
*/
|
||||
#define cpumask_any(srcp) cpumask_first(srcp)
|
||||
|
||||
/**
|
||||
* cpumask_first_and - return the first cpu from *srcp1 & *srcp2
|
||||
* @src1p: the first input
|
||||
* @src2p: the second input
|
||||
*
|
||||
* Returns >= nr_cpu_ids if no cpus set in both. See also cpumask_next_and().
|
||||
*/
|
||||
#define cpumask_first_and(src1p, src2p) cpumask_next_and(-1, (src1p), (src2p))
|
||||
|
||||
/**
|
||||
* cpumask_any_and - pick a "random" cpu from *mask1 & *mask2
|
||||
* @mask1: the first input cpumask
|
||||
|
|
|
|||
372
include/linux/find.h
Normal file
372
include/linux/find.h
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LINUX_FIND_H_
|
||||
#define __LINUX_FIND_H_
|
||||
|
||||
#ifndef __LINUX_BITMAP_H
|
||||
#error only <linux/bitmap.h> can be included directly
|
||||
#endif
|
||||
|
||||
#include <linux/bitops.h>
|
||||
|
||||
extern unsigned long _find_next_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2, unsigned long nbits,
|
||||
unsigned long start, unsigned long invert, unsigned long le);
|
||||
extern unsigned long _find_first_bit(const unsigned long *addr, unsigned long size);
|
||||
extern unsigned long _find_first_and_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2, unsigned long size);
|
||||
extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size);
|
||||
extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long size);
|
||||
|
||||
#ifndef find_next_bit
|
||||
/**
|
||||
* find_next_bit - find the next set bit in a memory region
|
||||
* @addr: The address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The bitmap size in bits
|
||||
*
|
||||
* Returns the bit number for the next set bit
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val;
|
||||
|
||||
if (unlikely(offset >= size))
|
||||
return size;
|
||||
|
||||
val = *addr & GENMASK(size - 1, offset);
|
||||
return val ? __ffs(val) : size;
|
||||
}
|
||||
|
||||
return _find_next_bit(addr, NULL, size, offset, 0UL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef find_next_and_bit
|
||||
/**
|
||||
* find_next_and_bit - find the next set bit in both memory regions
|
||||
* @addr1: The first address to base the search on
|
||||
* @addr2: The second address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The bitmap size in bits
|
||||
*
|
||||
* Returns the bit number for the next set bit
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_next_and_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val;
|
||||
|
||||
if (unlikely(offset >= size))
|
||||
return size;
|
||||
|
||||
val = *addr1 & *addr2 & GENMASK(size - 1, offset);
|
||||
return val ? __ffs(val) : size;
|
||||
}
|
||||
|
||||
return _find_next_bit(addr1, addr2, size, offset, 0UL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef find_next_zero_bit
|
||||
/**
|
||||
* find_next_zero_bit - find the next cleared bit in a memory region
|
||||
* @addr: The address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The bitmap size in bits
|
||||
*
|
||||
* Returns the bit number of the next zero bit
|
||||
* If no bits are zero, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val;
|
||||
|
||||
if (unlikely(offset >= size))
|
||||
return size;
|
||||
|
||||
val = *addr | ~GENMASK(size - 1, offset);
|
||||
return val == ~0UL ? size : ffz(val);
|
||||
}
|
||||
|
||||
return _find_next_bit(addr, NULL, size, offset, ~0UL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef find_first_bit
|
||||
/**
|
||||
* find_first_bit - find the first set bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The maximum number of bits to search
|
||||
*
|
||||
* Returns the bit number of the first set bit.
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *addr & GENMASK(size - 1, 0);
|
||||
|
||||
return val ? __ffs(val) : size;
|
||||
}
|
||||
|
||||
return _find_first_bit(addr, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef find_first_and_bit
|
||||
/**
|
||||
* find_first_and_bit - find the first set bit in both memory regions
|
||||
* @addr1: The first address to base the search on
|
||||
* @addr2: The second address to base the search on
|
||||
* @size: The bitmap size in bits
|
||||
*
|
||||
* Returns the bit number for the next set bit
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_first_and_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2,
|
||||
unsigned long size)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *addr1 & *addr2 & GENMASK(size - 1, 0);
|
||||
|
||||
return val ? __ffs(val) : size;
|
||||
}
|
||||
|
||||
return _find_first_and_bit(addr1, addr2, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef find_first_zero_bit
|
||||
/**
|
||||
* find_first_zero_bit - find the first cleared bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The maximum number of bits to search
|
||||
*
|
||||
* Returns the bit number of the first cleared bit.
|
||||
* If no bits are zero, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *addr | ~GENMASK(size - 1, 0);
|
||||
|
||||
return val == ~0UL ? size : ffz(val);
|
||||
}
|
||||
|
||||
return _find_first_zero_bit(addr, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef find_last_bit
|
||||
/**
|
||||
* find_last_bit - find the last set bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The number of bits to search
|
||||
*
|
||||
* Returns the bit number of the last set bit, or size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *addr & GENMASK(size - 1, 0);
|
||||
|
||||
return val ? __fls(val) : size;
|
||||
}
|
||||
|
||||
return _find_last_bit(addr, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* find_next_clump8 - find next 8-bit clump with set bits in a memory region
|
||||
* @clump: location to store copy of found clump
|
||||
* @addr: address to base the search on
|
||||
* @size: bitmap size in number of bits
|
||||
* @offset: bit offset at which to start searching
|
||||
*
|
||||
* Returns the bit offset for the next set clump; the found clump value is
|
||||
* copied to the location pointed by @clump. If no bits are set, returns @size.
|
||||
*/
|
||||
extern unsigned long find_next_clump8(unsigned long *clump,
|
||||
const unsigned long *addr,
|
||||
unsigned long size, unsigned long offset);
|
||||
|
||||
#define find_first_clump8(clump, bits, size) \
|
||||
find_next_clump8((clump), (bits), (size), 0)
|
||||
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
|
||||
static inline unsigned long find_next_zero_bit_le(const void *addr,
|
||||
unsigned long size, unsigned long offset)
|
||||
{
|
||||
return find_next_zero_bit(addr, size, offset);
|
||||
}
|
||||
|
||||
static inline unsigned long find_next_bit_le(const void *addr,
|
||||
unsigned long size, unsigned long offset)
|
||||
{
|
||||
return find_next_bit(addr, size, offset);
|
||||
}
|
||||
|
||||
static inline unsigned long find_first_zero_bit_le(const void *addr,
|
||||
unsigned long size)
|
||||
{
|
||||
return find_first_zero_bit(addr, size);
|
||||
}
|
||||
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
|
||||
#ifndef find_next_zero_bit_le
|
||||
static inline
|
||||
unsigned long find_next_zero_bit_le(const void *addr, unsigned
|
||||
long size, unsigned long offset)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *(const unsigned long *)addr;
|
||||
|
||||
if (unlikely(offset >= size))
|
||||
return size;
|
||||
|
||||
val = swab(val) | ~GENMASK(size - 1, offset);
|
||||
return val == ~0UL ? size : ffz(val);
|
||||
}
|
||||
|
||||
return _find_next_bit(addr, NULL, size, offset, ~0UL, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef find_next_bit_le
|
||||
static inline
|
||||
unsigned long find_next_bit_le(const void *addr, unsigned
|
||||
long size, unsigned long offset)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *(const unsigned long *)addr;
|
||||
|
||||
if (unlikely(offset >= size))
|
||||
return size;
|
||||
|
||||
val = swab(val) & GENMASK(size - 1, offset);
|
||||
return val ? __ffs(val) : size;
|
||||
}
|
||||
|
||||
return _find_next_bit(addr, NULL, size, offset, 0UL, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef find_first_zero_bit_le
|
||||
#define find_first_zero_bit_le(addr, size) \
|
||||
find_next_zero_bit_le((addr), (size), 0)
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error "Please fix <asm/byteorder.h>"
|
||||
#endif
|
||||
|
||||
#define for_each_set_bit(bit, addr, size) \
|
||||
for ((bit) = find_next_bit((addr), (size), 0); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
||||
|
||||
/* same as for_each_set_bit() but use bit as value to start with */
|
||||
#define for_each_set_bit_from(bit, addr, size) \
|
||||
for ((bit) = find_next_bit((addr), (size), (bit)); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
||||
|
||||
#define for_each_clear_bit(bit, addr, size) \
|
||||
for ((bit) = find_next_zero_bit((addr), (size), 0); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_zero_bit((addr), (size), (bit) + 1))
|
||||
|
||||
/* same as for_each_clear_bit() but use bit as value to start with */
|
||||
#define for_each_clear_bit_from(bit, addr, size) \
|
||||
for ((bit) = find_next_zero_bit((addr), (size), (bit)); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_zero_bit((addr), (size), (bit) + 1))
|
||||
|
||||
/**
|
||||
* for_each_set_bitrange - iterate over all set bit ranges [b; e)
|
||||
* @b: bit offset of start of current bitrange (first set bit)
|
||||
* @e: bit offset of end of current bitrange (first unset bit)
|
||||
* @addr: bitmap address to base the search on
|
||||
* @size: bitmap size in number of bits
|
||||
*/
|
||||
#define for_each_set_bitrange(b, e, addr, size) \
|
||||
for ((b) = find_next_bit((addr), (size), 0), \
|
||||
(e) = find_next_zero_bit((addr), (size), (b) + 1); \
|
||||
(b) < (size); \
|
||||
(b) = find_next_bit((addr), (size), (e) + 1), \
|
||||
(e) = find_next_zero_bit((addr), (size), (b) + 1))
|
||||
|
||||
/**
|
||||
* for_each_set_bitrange_from - iterate over all set bit ranges [b; e)
|
||||
* @b: bit offset of start of current bitrange (first set bit); must be initialized
|
||||
* @e: bit offset of end of current bitrange (first unset bit)
|
||||
* @addr: bitmap address to base the search on
|
||||
* @size: bitmap size in number of bits
|
||||
*/
|
||||
#define for_each_set_bitrange_from(b, e, addr, size) \
|
||||
for ((b) = find_next_bit((addr), (size), (b)), \
|
||||
(e) = find_next_zero_bit((addr), (size), (b) + 1); \
|
||||
(b) < (size); \
|
||||
(b) = find_next_bit((addr), (size), (e) + 1), \
|
||||
(e) = find_next_zero_bit((addr), (size), (b) + 1))
|
||||
|
||||
/**
|
||||
* for_each_clear_bitrange - iterate over all unset bit ranges [b; e)
|
||||
* @b: bit offset of start of current bitrange (first unset bit)
|
||||
* @e: bit offset of end of current bitrange (first set bit)
|
||||
* @addr: bitmap address to base the search on
|
||||
* @size: bitmap size in number of bits
|
||||
*/
|
||||
#define for_each_clear_bitrange(b, e, addr, size) \
|
||||
for ((b) = find_next_zero_bit((addr), (size), 0), \
|
||||
(e) = find_next_bit((addr), (size), (b) + 1); \
|
||||
(b) < (size); \
|
||||
(b) = find_next_zero_bit((addr), (size), (e) + 1), \
|
||||
(e) = find_next_bit((addr), (size), (b) + 1))
|
||||
|
||||
/**
|
||||
* for_each_clear_bitrange_from - iterate over all unset bit ranges [b; e)
|
||||
* @b: bit offset of start of current bitrange (first set bit); must be initialized
|
||||
* @e: bit offset of end of current bitrange (first unset bit)
|
||||
* @addr: bitmap address to base the search on
|
||||
* @size: bitmap size in number of bits
|
||||
*/
|
||||
#define for_each_clear_bitrange_from(b, e, addr, size) \
|
||||
for ((b) = find_next_zero_bit((addr), (size), (b)), \
|
||||
(e) = find_next_bit((addr), (size), (b) + 1); \
|
||||
(b) < (size); \
|
||||
(b) = find_next_zero_bit((addr), (size), (e) + 1), \
|
||||
(e) = find_next_bit((addr), (size), (b) + 1))
|
||||
|
||||
/**
|
||||
* for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits
|
||||
* @start: bit offset to start search and to store the current iteration offset
|
||||
* @clump: location to store copy of current 8-bit clump
|
||||
* @bits: bitmap address to base the search on
|
||||
* @size: bitmap size in number of bits
|
||||
*/
|
||||
#define for_each_set_clump8(start, clump, bits, size) \
|
||||
for ((start) = find_first_clump8(&(clump), (bits), (size)); \
|
||||
(start) < (size); \
|
||||
(start) = find_next_clump8(&(clump), (bits), (size), (start) + 8))
|
||||
|
||||
#endif /*__LINUX_FIND_H_ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue