Skip to content

Commit a6c04cf

Browse files
nordic-krchkartben
authored andcommitted
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 <[email protected]>
1 parent 187204a commit a6c04cf

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

lib/utils/bitarray.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,20 @@ int sys_bitarray_alloc(sys_bitarray_t *bitarray, size_t num_bits,
513513
goto out;
514514
}
515515

516+
if (bitarray->num_bits <= 32) {
517+
int off;
518+
519+
off = bitmask_find_gap(bitarray->bundles[0], num_bits, bitarray->num_bits, false);
520+
if (off < 0) {
521+
ret = -ENOSPC;
522+
} else {
523+
bitarray->bundles[0] |= BIT_MASK(num_bits) << off;
524+
*offset = off;
525+
ret = 0;
526+
}
527+
goto out;
528+
}
529+
516530
bit_idx = 0;
517531

518532
/* 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,
660674
* (offset to offset + num_bits) are all allocated before we clear
661675
* them.
662676
*/
663-
if (match_region(bitarray, offset, num_bits, true, &bd, NULL)) {
677+
if (bitarray->num_bits <= 32) {
678+
uint32_t mask = BIT_MASK(num_bits) << offset;
679+
680+
if ((mask & bitarray->bundles[0]) != mask) {
681+
ret = -EFAULT;
682+
} else {
683+
bitarray->bundles[0] &= ~mask;
684+
ret = 0;
685+
}
686+
} else if (match_region(bitarray, offset, num_bits, true, &bd, NULL)) {
664687
set_region(bitarray, offset, num_bits, false, &bd);
665688
ret = 0;
666689
} else {

0 commit comments

Comments
 (0)