lib: utils: bitarray: Use optimized version for 32 bit array

When bitarray is limited to a single 32 bit word then bitmask_find_gap
can be used which is much faster than bit by bit search which is
used in bitarray spanning across multiple 32 bit words. Tests shows
that allocation and freeing is 2-3 times faster.

Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruściński
2025-09-04 10:56:58 +02:00
committed by Benjamin Cabé
parent 187204a754
commit a6c04cf7d8

View File

@@ -513,6 +513,20 @@ int sys_bitarray_alloc(sys_bitarray_t *bitarray, size_t num_bits,
goto out;
}
if (bitarray->num_bits <= 32) {
int off;
off = bitmask_find_gap(bitarray->bundles[0], num_bits, bitarray->num_bits, false);
if (off < 0) {
ret = -ENOSPC;
} else {
bitarray->bundles[0] |= BIT_MASK(num_bits) << off;
*offset = off;
ret = 0;
}
goto out;
}
bit_idx = 0;
/* Find the first non-allocated bit by looking at bundles
@@ -660,7 +674,16 @@ int sys_bitarray_free(sys_bitarray_t *bitarray, size_t num_bits,
* (offset to offset + num_bits) are all allocated before we clear
* them.
*/
if (match_region(bitarray, offset, num_bits, true, &bd, NULL)) {
if (bitarray->num_bits <= 32) {
uint32_t mask = BIT_MASK(num_bits) << offset;
if ((mask & bitarray->bundles[0]) != mask) {
ret = -EFAULT;
} else {
bitarray->bundles[0] &= ~mask;
ret = 0;
}
} else if (match_region(bitarray, offset, num_bits, true, &bd, NULL)) {
set_region(bitarray, offset, num_bits, false, &bd);
ret = 0;
} else {