These have come from the deviced.
Change-Id: I8d5eb95703d32d8fd17054c4446378adb4db97b2
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
--- /dev/null
+/* MIT License
+ *
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "bitmap.h"
+#include "shared/log.h"
+
+/**
+ * Align bits by size of long, and convert it to long,
+ * for example, if long is 64bit then,
+ * ROUNDUP_BITS_TO_LONGS(0) -> 0
+ * ROUNDUP_BITS_TO_LONGS(1) -> 1
+ * ROUNDUP_BITS_TO_LONGS(64) -> 1
+ * ROUNDUP_BITS_TO_LONGS(65) -> 2
+ * ROUNDUP_BITS_TO_LONGS(128) -> 2
+ * ROUNDUP_BITS_TO_LONGS(129) -> 3
+ * ...
+ */
+#define BYTES_PER_LONG (sizeof(unsigned long))
+#define BITS_PER_LONG (BYTES_PER_LONG * 8)
+#define ROUNDUP(n, d) ((((n) + (d) - 1) / (d)) * (d))
+#define ROUNDUP_BITS_TO_LONGS(nbits) (ROUNDUP(nbits, BITS_PER_LONG) / BITS_PER_LONG)
+
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BITMAP_MARGIN (BYTES_PER_LONG * 2) /* trailing margin for safety, bytes */
+
+struct syscommon_bitmap {
+ /* bitmap */
+ unsigned long *b;
+
+ /* number of bits, not the maximum bit.
+ * maximum bit is size - 1 */
+ unsigned long size;
+};
+
+static void bitmap_alloc_size(struct syscommon_bitmap *bm, unsigned int nbits)
+{
+ unsigned int bytes = ROUNDUP_BITS_TO_LONGS(nbits) * BYTES_PER_LONG;
+
+ bytes += BITMAP_MARGIN;
+
+ bm->b = (unsigned long *) malloc(bytes);
+ if (!bm->b)
+ return;
+
+ bm->size = nbits;
+}
+
+void syscommon_bitmap_set_all_bits(struct syscommon_bitmap *bm)
+{
+ unsigned long complete_longs;
+ unsigned long complete_bytes;
+ unsigned long residue_bits;
+
+ if (!bm)
+ return;
+
+ complete_longs = bm->size / BITS_PER_LONG;
+ complete_bytes = complete_longs * BYTES_PER_LONG;
+ residue_bits = bm->size % BITS_PER_LONG;
+
+ /* set all bits of the long element except the last long element */
+ memset(bm->b, ~0, complete_bytes);
+
+ /* set residue bits in the last long element */
+ if (residue_bits)
+ bm->b[complete_longs] = (1UL << residue_bits) - 1;
+}
+
+void syscommon_bitmap_clear_all_bits(struct syscommon_bitmap *bm)
+{
+ unsigned int bytes;
+
+ if (!bm)
+ return;
+
+ bytes = ROUNDUP_BITS_TO_LONGS(bm->size) * BYTES_PER_LONG;
+
+ memset(bm->b, 0, bytes);
+}
+
+void syscommon_bitmap_set_bit(struct syscommon_bitmap *bm, unsigned long nr)
+{
+ if (!bm)
+ return;
+
+ if (nr >= bm->size) {
+ _E("Requested nr=%lu exceeds max bit=%lu", nr, bm->size - 1);
+ return;
+ }
+
+ bm->b[BIT_WORD(nr)] |= BIT_MASK(nr);
+}
+
+void syscommon_bitmap_clear_bit(struct syscommon_bitmap *bm, unsigned long nr)
+{
+ if (!bm)
+ return;
+
+ if (nr >= bm->size) {
+ _E("Requested nr=%lu exceeds max bit=%lu", nr, bm->size - 1);
+ return;
+ }
+
+ bm->b[BIT_WORD(nr)] &= ~BIT_MASK(nr);
+}
+
+bool syscommon_bitmap_test_bit(struct syscommon_bitmap *bm, unsigned long nr)
+{
+ if (!bm)
+ return false;
+
+ if (nr >= bm->size) {
+ _E("Requested nr=%lu exceeds max bit=%lu", nr, bm->size - 1);
+ return false;
+ }
+
+ return bm->b[BIT_WORD(nr)] & BIT_MASK(nr);
+}
+
+int syscommon_bitmap_count_set_bit(struct syscommon_bitmap *bm)
+{
+ int i;
+ int count = 0;
+
+ if (!bm)
+ return -1;
+
+ for (i = 0; i < ROUNDUP_BITS_TO_LONGS(bm->size); ++i)
+ count += __builtin_popcountl(bm->b[i]);
+
+ return count;
+}
+
+int syscommon_bitmap_count_unset_bit(struct syscommon_bitmap *bm)
+{
+ if (!bm)
+ return -1;
+
+ return bm->size - syscommon_bitmap_count_set_bit(bm);
+}
+
+struct syscommon_bitmap* syscommon_bitmap_init_bitmap(unsigned int nbits)
+{
+ struct syscommon_bitmap *bm = NULL;
+
+ if (nbits == 0)
+ return NULL;
+
+ bm = (struct syscommon_bitmap *) malloc(sizeof(struct syscommon_bitmap));
+ if (!bm)
+ return NULL;
+
+ bm->b = NULL;
+ bm->size = 0;
+
+ bitmap_alloc_size(bm, nbits);
+ if (!bm->b) {
+ free(bm);
+ return NULL;
+ }
+
+ syscommon_bitmap_clear_all_bits(bm);
+ bm->size = nbits;
+
+ return bm;
+}
+
+void syscommon_bitmap_deinit_bitmap(struct syscommon_bitmap *bm)
+{
+ if (!bm)
+ return;
+
+ free(bm->b);
+ free(bm);
+}
--- /dev/null
+/* MIT License
+ *
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. */
+
+#ifndef __SYSCOMMON_BITMAP_H__
+#define __SYSCOMMON_BITMAP_H__
+
+#include <stdbool.h>
+
+struct syscommon_bitmap;
+
+void syscommon_bitmap_set_bit(struct syscommon_bitmap *b, unsigned long nr);
+void syscommon_bitmap_clear_bit(struct syscommon_bitmap *b, unsigned long nr);
+bool syscommon_bitmap_test_bit(struct syscommon_bitmap *b, unsigned long nr);
+void syscommon_bitmap_set_all_bits(struct syscommon_bitmap *b);
+void syscommon_bitmap_clear_all_bits(struct syscommon_bitmap *b);
+int syscommon_bitmap_count_set_bit(struct syscommon_bitmap *b);
+int syscommon_bitmap_count_unset_bit(struct syscommon_bitmap *b);
+struct syscommon_bitmap* syscommon_bitmap_init_bitmap(unsigned int nbits);
+void syscommon_bitmap_deinit_bitmap(struct syscommon_bitmap *b);
+
+#endif
#include "libcommon/file.h"
#include "libcommon/list.h"
#include "libcommon/ini-parser.h"
+#include "libcommon/bitmap.h"
#include "../test-main.h"
#include "../test-mock.h"
assert_false(garbage);
}
+static void test_init_bitmap_p(void **state)
+{
+ struct syscommon_bitmap *bm;
+
+ bm = syscommon_bitmap_init_bitmap(10);
+ assert_non_null(bm);
+
+ syscommon_bitmap_deinit_bitmap(bm);
+}
+
+static void test_init_bitmap_n(void **state)
+{
+ struct syscommon_bitmap *bm = NULL;
+
+ bm = syscommon_bitmap_init_bitmap(0);
+ assert_null(bm);
+}
+
+static void test_test_bit(void **state)
+{
+ struct syscommon_bitmap *bm;
+ const int bmsize = 37;
+ bool bit;
+ int i, nbit;
+
+ bm = syscommon_bitmap_init_bitmap(bmsize);
+ assert_non_null(bm);
+
+ for (i = 0; i < bmsize; ++i) {
+ bit = syscommon_bitmap_test_bit(bm, i);
+ assert_false(bit);
+ }
+
+ /* count bit by setting one by one */
+ for (i = 0; i < bmsize; ++i) {
+ syscommon_bitmap_set_bit(bm, i);
+ nbit = syscommon_bitmap_count_set_bit(bm);
+ assert_int_equal(nbit, i + 1);
+ }
+
+ /* test the marginal bit */
+ bit = syscommon_bitmap_test_bit(bm, 0);
+ assert_true(bit);
+ bit = syscommon_bitmap_test_bit(bm, bmsize - 1);
+ assert_true(bit);
+ bit = syscommon_bitmap_test_bit(bm, bmsize);
+ assert_false(bit);
+
+
+ /* count bit by clearing one by one */
+ for (i = 0; i < bmsize; ++i) {
+ syscommon_bitmap_clear_bit(bm, i);
+ nbit = syscommon_bitmap_count_set_bit(bm);
+ assert_int_equal(nbit, bmsize - i - 1);
+ }
+
+ syscommon_bitmap_deinit_bitmap(bm);
+}
+
+static void test_all_bit(void **state)
+{
+ struct syscommon_bitmap *bm;
+ const int bmsize = 37;
+ int nbit;
+
+ bm = syscommon_bitmap_init_bitmap(bmsize);
+ assert_non_null(bm);
+
+ syscommon_bitmap_set_all_bits(bm);
+ nbit = syscommon_bitmap_count_set_bit(bm);
+ assert_int_equal(nbit, bmsize);
+
+ syscommon_bitmap_clear_all_bits(bm);
+ nbit = syscommon_bitmap_count_set_bit(bm);
+ assert_int_equal(nbit, 0);
+
+ syscommon_bitmap_deinit_bitmap(bm);
+}
+
int run_test_suite(void)
{
const struct CMUnitTest testsuite[] = {
cmocka_unit_test(test_list_append_p),
cmocka_unit_test(test_list_prepend_p),
cmocka_unit_test(test_config_parse_p),
+ cmocka_unit_test(test_init_bitmap_p),
+ cmocka_unit_test(test_init_bitmap_n),
+ cmocka_unit_test(test_test_bit),
+ cmocka_unit_test(test_all_bit),
};
return cmocka_run_group_tests(testsuite, NULL, NULL);