lib: bitarray: add method to xor two bitarrays

This is part one of several changes to add more methods to the bitarray api
so that it can be used for broader usecases, specifically LoRaWAN forward
error correction.

Signed-off-by: Lucas Romero <luqasn@gmail.com>
This commit is contained in:
Lucas Romero 2024-05-16 13:43:07 +02:00 committed by Anas Nashif
commit 752d3c529e
3 changed files with 216 additions and 0 deletions

View file

@ -617,6 +617,149 @@ ZTEST(bitarray, test_bitarray_popcount_region)
ret);
}
ZTEST(bitarray, test_bitarray_xor)
{
int ret;
/* Bitarrays have embedded spinlocks and can't on the stack. */
if (IS_ENABLED(CONFIG_KERNEL_COHERENCE)) {
ztest_test_skip();
}
SYS_BITARRAY_DEFINE(ba, 128);
SYS_BITARRAY_DEFINE(bb, 128);
SYS_BITARRAY_DEFINE(bc, 129);
printk("Testing bit array region xor spanning single bundle\n");
/* Pre-populate the bits */
ba.bundles[0] = 0x80001001;
ba.bundles[1] = 0x10000008;
ba.bundles[2] = 0xFFFFFFFF;
ba.bundles[3] = 0x00000000;
bb.bundles[0] = 0x80010001;
bb.bundles[1] = 0x10000008;
bb.bundles[2] = 0xFFFFFFFF;
bb.bundles[3] = 0x00000000;
ret = sys_bitarray_xor(&ba, &bb, 32, 0);
zassert_equal(ret, 0, "sys_bitarray_xor() returned unexpected value: %d", ret);
zassert_equal(ba.bundles[0], 0x00011000, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[0]);
zassert_equal(bb.bundles[0], 0x80010001, "sys_bitarray_xor() result unexpected: %x",
bb.bundles[0]);
zassert_equal(ba.bundles[1], 0x10000008, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[1]);
zassert_equal(bb.bundles[1], 0x10000008, "sys_bitarray_xor() result unexpected: %x",
bb.bundles[1]);
zassert_equal(ba.bundles[2], 0xFFFFFFFF, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[2]);
zassert_equal(bb.bundles[2], 0xFFFFFFFF, "sys_bitarray_xor() result unexpected: %x",
bb.bundles[2]);
zassert_equal(ba.bundles[3], 0x00000000, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[3]);
zassert_equal(bb.bundles[3], 0x00000000, "sys_bitarray_xor() result unexpected: %x",
bb.bundles[3]);
/* Pre-populate the bits */
ba.bundles[0] = 0x80001001;
ba.bundles[1] = 0x10000008;
ba.bundles[2] = 0xFFFFFFFF;
ba.bundles[3] = 0x00000000;
bb.bundles[0] = 0x80010001;
bb.bundles[1] = 0x10000008;
bb.bundles[2] = 0xFFFFFFFF;
bb.bundles[3] = 0x00000000;
ret = sys_bitarray_xor(&ba, &bb, 16, 0);
zassert_equal(ret, 0, "sys_bitarray_xor() returned unexpected value: %d", ret);
zassert_equal(ba.bundles[0], 0x80001000, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[0]);
zassert_equal(bb.bundles[0], 0x80010001, "sys_bitarray_xor() result unexpected: %x",
bb.bundles[0]);
/* Pre-populate the bits */
ba.bundles[0] = 0x80001001;
ba.bundles[1] = 0x10000008;
ba.bundles[2] = 0xFFFFFFFF;
ba.bundles[3] = 0x00000000;
bb.bundles[0] = 0x80010001;
bb.bundles[1] = 0x10000008;
bb.bundles[2] = 0xFFFFFFFF;
bb.bundles[3] = 0x00000000;
ret = sys_bitarray_xor(&ba, &bb, 16, 16);
zassert_equal(ret, 0, "sys_bitarray_xor() returned unexpected value: %d", ret);
zassert_equal(ba.bundles[0], 0x00011001, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[0]);
zassert_equal(bb.bundles[0], 0x80010001, "sys_bitarray_xor() result unexpected: %x",
bb.bundles[0]);
printk("Testing bit array region xor spanning multiple bundles\n");
/* Pre-populate the bits */
ba.bundles[0] = 0x00000000;
ba.bundles[1] = 0xFFFFFFFF;
ba.bundles[2] = 0xFFFFFFFF;
ba.bundles[3] = 0xFFFFFFFF;
bb.bundles[0] = 0x00000000;
bb.bundles[1] = 0xFFFFFFFF;
bb.bundles[2] = 0xFFFFFFFF;
bb.bundles[3] = 0xFFFFFFFF;
ret = sys_bitarray_xor(&ba, &bb, 32*3 - 2, 32 + 1);
zassert_equal(ret, 0, "sys_bitarray_xor() returned unexpected value: %d", ret);
zassert_equal(ba.bundles[0], 0x00000000, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[0]);
zassert_equal(ba.bundles[1], 0x00000001, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[1]);
zassert_equal(ba.bundles[2], 0x00000000, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[2]);
zassert_equal(ba.bundles[3], 0x80000000, "sys_bitarray_xor() result unexpected: %x",
ba.bundles[3]);
printk("Testing error cases\n");
/* Pre-populate the bits */
ba.bundles[0] = 0x00000000;
ba.bundles[1] = 0x00000000;
ba.bundles[2] = 0x00000000;
ba.bundles[3] = 0x00000000;
bb.bundles[0] = 0x00000000;
bb.bundles[1] = 0x00000000;
bb.bundles[2] = 0x00000000;
bb.bundles[3] = 0x00000000;
bc.bundles[0] = 0x00000000;
bc.bundles[1] = 0x00000000;
bc.bundles[2] = 0x00000000;
bc.bundles[3] = 0x00000000;
bc.bundles[4] = 0x00000000;
ret = sys_bitarray_xor(&ba, &bb, 32, 0);
zassert_equal(ret, 0, "sys_bitarray_xor() returned unexpected value: %d", ret);
ret = sys_bitarray_xor(&ba, &bc, 32, 0);
zassert_equal(ret, -EINVAL, "sys_bitarray_xor() returned unexpected value: %d", ret);
ret = sys_bitarray_xor(&bc, &ba, 32, 0);
zassert_equal(ret, -EINVAL, "sys_bitarray_xor() returned unexpected value: %d", ret);
ret = sys_bitarray_xor(&ba, &bb, 128, 0);
zassert_equal(ret, 0, "sys_bitarray_xor() returned unexpected value: %d", ret);
ret = sys_bitarray_xor(&ba, &bb, 128, 1);
zassert_equal(ret, -EINVAL, "sys_bitarray_xor() returned unexpected value: %d", ret);
ret = sys_bitarray_xor(&ba, &bb, 129, 0);
zassert_equal(ret, -EINVAL, "sys_bitarray_xor() returned unexpected value: %d", ret);
ret = sys_bitarray_xor(&ba, &bb, 0, 0);
zassert_equal(ret, -EINVAL, "sys_bitarray_xor() returned unexpected value: %d", ret);
}
ZTEST(bitarray, test_bitarray_region_set_clear)
{
int ret;