1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:12:57 +01:00

Merge pull request #18879 from benpicco/bf_popcnt

sys/bitfield: add bf_popcnt()
This commit is contained in:
Marian Buschsieweke 2022-11-11 11:35:14 +01:00 committed by GitHub
commit bec46c55bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 0 deletions

View File

@ -21,6 +21,7 @@
#include <stdint.h>
#include <string.h>
#include "bitfield.h"
#include "bitarithm.h"
#include "irq.h"
static inline unsigned _skip_bytes(const uint8_t field[], unsigned nbytes, uint8_t byte)
@ -92,3 +93,21 @@ void bf_set_all(uint8_t field[], size_t size)
field[bytes] = ~((1U << (8 - bits)) - 1);
}
}
unsigned bf_popcnt(const uint8_t field[], size_t size)
{
unsigned bytes = size >> 3;
unsigned bits = size & 0x7;
unsigned mask = ~((1U << (8 - bits)) - 1);
unsigned count = 0;
for (unsigned i = 0; i < bytes; ++i) {
count += bitarithm_bits_set(field[i]);
}
if (bits) {
count += bitarithm_bits_set(field[bytes] & mask);
}
return count;
}

View File

@ -219,6 +219,16 @@ int bf_find_first_unset(const uint8_t field[], size_t size);
*/
void bf_set_all(uint8_t field[], size_t size);
/**
* @brief Count set bits in the bitfield
*
* @param[in] field The bitfield
* @param[in] size The size of the bitfield
*
* @return number of '1' bits in the bitfield
*/
unsigned bf_popcnt(const uint8_t field[], size_t size);
#ifdef __cplusplus
}
#endif

View File

@ -299,6 +299,27 @@ static void test_bf_set_all(void)
TEST_ASSERT_EQUAL_INT(0, field[4]);
}
static void test_bf_popcnt(void)
{
uint8_t field[5];
memset(field, 0xff, sizeof(field));
bf_set_all(field, 5);
TEST_ASSERT_EQUAL_INT(5, bf_popcnt(field, 5));
field[0] = 0x1;
field[1] = 0x80;
TEST_ASSERT_EQUAL_INT(2, bf_popcnt(field, 9));
field[0] = 0x0;
field[1] = 0x0;
TEST_ASSERT_EQUAL_INT(0, bf_popcnt(field, 16));
field[0] = 0xff;
field[1] = 0xff;
TEST_ASSERT_EQUAL_INT(16, bf_popcnt(field, 16));
}
Test *tests_bitfield_tests(void) {
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_bf_set),
@ -313,6 +334,7 @@ Test *tests_bitfield_tests(void) {
new_TestFixture(test_bf_find_first_set),
new_TestFixture(test_bf_find_first_unset),
new_TestFixture(test_bf_set_all),
new_TestFixture(test_bf_popcnt),
};
EMB_UNIT_TESTCALLER(bitfield_tests, NULL, NULL, fixtures);