[PATCH v2 3/6] lib: test bitmap sets binary operation iterators

From: Mathieu Desnoyers
Date: Thu Aug 29 2024 - 10:00:28 EST


Test the following bitmap iterators applying binary operations on sets
of two bitmaps:

- for_each_and_bit,
- for_each_andnot_bit,
- for_each_nor_bit,
- for_each_or_bit.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxxxx>
Cc: Yury Norov <yury.norov@xxxxxxxxx>
Cc: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx>
---
lib/test_bitmap.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)

diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index 6dfb8d46a4ff..96ce3c78c7fa 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -184,6 +184,32 @@ __check_eq_str(const char *srcfile, unsigned int line,
result; \
})

+static bool __init
+__check_neq_range_ulong(const char *srcfile, unsigned int line,
+ const unsigned long exp_ulong_begin,
+ const unsigned long exp_ulong_end,
+ unsigned long x)
+{
+ if (exp_ulong_begin <= x && exp_ulong_end >= x) {
+ pr_err("[%s:%u] did not value %lu within range [%lu,%lu]\n",
+ srcfile, line, x, exp_ulong_begin, exp_ulong_end);
+ return false;
+ }
+ return true;
+}
+
+#define __expect_neq_range(suffix, ...) \
+ ({ \
+ int result = 0; \
+ total_tests++; \
+ if (!__check_neq_range_ ## suffix(__FILE__, __LINE__, \
+ ##__VA_ARGS__)) { \
+ failed_tests++; \
+ result = 1; \
+ } \
+ result; \
+ })
+
#define expect_eq_ulong(...) __expect_eq(ulong, ##__VA_ARGS__)
#define expect_eq_uint(x, y) expect_eq_ulong((unsigned int)(x), (unsigned int)(y))
#define expect_eq_bitmap(...) __expect_eq(bitmap, ##__VA_ARGS__)
@@ -192,6 +218,9 @@ __check_eq_str(const char *srcfile, unsigned int line,
#define expect_eq_clump8(...) __expect_eq(clump8, ##__VA_ARGS__)
#define expect_eq_str(...) __expect_eq(str, ##__VA_ARGS__)

+#define expect_neq_range_ulong(...) __expect_neq_range(ulong, ##__VA_ARGS__)
+#define expect_neq_range_uint(begin, end, y) expect_neq_range_ulong((unsigned int)(begin), (unsigned int) end, (unsigned int)(y))
+
static void __init test_zero_clear(void)
{
DECLARE_BITMAP(bmap, 1024);
@@ -849,6 +878,57 @@ static void __init test_for_each_set_bit(void)
expect_eq_bitmap(orig, copy, 500);
}

+static void __init test_for_each_binaryops_bit(void)
+{
+ DECLARE_BITMAP(orig1, 500);
+ DECLARE_BITMAP(orig2, 500);
+ unsigned int bit, count;
+
+ bitmap_zero(orig1, 500);
+ bitmap_zero(orig2, 500);
+
+ /* Set individual bits in orig1 and orig2 with stride 10 (expected in both orig1 & orig2) */
+ for (bit = 0; bit < 500; bit += 10) {
+ bitmap_set(orig1, bit, 1);
+ bitmap_set(orig2, bit, 1);
+ }
+ /* Set individual bits in orig1 with offset 1, stride 10 (expected in orig1 only) */
+ for (bit = 1; bit < 500; bit += 10)
+ bitmap_set(orig1, bit, 1);
+ /* Set individual bits in orig2 with offset 2, stride 10 (expected in orig2 only). */
+ for (bit = 2; bit < 500; bit += 10)
+ bitmap_set(orig2, bit, 1);
+
+ count = 0;
+ for_each_and_bit(bit, orig1, orig2, 500) { /* orig1 & orig2 */
+ expect_neq_range_uint(1, 9, bit % 10);
+ count++;
+ }
+ expect_eq_uint(50, count);
+
+ count = 0;
+ for_each_andnot_bit(bit, orig1, orig2, 500) { /* orig1 & ~orig2 */
+ expect_neq_range_uint(0, 0, bit % 10);
+ expect_neq_range_uint(2, 9, bit % 10);
+ count++;
+ }
+ expect_eq_uint(50, count);
+
+ count = 0;
+ for_each_nor_bit(bit, orig1, orig2, 500) { /* ~(orig1 | orig2) */
+ expect_neq_range_uint(0, 2, bit % 10);
+ count++;
+ }
+ expect_eq_uint(7 * 50, count);
+
+ count = 0;
+ for_each_or_bit(bit, orig1, orig2, 500) { /* orig1 | orig2 */
+ expect_neq_range_uint(3, 9, bit % 10);
+ count++;
+ }
+ expect_eq_uint(3 * 50, count);
+}
+
static void __init test_for_each_set_bit_from(void)
{
DECLARE_BITMAP(orig, 500);
@@ -1482,6 +1562,7 @@ static void __init selftest(void)
test_for_each_clear_bitrange_from();
test_for_each_set_clump8();
test_for_each_set_bit_wrap();
+ test_for_each_binaryops_bit();
}

KSTM_MODULE_LOADERS(test_bitmap);
--
2.39.2