Add function which finds contiguous number of bits which are not set in the 32 bit mask. Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
51 lines
1.0 KiB
C
51 lines
1.0 KiB
C
/*
|
|
* Copyright (c) 2025 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include <zephyr/sys/util.h>
|
|
#include <zephyr/sys/math_extras.h>
|
|
|
|
int bitmask_find_gap(uint32_t mask, size_t num_bits, size_t total_bits, bool first_match)
|
|
{
|
|
uint32_t max = UINT32_MAX;
|
|
int max_loc = -1;
|
|
|
|
if (total_bits < 32) {
|
|
mask |= ~BIT_MASK(total_bits);
|
|
}
|
|
|
|
mask = ~mask;
|
|
while (mask != 0U) {
|
|
uint32_t block_size;
|
|
uint32_t loc;
|
|
int nidx;
|
|
uint32_t idx = 31 - u32_count_leading_zeros(mask);
|
|
uint32_t rmask = ~BIT_MASK(idx);
|
|
|
|
rmask |= mask;
|
|
rmask = ~rmask;
|
|
if (rmask != 0U) {
|
|
nidx = 31 - u32_count_leading_zeros(rmask);
|
|
block_size = idx - nidx;
|
|
loc = nidx + 1;
|
|
mask &= BIT_MASK(nidx);
|
|
} else {
|
|
mask = 0;
|
|
block_size = idx + 1;
|
|
loc = 0;
|
|
}
|
|
|
|
if ((block_size == num_bits) || (first_match && block_size > num_bits)) {
|
|
max_loc = loc;
|
|
max = block_size;
|
|
break;
|
|
} else if (block_size >= num_bits && block_size < max) {
|
|
max_loc = loc;
|
|
max = block_size;
|
|
}
|
|
}
|
|
|
|
return max_loc;
|
|
}
|