Skip to content

Commit 53c2d58

Browse files
nordic-krchkartben
authored andcommitted
lib: utils: Add function for finding group of cleared bits in a bit mask
Add function which finds contiguous number of bits which are not set in the 32 bit mask. Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 993b642 commit 53c2d58

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

include/zephyr/sys/util.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,22 @@ extern "C" {
434434
*/
435435
#define IN_RANGE(val, min, max) ((val) >= (min) && (val) <= (max))
436436

437+
/**
438+
* Find number of contiguous bits which are not set in the bit mask (32 bits).
439+
*
440+
* It is possible to return immediately when requested number of bits is found or
441+
* iterate over whole mask and return the best fit (smallest from available options).
442+
*
443+
* @param[in] mask 32 bit mask.
444+
* @param[in] num_bits Number of bits to find.
445+
* @param[in] total_bits Total number of LSB bits that can be used in the mask.
446+
* @param[in] first_match If true returns when first match is found, else returns the best fit.
447+
*
448+
* @retval -1 Contiguous bits not found.
449+
* @retval non-negative Starting index of the bits group.
450+
*/
451+
int bitmask_find_gap(uint32_t mask, size_t num_bits, size_t total_bits, bool first_match);
452+
437453
/**
438454
* @brief Is @p x a power of two?
439455
* @param x value to check

lib/utils/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ zephyr_sources(
88
rb.c
99
timeutil.c
1010
bitarray.c
11+
bitmask.c
1112
)
1213

1314
zephyr_sources_ifdef(CONFIG_ONOFF onoff.c)

lib/utils/bitmask.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include <zephyr/sys/util.h>
7+
#include <zephyr/sys/math_extras.h>
8+
9+
int bitmask_find_gap(uint32_t mask, size_t num_bits, size_t total_bits, bool first_match)
10+
{
11+
uint32_t max = UINT32_MAX;
12+
int max_loc = -1;
13+
14+
if (total_bits < 32) {
15+
mask |= ~BIT_MASK(total_bits);
16+
}
17+
18+
mask = ~mask;
19+
while (mask != 0U) {
20+
uint32_t block_size;
21+
uint32_t loc;
22+
int nidx;
23+
uint32_t idx = 31 - u32_count_leading_zeros(mask);
24+
uint32_t rmask = ~BIT_MASK(idx);
25+
26+
rmask |= mask;
27+
rmask = ~rmask;
28+
if (rmask != 0U) {
29+
nidx = 31 - u32_count_leading_zeros(rmask);
30+
block_size = idx - nidx;
31+
loc = nidx + 1;
32+
mask &= BIT_MASK(nidx);
33+
} else {
34+
mask = 0;
35+
block_size = idx + 1;
36+
loc = 0;
37+
}
38+
39+
if ((block_size == num_bits) || (first_match && block_size > num_bits)) {
40+
max_loc = loc;
41+
max = block_size;
42+
break;
43+
} else if (block_size >= num_bits && block_size < max) {
44+
max_loc = loc;
45+
max = block_size;
46+
}
47+
}
48+
49+
return max_loc;
50+
}

0 commit comments

Comments
 (0)