summaryrefslogtreecommitdiff
path: root/include/linux/find.h
diff options
context:
space:
mode:
authorYury Norov <yury.norov@gmail.com>2022-09-19 14:05:57 -0700
committerYury Norov <yury.norov@gmail.com>2022-10-01 10:22:57 -0700
commit4fe49b3b97c2640147c46519c2a6fdb06df34f5f (patch)
treebea4a14dd06b042f19b11db141519aae7c01814f /include/linux/find.h
parent6cc18331a987c4a29d66b9c4fd292587fba4d7bd (diff)
lib/bitmap: introduce for_each_set_bit_wrap() macro
Add for_each_set_bit_wrap() macro and use it in for_each_cpu_wrap(). The new macro is based on __for_each_wrap() iterator, which is simpler and smaller than cpumask_next_wrap(). Signed-off-by: Yury Norov <yury.norov@gmail.com>
Diffstat (limited to 'include/linux/find.h')
-rw-r--r--include/linux/find.h39
1 files changed, 39 insertions, 0 deletions
diff --git a/include/linux/find.h b/include/linux/find.h
index 77c087b7a451..3b746a183216 100644
--- a/include/linux/find.h
+++ b/include/linux/find.h
@@ -336,6 +336,32 @@ unsigned long find_next_bit_wrap(const unsigned long *addr,
return bit < offset ? bit : size;
}
+/*
+ * Helper for for_each_set_bit_wrap(). Make sure you're doing right thing
+ * before using it alone.
+ */
+static inline
+unsigned long __for_each_wrap(const unsigned long *bitmap, unsigned long size,
+ unsigned long start, unsigned long n)
+{
+ unsigned long bit;
+
+ /* If not wrapped around */
+ if (n > start) {
+ /* and have a bit, just return it. */
+ bit = find_next_bit(bitmap, size, n);
+ if (bit < size)
+ return bit;
+
+ /* Otherwise, wrap around and ... */
+ n = 0;
+ }
+
+ /* Search the other part. */
+ bit = find_next_bit(bitmap, start, n);
+ return bit < start ? bit : size;
+}
+
/**
* find_next_clump8 - find next 8-bit clump with set bits in a memory region
* @clump: location to store copy of found clump
@@ -515,6 +541,19 @@ unsigned long find_next_bit_le(const void *addr, unsigned
(e) = find_next_bit((addr), (size), (b) + 1))
/**
+ * for_each_set_bit_wrap - iterate over all set bits starting from @start, and
+ * wrapping around the end of bitmap.
+ * @bit: offset for current iteration
+ * @addr: bitmap address to base the search on
+ * @size: bitmap size in number of bits
+ * @start: Starting bit for bitmap traversing, wrapping around the bitmap end
+ */
+#define for_each_set_bit_wrap(bit, addr, size, start) \
+ for ((bit) = find_next_bit_wrap((addr), (size), (start)); \
+ (bit) < (size); \
+ (bit) = __for_each_wrap((addr), (size), (start), (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