LCOV - code coverage report
Current view: top level - app/test - test_bitset.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 240 248 96.8 %
Date: 2025-03-01 20:23:48 Functions: 40 40 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 222 288 77.1 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2023 Ericsson AB
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <inttypes.h>
       6                 :            : #include <stdlib.h>
       7                 :            : 
       8                 :            : #include <rte_bitset.h>
       9                 :            : #include <rte_random.h>
      10                 :            : 
      11                 :            : #include "test.h"
      12                 :            : 
      13                 :            : #define MAGIC UINT64_C(0xdeadbeefdeadbeef)
      14                 :            : 
      15                 :            : static void
      16                 :            : rand_buf(void *buf, size_t n)
      17                 :            : {
      18                 :            :         size_t i;
      19                 :            : 
      20   [ +  +  +  +  :   10875671 :         for (i = 0; i < n; i++)
          +  +  +  +  +  
                +  +  + ]
      21                 :   10705664 :                 ((unsigned char *)buf)[i] = rte_rand();
      22                 :            : }
      23                 :            : 
      24                 :            : static uint64_t *
      25                 :     130005 : alloc_bitset(size_t size)
      26                 :            : {
      27                 :            :         uint64_t *p;
      28                 :            : 
      29                 :     130005 :         p = malloc(RTE_BITSET_SIZE(size) + 2 * sizeof(uint64_t));
      30         [ -  + ]:     130005 :         if (p == NULL)
      31                 :          0 :                 rte_panic("Unable to allocate memory\n");
      32                 :            : 
      33                 :     130005 :         rand_buf(&p[0], RTE_BITSET_SIZE(size));
      34                 :            : 
      35                 :     130005 :         p[0] = MAGIC;
      36                 :     130005 :         p[RTE_BITSET_NUM_WORDS(size) + 1] = MAGIC;
      37                 :            : 
      38                 :     130005 :         return p + 1;
      39                 :            : }
      40                 :            : 
      41                 :            : 
      42                 :            : static int
      43                 :     130005 : free_bitset(uint64_t *bitset, size_t size)
      44                 :            : {
      45                 :            :         uint64_t *p;
      46                 :            : 
      47                 :     130005 :         p = bitset - 1;
      48                 :            : 
      49         [ +  - ]:     130005 :         if (p[0] != MAGIC)
      50                 :            :                 return TEST_FAILED;
      51                 :            : 
      52         [ +  - ]:     130005 :         if (p[RTE_BITSET_NUM_WORDS(size) + 1] != MAGIC)
      53                 :            :                 return TEST_FAILED;
      54                 :            : 
      55                 :     130005 :         free(p);
      56                 :            : 
      57                 :     130005 :         return TEST_SUCCESS;
      58                 :            : }
      59                 :            : 
      60                 :            : static bool
      61                 :            : rand_bool(void)
      62                 :            : {
      63                 :   30943642 :         return rte_rand_max(2);
      64                 :            : }
      65                 :            : 
      66                 :            : static void
      67                 :            : rand_bool_ary(bool *ary, size_t len)
      68                 :            : {
      69                 :            :         size_t i;
      70                 :            : 
      71   [ +  +  +  +  :   30251366 :         for (i = 0; i < len; i++)
             +  +  +  + ]
      72                 :   30191363 :                 ary[i] = rand_bool();
      73                 :            : }
      74                 :            : 
      75                 :            : static void
      76                 :      80005 : rand_unused_bits(uint64_t *bitset, size_t size)
      77                 :            : {
      78                 :      80005 :         uint64_t bits = rte_rand() & ~__RTE_BITSET_USED_MASK(size);
      79                 :            : 
      80                 :      80005 :         bitset[RTE_BITSET_NUM_WORDS(size) - 1] |= bits;
      81                 :      80005 : }
      82                 :            : 
      83                 :            : static void
      84                 :      30000 : rand_bitset(uint64_t *bitset, size_t size)
      85                 :            : {
      86                 :            :         size_t i;
      87                 :            : 
      88                 :            :         rte_bitset_init(bitset, size);
      89                 :            : 
      90         [ +  + ]:   15019590 :         for (i = 0; i < size; i++)
      91                 :            :                 rte_bitset_assign(bitset, i, rand_bool());
      92                 :            : 
      93                 :      30000 :         rand_unused_bits(bitset, size);
      94                 :      30000 : }
      95                 :            : 
      96                 :            : typedef bool test_fun(const uint64_t *bitset, size_t bit_num);
      97                 :            : typedef void set_fun(uint64_t *bitset, size_t bit_num);
      98                 :            : typedef void clear_fun(uint64_t *bitset, size_t bit_num);
      99                 :            : typedef void assign_fun(uint64_t *bitset, size_t bit_num, bool value);
     100                 :            : typedef void flip_fun(uint64_t *bitset, size_t bit_num);
     101                 :            : 
     102                 :            : #define RAND_SET_MAX_SIZE 1000
     103                 :            : 
     104                 :            : static int
     105                 :      20000 : test_set_clear_size(test_fun test_fun, set_fun set_fun, clear_fun clear_fun, size_t size)
     106                 :            : {
     107                 :            :         size_t i;
     108                 :            :         bool reference[RAND_SET_MAX_SIZE];
     109                 :            :         uint64_t *bitset;
     110                 :            : 
     111                 :            :         rand_bool_ary(reference, size);
     112                 :            : 
     113                 :      20000 :         bitset = alloc_bitset(size);
     114                 :            : 
     115         [ -  + ]:      20000 :         TEST_ASSERT(bitset != NULL, "Failed to allocate memory");
     116                 :            : 
     117                 :            :         rte_bitset_init(bitset, size);
     118                 :            : 
     119         [ +  + ]:   10059083 :         for (i = 0; i < size; i++) {
     120         [ +  + ]:   10039083 :                 if (reference[i])
     121                 :    5018804 :                         set_fun(bitset, i);
     122                 :            :                 else
     123                 :    5020279 :                         clear_fun(bitset, i);
     124                 :            :         }
     125                 :            : 
     126         [ +  + ]:   10059083 :         for (i = 0; i < size; i++)
     127         [ +  - ]:   10039083 :                 if (reference[i] != test_fun(bitset, i))
     128                 :            :                         return TEST_FAILED;
     129                 :            : 
     130         [ -  + ]:      20000 :         TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS,
     131                 :            :                 "Buffer over- or underrun detected");
     132                 :            : 
     133                 :            :         return TEST_SUCCESS;
     134                 :            : }
     135                 :            : 
     136                 :            : #define RAND_ITERATIONS 10000
     137                 :            : 
     138                 :            : static int
     139                 :          2 : test_set_clear_fun(test_fun test_fun, set_fun set_fun, clear_fun clear_fun)
     140                 :            : {
     141                 :            :         size_t i;
     142                 :            : 
     143         [ +  + ]:      20002 :         for (i = 0; i < RAND_ITERATIONS; i++) {
     144                 :      20000 :                 size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1);
     145                 :            : 
     146         [ +  - ]:      20000 :                 if (test_set_clear_size(test_fun, set_fun, clear_fun, size) != TEST_SUCCESS)
     147                 :            :                         return TEST_FAILED;
     148                 :            :         }
     149                 :            : 
     150                 :            :         return TEST_SUCCESS;
     151                 :            : }
     152                 :            : 
     153                 :            : static int
     154                 :          1 : test_set_clear(void)
     155                 :            : {
     156                 :          1 :         return test_set_clear_fun(rte_bitset_test, rte_bitset_set, rte_bitset_clear);
     157                 :            : }
     158                 :            : 
     159                 :            : static int
     160                 :      20000 : test_flip_size(test_fun test_fun, assign_fun assign_fun, flip_fun flip_fun, size_t size)
     161                 :            : {
     162                 :            :         size_t i;
     163                 :            :         uint64_t *bitset;
     164                 :            : 
     165                 :      20000 :         bitset = alloc_bitset(size);
     166                 :            : 
     167         [ -  + ]:      20000 :         TEST_ASSERT(bitset != NULL, "Failed to allocate memory");
     168                 :            : 
     169                 :      20000 :         rand_bitset(bitset, size);
     170                 :            : 
     171         [ +  + ]:    9970776 :         for (i = 0; i < size; i++) {
     172                 :    9950776 :                 uint64_t *reference = alloca(RTE_BITSET_SIZE(size));
     173                 :            : 
     174                 :    9950776 :                 rte_bitset_copy(reference, bitset, size);
     175                 :            : 
     176                 :    9950776 :                 bool value = test_fun(bitset, i);
     177                 :            : 
     178                 :    9950776 :                 flip_fun(bitset, i);
     179                 :            : 
     180         [ -  + ]:    9950776 :                 TEST_ASSERT(test_fun(bitset, i) != value, "Bit %zd was not flipped", i);
     181                 :            : 
     182                 :    9950776 :                 assign_fun(reference, i, !value);
     183                 :            : 
     184         [ -  + ]:    9950776 :                 TEST_ASSERT(rte_bitset_equal(bitset, reference, size),
     185                 :            :                         "Not only the target bit %zd was flipped", i);
     186                 :            : 
     187                 :            : 
     188                 :            :         }
     189                 :            : 
     190         [ -  + ]:      20000 :         TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS,
     191                 :            :                 "Buffer over- or underrun detected");
     192                 :            : 
     193                 :            :         return TEST_SUCCESS;
     194                 :            : }
     195                 :            : 
     196                 :            : static int
     197                 :          2 : test_flip_fun(test_fun test_fun, assign_fun assign_fun, flip_fun flip_fun)
     198                 :            : {
     199                 :            :         size_t i;
     200                 :            : 
     201         [ +  + ]:      20002 :         for (i = 0; i < RAND_ITERATIONS; i++) {
     202                 :      20000 :                 size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1);
     203                 :            : 
     204         [ +  - ]:      20000 :                 if (test_flip_size(test_fun, assign_fun, flip_fun, size) != TEST_SUCCESS)
     205                 :            :                         return TEST_FAILED;
     206                 :            :         }
     207                 :            : 
     208                 :            :         return TEST_SUCCESS;
     209                 :            : }
     210                 :            : 
     211                 :            : static int
     212                 :          1 : test_flip(void)
     213                 :            : {
     214                 :          1 :         return test_flip_fun(rte_bitset_test, rte_bitset_assign, rte_bitset_flip);
     215                 :            : }
     216                 :            : 
     217                 :            : static bool
     218                 :   14848528 : bitset_atomic_test(const uint64_t *bitset, size_t bit_num)
     219                 :            : {
     220                 :   14848528 :         return rte_bitset_atomic_test(bitset, bit_num, rte_memory_order_relaxed);
     221                 :            : }
     222                 :            : 
     223                 :            : static void
     224                 :    2490593 : bitset_atomic_set(uint64_t *bitset, size_t bit_num)
     225                 :            : {
     226                 :            :         rte_bitset_atomic_set(bitset, bit_num, rte_memory_order_relaxed);
     227                 :    2490593 : }
     228                 :            : 
     229                 :            : static void
     230                 :    2492075 : bitset_atomic_clear(uint64_t *bitset, size_t bit_num)
     231                 :            : {
     232                 :            :         rte_bitset_atomic_clear(bitset, bit_num, rte_memory_order_relaxed);
     233                 :    2492075 : }
     234                 :            : 
     235                 :            : static void
     236                 :    4932930 : bitset_atomic_flip(uint64_t *bitset, size_t bit_num)
     237                 :            : {
     238                 :            :         rte_bitset_atomic_flip(bitset, bit_num, rte_memory_order_relaxed);
     239                 :    4932930 : }
     240                 :            : 
     241                 :            : static void
     242                 :    4932930 : bitset_atomic_assign(uint64_t *bitset, size_t bit_num, bool bit_value)
     243                 :            : {
     244                 :    4932930 :         rte_bitset_atomic_assign(bitset, bit_num, bit_value, rte_memory_order_relaxed);
     245                 :    4932930 : }
     246                 :            : 
     247                 :            : static int
     248                 :          1 : test_atomic_set_clear(void)
     249                 :            : {
     250                 :          1 :         return test_set_clear_fun(bitset_atomic_test, bitset_atomic_set, bitset_atomic_clear);
     251                 :            : }
     252                 :            : 
     253                 :            : static int
     254                 :          1 : test_atomic_flip(void)
     255                 :            : {
     256                 :          1 :         return test_flip_fun(bitset_atomic_test, bitset_atomic_assign, bitset_atomic_flip);
     257                 :            : }
     258                 :            : 
     259                 :            : static ssize_t
     260                 :            : find(const bool *ary, size_t num_bools, size_t start, size_t len, bool set)
     261                 :            : {
     262                 :            :         size_t i;
     263                 :            : 
     264   [ +  +  +  + ]:    3982366 :         for (i = 0; i < len; i++) {
     265                 :    3958565 :                 ssize_t idx = (start + i) % num_bools;
     266                 :            : 
     267   [ +  +  +  + ]:    3958565 :                 if (ary[idx] == set)
     268                 :            :                         return idx;
     269                 :            :         }
     270                 :            : 
     271                 :            :         return -1;
     272                 :            : }
     273                 :            : 
     274                 :            : static ssize_t
     275                 :            : find_set(const bool *ary, size_t num_bools, size_t start, size_t len)
     276                 :            : {
     277                 :            :         return find(ary, num_bools, start, len, true);
     278                 :            : }
     279                 :            : 
     280                 :            : static ssize_t
     281                 :            : find_clear(const bool *ary, size_t num_bools, size_t start, size_t len)
     282                 :            : {
     283                 :            :         return find(ary, num_bools, start, len, false);
     284                 :            : }
     285                 :            : 
     286                 :            : #define FFS_ITERATIONS 100
     287                 :            : 
     288                 :            : static int
     289                 :      20000 : test_find_size(size_t size, bool set)
     290                 :            : {
     291                 :            :         uint64_t *bitset;
     292                 :            :         bool reference[RAND_SET_MAX_SIZE];
     293                 :            :         size_t i;
     294                 :            : 
     295                 :      20000 :         bitset = alloc_bitset(size);
     296                 :            : 
     297         [ -  + ]:      20000 :         TEST_ASSERT(bitset != NULL, "Failed to allocate memory");
     298                 :            : 
     299                 :            :         rte_bitset_init(bitset, size);
     300                 :            : 
     301         [ +  + ]:    9967066 :         for (i = 0; i < size; i++) {
     302                 :            :                 bool bit = rand_bool();
     303                 :    9947066 :                 reference[i] = bit;
     304                 :            : 
     305         [ +  + ]:    9947066 :                 if (bit)
     306                 :            :                         rte_bitset_set(bitset, i);
     307                 :            :                 else /* redundant, still useful for testing */
     308                 :            :                         rte_bitset_clear(bitset, i);
     309                 :            :         }
     310                 :            : 
     311         [ +  + ]:    2020000 :         for (i = 0; i < FFS_ITERATIONS; i++) {
     312                 :    2000000 :                 size_t start_bit = rte_rand_max(size);
     313                 :    2000000 :                 size_t len = rte_rand_max(size + 1);
     314                 :    2000000 :                 bool full_range = len == size && start_bit == 0;
     315                 :    2000000 :                 bool wraps = start_bit + len > size;
     316                 :            :                 ssize_t rc;
     317                 :            : 
     318         [ +  + ]:    2000000 :                 if (set) {
     319   [ +  +  +  + ]:    1000414 :                         if (full_range && rand_bool())
     320                 :        216 :                                 rc = rte_bitset_find_first_set(bitset, size);
     321   [ +  +  +  + ]:    1505432 :                         else if (wraps || rand_bool())
     322                 :     746946 :                                 rc = rte_bitset_find_set_wrap(bitset, size, start_bit, len);
     323                 :            :                         else
     324                 :            :                                 rc = rte_bitset_find_set(bitset, size, start_bit, len);
     325                 :            : 
     326         [ +  - ]:    1000000 :                         if (rc != find_set(reference, size, start_bit, len))
     327                 :            :                                 return TEST_FAILED;
     328                 :            :                 } else {
     329   [ +  +  +  + ]:    1000398 :                         if (full_range && rand_bool())
     330                 :        211 :                                 rc = rte_bitset_find_first_clear(bitset, size);
     331   [ +  +  +  + ]:    1505247 :                         else if (wraps || rand_bool())
     332                 :     747447 :                                 rc = rte_bitset_find_clear_wrap(bitset, size, start_bit, len);
     333                 :            :                         else
     334                 :            :                                 rc = rte_bitset_find_clear(bitset, size, start_bit, len);
     335                 :            : 
     336         [ +  - ]:    1000000 :                         if (rc != find_clear(reference, size, start_bit, len))
     337                 :            :                                 return TEST_FAILED;
     338                 :            :                 }
     339                 :            : 
     340                 :            :         }
     341                 :            : 
     342         [ -  + ]:      20000 :         TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS,
     343                 :            :                 "Buffer over- or underrun detected");
     344                 :            : 
     345                 :            :         return TEST_SUCCESS;
     346                 :            : }
     347                 :            : 
     348                 :            : static int
     349                 :            : test_find_set_size(size_t size)
     350                 :            : {
     351                 :      10000 :         return test_find_size(size, true);
     352                 :            : }
     353                 :            : 
     354                 :            : static int
     355                 :            : test_find_clear_size(size_t size)
     356                 :            : {
     357                 :      10000 :         return test_find_size(size, false);
     358                 :            : }
     359                 :            : 
     360                 :            : static int
     361                 :          1 : test_find(void)
     362                 :            : {
     363                 :            :         size_t i;
     364                 :            : 
     365         [ +  + ]:      10001 :         for (i = 0; i < RAND_ITERATIONS; i++) {
     366                 :      10000 :                 size_t size = 2 + rte_rand_max(RAND_SET_MAX_SIZE - 2);
     367                 :            : 
     368         [ +  - ]:      10000 :                 if (test_find_set_size(size) != TEST_SUCCESS)
     369                 :            :                         return TEST_FAILED;
     370                 :            : 
     371         [ +  - ]:      10000 :                 if (test_find_clear_size(size) != TEST_SUCCESS)
     372                 :            :                         return TEST_FAILED;
     373                 :            :         }
     374                 :            : 
     375                 :            :         return TEST_SUCCESS;
     376                 :            : }
     377                 :            : 
     378                 :            : static int
     379                 :            : record_match(ssize_t match_idx, size_t size, int *calls)
     380                 :            : {
     381   [ +  -  +  -  :    3772483 :         if (match_idx < 0 || (size_t)match_idx >= size)
          +  -  +  -  +  
                -  +  - ]
     382                 :            :                 return TEST_FAILED;
     383                 :            : 
     384                 :    3772483 :         calls[match_idx]++;
     385                 :            : 
     386                 :            :         return TEST_SUCCESS;
     387                 :            : }
     388                 :            : 
     389                 :            : static int
     390                 :      40000 : test_foreach_size(ssize_t size, bool may_wrap, bool set)
     391                 :            : {
     392                 :            :         bool reference[RAND_SET_MAX_SIZE];
     393                 :            :         int calls[RAND_SET_MAX_SIZE];
     394                 :            :         uint64_t *bitset;
     395                 :            :         ssize_t i;
     396                 :            :         ssize_t start_bit;
     397                 :            :         ssize_t len;
     398                 :            :         bool full_range;
     399                 :            :         size_t total_calls = 0;
     400                 :            : 
     401                 :      40000 :         rand_bool_ary(reference, size);
     402                 :            : 
     403                 :      40000 :         bitset = alloc_bitset(size);
     404                 :            : 
     405         [ -  + ]:      40000 :         TEST_ASSERT(bitset != NULL, "Failed to allocate memory");
     406                 :            : 
     407                 :            :         memset(calls, 0, sizeof(calls));
     408                 :            : 
     409                 :      40000 :         start_bit = rte_rand_max(size);
     410         [ +  + ]:      60000 :         len = may_wrap ? rte_rand_max(size + 1) :
     411                 :      20000 :                 rte_rand_max(size - start_bit + 1);
     412                 :            : 
     413                 :            :         rte_bitset_init(bitset, size);
     414                 :            : 
     415                 :            :         /* random data in the unused bits should not matter */
     416                 :      40000 :         rand_buf(bitset, RTE_BITSET_SIZE(size));
     417                 :            : 
     418         [ +  + ]:    7586471 :         for (i = start_bit; i < start_bit + len; i++) {
     419                 :    7546471 :                 size_t idx = i % size;
     420                 :            : 
     421         [ +  + ]:    7546471 :                 if (reference[idx])
     422                 :            :                         rte_bitset_set(bitset, idx);
     423                 :            :                 else
     424                 :            :                         rte_bitset_clear(bitset, idx);
     425                 :            : 
     426         [ +  - ]:    7546471 :                 if (rte_bitset_test(bitset, idx) != reference[idx])
     427                 :            :                         return TEST_FAILED;
     428                 :            :         }
     429                 :            : 
     430                 :      40000 :         full_range = (len == size && start_bit == 0);
     431                 :            : 
     432                 :            :         /* XXX: verify iteration order as well */
     433         [ +  + ]:      40000 :         if (set) {
     434   [ +  +  +  + ]:      20021 :                 if (full_range && rand_bool()) {
     435   [ +  +  +  + ]:         33 :                         RTE_BITSET_FOREACH_SET(i, bitset, size) {
     436                 :            :                                 if (record_match(i, size, calls) != TEST_SUCCESS)
     437                 :            :                                         return TEST_FAILED;
     438                 :            :                         }
     439         [ +  + ]:      19993 :                 } else if (may_wrap) {
     440   [ +  +  +  +  :    1257326 :                         RTE_BITSET_FOREACH_SET_WRAP(i, bitset, size, start_bit, len) {
                   +  + ]
     441                 :            :                                 if (record_match(i, size, calls) != TEST_SUCCESS) {
     442                 :            :                                         printf("failed\n");
     443                 :          0 :                                         return TEST_FAILED;
     444                 :            :                                 }
     445                 :            :                         }
     446                 :            :                 } else {
     447   [ +  -  +  +  :     635926 :                         RTE_BITSET_FOREACH_SET_RANGE(i, bitset, size, start_bit, len) {
                   +  + ]
     448                 :            :                                 if (record_match(i, size, calls) != TEST_SUCCESS)
     449                 :            :                                         return TEST_FAILED;
     450                 :            :                         }
     451                 :            :                 }
     452                 :            :         } else {
     453   [ +  +  +  + ]:      20020 :                 if (full_range && rand_bool()) {
     454   [ +  +  +  + ]:         35 :                         RTE_BITSET_FOREACH_CLEAR(i, bitset, size)
     455                 :            :                                 if (record_match(i, size, calls) != TEST_SUCCESS)
     456                 :            :                                         return TEST_FAILED;
     457         [ +  + ]:      19989 :                 } else if (may_wrap) {
     458   [ +  +  +  +  :    1280677 :                         RTE_BITSET_FOREACH_CLEAR_WRAP(i, bitset, size, start_bit, len) {
                   +  + ]
     459                 :            :                                 if (record_match(i, size, calls) != TEST_SUCCESS)
     460                 :            :                                         return TEST_FAILED;
     461                 :            :                         }
     462                 :            :                 } else {
     463   [ +  -  +  +  :     638486 :                         RTE_BITSET_FOREACH_CLEAR_RANGE(i, bitset, size, start_bit, len)
                   +  + ]
     464                 :            :                                 if (record_match(i, size, calls) != TEST_SUCCESS)
     465                 :            :                                         return TEST_FAILED;
     466                 :            :                 }
     467                 :            :         }
     468                 :            : 
     469         [ +  + ]:    7586471 :         for (i = 0; i < len; i++) {
     470                 :    7546471 :                 size_t idx = (start_bit + i) % size;
     471                 :            : 
     472   [ +  +  -  + ]:    7546471 :                 if (reference[idx] == set && calls[idx] != 1) {
     473                 :            :                         printf("bit %zd shouldn't have been found %d times\n", idx, calls[idx]);
     474                 :          0 :                         return TEST_FAILED;
     475                 :            :                 }
     476                 :            : 
     477   [ +  +  -  + ]:    7546471 :                 if (reference[idx] != set && calls[idx] != 0) {
     478                 :          0 :                         puts("bar");
     479                 :          0 :                         return TEST_FAILED;
     480                 :            :                 }
     481                 :            : 
     482                 :    7546471 :                 total_calls += calls[idx];
     483                 :            :         }
     484                 :            : 
     485         [ +  + ]:      40000 :         if (full_range) {
     486                 :            :                 size_t count;
     487                 :            : 
     488         [ +  + ]:         41 :                 count = set ? rte_bitset_count_set(bitset, size) :
     489                 :            :                         rte_bitset_count_clear(bitset, size);
     490                 :            : 
     491         [ +  - ]:         41 :                 if (count != total_calls)
     492                 :            :                         return TEST_FAILED;
     493                 :            :         }
     494                 :            : 
     495         [ -  + ]:      40000 :         TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS,
     496                 :            :                 "Buffer over- or underrun detected");
     497                 :            : 
     498                 :            :         return TEST_SUCCESS;
     499                 :            : }
     500                 :            : 
     501                 :            : static int
     502                 :          1 : test_foreach(void)
     503                 :            : {
     504                 :            :         size_t i;
     505                 :            : 
     506         [ +  + ]:      10001 :         for (i = 0; i < RAND_ITERATIONS; i++) {
     507                 :      10000 :                 size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1);
     508                 :            : 
     509         [ +  - ]:      10000 :                 if (test_foreach_size(size, false, true) != TEST_SUCCESS)
     510                 :            :                         return TEST_FAILED;
     511                 :            : 
     512         [ +  - ]:      10000 :                 if (test_foreach_size(size, false, false) != TEST_SUCCESS)
     513                 :            :                         return TEST_FAILED;
     514                 :            : 
     515         [ +  - ]:      10000 :                 if (test_foreach_size(size, true, true) != TEST_SUCCESS)
     516                 :            :                         return TEST_FAILED;
     517                 :            : 
     518         [ +  - ]:      10000 :                 if (test_foreach_size(size, true, false) != TEST_SUCCESS)
     519                 :            :                         return TEST_FAILED;
     520                 :            :         }
     521                 :            : 
     522                 :            :         return TEST_SUCCESS;
     523                 :            : }
     524                 :            : 
     525                 :            : static int
     526                 :      10005 : test_count_size(size_t size)
     527                 :            : {
     528                 :            :         uint64_t *bitset;
     529                 :            : 
     530                 :      10005 :         bitset = alloc_bitset(size);
     531                 :            : 
     532         [ -  + ]:      10005 :         TEST_ASSERT(bitset != NULL, "Failed to allocate memory");
     533                 :            : 
     534                 :            :         rte_bitset_init(bitset, size);
     535                 :            : 
     536                 :      10005 :         rand_unused_bits(bitset, size);
     537                 :            : 
     538         [ +  - ]:      10005 :         if (rte_bitset_count_set(bitset, size) != 0)
     539                 :            :                 return TEST_FAILED;
     540                 :            : 
     541                 :            :         if (rte_bitset_count_clear(bitset, size) != size)
     542                 :            :                 return TEST_FAILED;
     543                 :            : 
     544                 :            :         rte_bitset_set_all(bitset, size);
     545                 :            : 
     546         [ +  - ]:      10005 :         if (rte_bitset_count_set(bitset, size) != size)
     547                 :            :                 return TEST_FAILED;
     548                 :            : 
     549                 :            :         if (rte_bitset_count_clear(bitset, size) != 0)
     550                 :            :                 return TEST_FAILED;
     551                 :            : 
     552                 :            :         rte_bitset_clear_all(bitset, size);
     553                 :            : 
     554         [ +  - ]:      10005 :         if (rte_bitset_count_set(bitset, size) != 0)
     555                 :            :                 return TEST_FAILED;
     556                 :            : 
     557                 :            :         if (rte_bitset_count_clear(bitset, size) != size)
     558                 :            :                 return TEST_FAILED;
     559                 :            : 
     560                 :      10005 :         rte_bitset_set(bitset, rte_rand_max(size));
     561                 :            : 
     562         [ +  - ]:      10005 :         if (rte_bitset_count_set(bitset, size) != 1)
     563                 :            :                 return TEST_FAILED;
     564                 :            : 
     565                 :            :         if (rte_bitset_count_clear(bitset, size) != (size - 1))
     566                 :            :                 return TEST_FAILED;
     567                 :            : 
     568                 :            :         rte_bitset_clear_all(bitset, size);
     569         [ +  - ]:      10005 :         if (rte_bitset_count_set(bitset, size) != 0)
     570                 :            :                 return TEST_FAILED;
     571                 :            :         if (rte_bitset_count_clear(bitset, size) != size)
     572                 :            :                 return TEST_FAILED;
     573                 :            : 
     574                 :            :         rte_bitset_set_all(bitset, size);
     575         [ +  - ]:      10005 :         if (rte_bitset_count_set(bitset, size) != size)
     576                 :            :                 return TEST_FAILED;
     577                 :            :         if (rte_bitset_count_clear(bitset, size) != 0)
     578                 :            :                 return TEST_FAILED;
     579                 :            : 
     580         [ -  + ]:      10005 :         TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS,
     581                 :            :                 "Buffer over- or underrun detected");
     582                 :            : 
     583                 :            :         return TEST_SUCCESS;
     584                 :            : }
     585                 :            : 
     586                 :            : static int
     587                 :          1 : test_count(void)
     588                 :            : {
     589                 :            :         size_t i;
     590                 :            : 
     591         [ +  - ]:          1 :         if (test_count_size(128) != TEST_SUCCESS)
     592                 :            :                 return TEST_FAILED;
     593         [ +  - ]:          1 :         if (test_count_size(1) != TEST_SUCCESS)
     594                 :            :                 return TEST_FAILED;
     595         [ +  - ]:          1 :         if (test_count_size(63) != TEST_SUCCESS)
     596                 :            :                 return TEST_FAILED;
     597         [ +  - ]:          1 :         if (test_count_size(64) != TEST_SUCCESS)
     598                 :            :                 return TEST_FAILED;
     599         [ +  - ]:          1 :         if (test_count_size(65) != TEST_SUCCESS)
     600                 :            :                 return TEST_FAILED;
     601                 :            : 
     602         [ +  + ]:      10001 :         for (i = 0; i < RAND_ITERATIONS; i++) {
     603                 :      10000 :                 size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1);
     604                 :            : 
     605         [ +  - ]:      10000 :                 if (test_count_size(size) != TEST_SUCCESS)
     606                 :            :                         return TEST_FAILED;
     607                 :            :         }
     608                 :            : 
     609                 :            :         return TEST_SUCCESS;
     610                 :            : }
     611                 :            : 
     612                 :            : #define GEN_DECLARE(size) \
     613                 :            : { \
     614                 :            :         RTE_BITSET_DECLARE(bitset, size); \
     615                 :            :         size_t idx = rte_rand_max(size); \
     616                 :            :         rte_bitset_init(bitset, size); \
     617                 :            :         rte_bitset_set(bitset, idx); \
     618                 :            :         if (!rte_bitset_test(bitset, idx)) \
     619                 :            :                 return TEST_FAILED; \
     620                 :            :         if (rte_bitset_count_set(bitset, size) != 1) \
     621                 :            :                 return TEST_FAILED; \
     622                 :            :         return TEST_SUCCESS; \
     623                 :            : }
     624                 :            : 
     625                 :            : static int
     626                 :          1 : test_define(void)
     627                 :            : {
     628         [ -  + ]:          1 :         GEN_DECLARE(1);
     629                 :            :         GEN_DECLARE(64);
     630                 :            :         GEN_DECLARE(65);
     631                 :            :         GEN_DECLARE(4097);
     632                 :            : }
     633                 :            : 
     634                 :            : typedef void bitset_op(uint64_t *dst, const uint64_t *a, const uint64_t *b, size_t bit_num);
     635                 :            : typedef bool bool_op(bool a, bool b);
     636                 :            : 
     637                 :            : #define LOGIC_MAX_SET_SIZE 200
     638                 :            : 
     639                 :            : static int
     640                 :          3 : test_logic_op(bitset_op bitset_op, bool_op bool_op)
     641                 :            : {
     642                 :          3 :         const size_t size = 1 + rte_rand_max(LOGIC_MAX_SET_SIZE);
     643                 :            :         RTE_BITSET_DECLARE(bitset_a, LOGIC_MAX_SET_SIZE);
     644                 :            :         RTE_BITSET_DECLARE(bitset_b, LOGIC_MAX_SET_SIZE);
     645                 :            :         RTE_BITSET_DECLARE(bitset_d, LOGIC_MAX_SET_SIZE);
     646                 :            : 
     647                 :            :         bool ary_a[LOGIC_MAX_SET_SIZE];
     648                 :            :         bool ary_b[LOGIC_MAX_SET_SIZE];
     649                 :            :         bool ary_d[LOGIC_MAX_SET_SIZE];
     650                 :            : 
     651                 :            :         rand_bool_ary(ary_a, size);
     652                 :            :         rand_bool_ary(ary_b, size);
     653                 :            : 
     654                 :            :         size_t i;
     655         [ +  + ]:        475 :         for (i = 0; i < size; i++) {
     656         [ +  + ]:        472 :                 rte_bitset_assign(bitset_a, i, ary_a[i]);
     657         [ +  + ]:        472 :                 rte_bitset_assign(bitset_b, i, ary_b[i]);
     658                 :        472 :                 ary_d[i] = bool_op(ary_a[i], ary_b[i]);
     659                 :            :         }
     660                 :            : 
     661                 :          3 :         bitset_op(bitset_d, bitset_a, bitset_b, size);
     662                 :            : 
     663         [ +  + ]:        475 :         for (i = 0; i < size; i++)
     664         [ -  + ]:        472 :                 TEST_ASSERT_EQUAL(rte_bitset_test(bitset_d, i), ary_d[i],
     665                 :            :                         "Unexpected value of bit %zd", i);
     666                 :            : 
     667                 :            :         return TEST_SUCCESS;
     668                 :            : }
     669                 :            : 
     670                 :            : static bool
     671                 :        190 : bool_or(bool a, bool b)
     672                 :            : {
     673                 :        190 :         return a || b;
     674                 :            : }
     675                 :            : 
     676                 :            : static int
     677                 :          1 : test_or(void)
     678                 :            : {
     679                 :          1 :         return test_logic_op(rte_bitset_or, bool_or);
     680                 :            : }
     681                 :            : 
     682                 :            : static bool
     683                 :        151 : bool_and(bool a, bool b)
     684                 :            : {
     685                 :        151 :         return a && b;
     686                 :            : }
     687                 :            : 
     688                 :            : static int
     689                 :          1 : test_and(void)
     690                 :            : {
     691                 :          1 :         return test_logic_op(rte_bitset_and, bool_and);
     692                 :            : }
     693                 :            : 
     694                 :            : static bool
     695                 :        131 : bool_xor(bool a, bool b)
     696                 :            : {
     697                 :        131 :         return a != b;
     698                 :            : }
     699                 :            : 
     700                 :            : static int
     701                 :          1 : test_xor(void)
     702                 :            : {
     703                 :          1 :         return test_logic_op(rte_bitset_xor, bool_xor);
     704                 :            : }
     705                 :            : 
     706                 :            : static int
     707                 :          1 : test_complement(void)
     708                 :            : {
     709                 :            :         int i;
     710                 :            : 
     711         [ +  + ]:      10001 :         for (i = 0; i < RAND_ITERATIONS; i++) {
     712                 :      10000 :                 const size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1);
     713                 :            : 
     714                 :            :                 RTE_BITSET_DECLARE(src, RAND_SET_MAX_SIZE);
     715                 :            : 
     716                 :      10000 :                 rand_bitset(src, size);
     717                 :            : 
     718                 :      10000 :                 bool bit_idx = rte_rand_max(size);
     719                 :            :                 bool bit_value = rte_bitset_test(src, bit_idx);
     720                 :            : 
     721                 :            :                 RTE_BITSET_DECLARE(dst, RAND_SET_MAX_SIZE);
     722                 :            : 
     723                 :            :                 rte_bitset_complement(dst, src, size);
     724                 :            : 
     725         [ -  + ]:      10000 :                 TEST_ASSERT(bit_value != rte_bitset_test(dst, bit_idx),
     726                 :            :                         "Bit %d was not flipped", bit_idx);
     727                 :            :         }
     728                 :            : 
     729                 :            :         return TEST_SUCCESS;
     730                 :            : }
     731                 :            : 
     732                 :            : #define SHIFT_SET_MAX_SIZE 500
     733                 :            : 
     734                 :            : static int
     735                 :          2 : test_shift(bool right)
     736                 :            : {
     737                 :            :         int i;
     738                 :            : 
     739         [ +  + ]:          2 :         const char *direction = right ? "right" : "left";
     740                 :            : 
     741         [ +  + ]:      20002 :         for (i = 0; i < 10000; i++) {
     742                 :      20000 :                 const int size = 1 + (int)rte_rand_max(SHIFT_SET_MAX_SIZE);
     743                 :      20000 :                 const int shift_count = (int)rte_rand_max(1.5 * size);
     744                 :            :                 int src_idx;
     745                 :            : 
     746                 :            :                 RTE_BITSET_DECLARE(src, SHIFT_SET_MAX_SIZE);
     747                 :            :                 RTE_BITSET_DECLARE(reference, SHIFT_SET_MAX_SIZE);
     748                 :            : 
     749                 :      20000 :                 rte_bitset_init(src, size);
     750                 :            :                 rte_bitset_init(reference, size);
     751                 :            : 
     752                 :      20000 :                 rand_unused_bits(src, size);
     753                 :      20000 :                 rand_unused_bits(reference, size);
     754                 :            : 
     755         [ +  + ]:    5015027 :                 for (src_idx = 0; src_idx < size; src_idx++) {
     756                 :            :                         bool value = rand_bool();
     757                 :            : 
     758         [ +  + ]:    4995027 :                         rte_bitset_assign(src, src_idx, value);
     759                 :            : 
     760         [ +  + ]:    4995027 :                         int dst_idx = right ? src_idx - shift_count : src_idx + shift_count;
     761                 :            : 
     762         [ +  + ]:    4995027 :                         if (dst_idx >= 0 && dst_idx < size)
     763         [ +  + ]:    1646561 :                                 rte_bitset_assign(reference, dst_idx, value);
     764                 :            :                 }
     765                 :            : 
     766                 :      20000 :                 uint64_t *dst = alloc_bitset(size);
     767                 :            : 
     768         [ +  + ]:      20000 :                 if (right)
     769                 :      10000 :                         rte_bitset_shift_right(dst, src, size, shift_count);
     770                 :            :                 else
     771                 :      10000 :                         rte_bitset_shift_left(dst, src, size, shift_count);
     772                 :            : 
     773         [ -  + ]:      20000 :                 TEST_ASSERT(rte_bitset_equal(dst, reference, size),
     774                 :            :                         "Unexpected result from shifting bitset of size %d bits %d bits %s",
     775                 :            :                         size, shift_count, direction);
     776                 :            : 
     777         [ -  + ]:      20000 :                 TEST_ASSERT_EQUAL(free_bitset(dst, size), TEST_SUCCESS,
     778                 :            :                         "Shift %s operation overwrote buffer", direction);
     779                 :            :         }
     780                 :            : 
     781                 :            :         return TEST_SUCCESS;
     782                 :            : }
     783                 :            : 
     784                 :            : static int
     785                 :          1 : test_shift_right(void)
     786                 :            : {
     787                 :          1 :         return test_shift(true);
     788                 :            : }
     789                 :            : 
     790                 :            : static int
     791                 :          1 : test_shift_left(void)
     792                 :            : {
     793                 :          1 :         return test_shift(false);
     794                 :            : }
     795                 :            : 
     796                 :            : #define EQUAL_SET_MAX_SIZE 100
     797                 :            : 
     798                 :            : static int
     799                 :          1 : test_equal(void)
     800                 :            : {
     801                 :            :         const size_t size = EQUAL_SET_MAX_SIZE;
     802                 :            :         RTE_BITSET_DECLARE(bitset_a, EQUAL_SET_MAX_SIZE);
     803                 :            :         RTE_BITSET_DECLARE(bitset_b, EQUAL_SET_MAX_SIZE);
     804                 :            : 
     805                 :            :         rand_buf(bitset_a, RTE_BITSET_SIZE(size));
     806                 :            :         rand_buf(bitset_b, RTE_BITSET_SIZE(size));
     807                 :            : 
     808                 :            :         rte_bitset_init(bitset_a, size);
     809                 :            :         rte_bitset_init(bitset_b, size);
     810                 :            : 
     811                 :            :         rte_bitset_set(bitset_a, 9);
     812                 :            :         rte_bitset_set(bitset_b, 9);
     813                 :            :         rte_bitset_set(bitset_a, 90);
     814                 :            :         rte_bitset_set(bitset_b, 90);
     815                 :            : 
     816         [ +  - ]:          1 :         if (!rte_bitset_equal(bitset_a, bitset_b, size))
     817                 :            :                 return TEST_FAILED;
     818                 :            : 
     819                 :            :         /* set unused bit, which should be ignored */
     820                 :            :         rte_bitset_set(&bitset_a[1], 60);
     821                 :            : 
     822         [ -  + ]:          1 :         if (!rte_bitset_equal(bitset_a, bitset_b, size))
     823                 :          0 :                 return TEST_FAILED;
     824                 :            : 
     825                 :            :         return TEST_SUCCESS;
     826                 :            : }
     827                 :            : 
     828                 :            : static int
     829                 :          1 : test_copy(void)
     830                 :            : {
     831                 :            :         const size_t size = EQUAL_SET_MAX_SIZE;
     832                 :            :         RTE_BITSET_DECLARE(bitset_a, EQUAL_SET_MAX_SIZE);
     833                 :            :         RTE_BITSET_DECLARE(bitset_b, EQUAL_SET_MAX_SIZE);
     834                 :            : 
     835                 :            :         rand_buf(bitset_a, RTE_BITSET_SIZE(size));
     836                 :            :         rand_buf(bitset_b, RTE_BITSET_SIZE(size));
     837                 :            : 
     838                 :            :         rte_bitset_copy(bitset_a, bitset_b, size);
     839                 :            : 
     840         [ -  + ]:          1 :         if (!rte_bitset_equal(bitset_a, bitset_b, size))
     841                 :          0 :                 return TEST_FAILED;
     842                 :            : 
     843                 :            :         return TEST_SUCCESS;
     844                 :            : }
     845                 :            : 
     846                 :            : static int
     847                 :          1 : test_to_str(void)
     848                 :            : {
     849                 :            :         char buf[1024];
     850                 :            :         RTE_BITSET_DECLARE(bitset, 128);
     851                 :            : 
     852                 :            :         rte_bitset_init(bitset, 128);
     853                 :            :         rte_bitset_set(bitset, 1);
     854                 :            : 
     855         [ +  - ]:          1 :         if (rte_bitset_to_str(bitset, 2, buf, 3) != 3)
     856                 :            :                 return TEST_FAILED;
     857         [ +  - ]:          1 :         if (strcmp(buf, "10") != 0)
     858                 :            :                 return TEST_FAILED;
     859                 :            : 
     860                 :            :         rte_bitset_set(bitset, 0);
     861                 :            : 
     862         [ +  - ]:          1 :         if (rte_bitset_to_str(bitset, 1, buf, sizeof(buf)) != 2)
     863                 :            :                 return TEST_FAILED;
     864         [ +  - ]:          1 :         if (strcmp(buf, "1") != 0)
     865                 :            :                 return TEST_FAILED;
     866                 :            : 
     867                 :            :         rte_bitset_init(bitset, 99);
     868                 :            :         rte_bitset_set(bitset, 98);
     869                 :            : 
     870         [ +  - ]:          1 :         if (rte_bitset_to_str(bitset, 99, buf, sizeof(buf)) != 100)
     871                 :            :                 return TEST_FAILED;
     872                 :            : 
     873   [ +  -  +  - ]:          1 :         if (buf[0] != '1' || strchr(&buf[1], '1') != NULL)
     874                 :            :                 return TEST_FAILED;
     875                 :            : 
     876         [ -  + ]:          1 :         if (rte_bitset_to_str(bitset, 128, buf, 64) != -EINVAL)
     877                 :          0 :                 return TEST_FAILED;
     878                 :            : 
     879                 :            :         return TEST_SUCCESS;
     880                 :            : }
     881                 :            : 
     882                 :            : static struct unit_test_suite bitset_tests = {
     883                 :            :         .suite_name = "bitset test suite",
     884                 :            :         .unit_test_cases = {
     885                 :            :                 TEST_CASE_ST(NULL, NULL, test_set_clear),
     886                 :            :                 TEST_CASE_ST(NULL, NULL, test_flip),
     887                 :            :                 TEST_CASE_ST(NULL, NULL, test_atomic_set_clear),
     888                 :            :                 TEST_CASE_ST(NULL, NULL, test_atomic_flip),
     889                 :            :                 TEST_CASE_ST(NULL, NULL, test_find),
     890                 :            :                 TEST_CASE_ST(NULL, NULL, test_foreach),
     891                 :            :                 TEST_CASE_ST(NULL, NULL, test_count),
     892                 :            :                 TEST_CASE_ST(NULL, NULL, test_define),
     893                 :            :                 TEST_CASE_ST(NULL, NULL, test_or),
     894                 :            :                 TEST_CASE_ST(NULL, NULL, test_and),
     895                 :            :                 TEST_CASE_ST(NULL, NULL, test_xor),
     896                 :            :                 TEST_CASE_ST(NULL, NULL, test_complement),
     897                 :            :                 TEST_CASE_ST(NULL, NULL, test_shift_right),
     898                 :            :                 TEST_CASE_ST(NULL, NULL, test_shift_left),
     899                 :            :                 TEST_CASE_ST(NULL, NULL, test_equal),
     900                 :            :                 TEST_CASE_ST(NULL, NULL, test_copy),
     901                 :            :                 TEST_CASE_ST(NULL, NULL, test_to_str),
     902                 :            :                 TEST_CASES_END()
     903                 :            :         }
     904                 :            : };
     905                 :            : 
     906                 :            : static int
     907                 :          1 : test_bitset(void)
     908                 :            : {
     909                 :          1 :         return unit_test_suite_runner(&bitset_tests);
     910                 :            : }
     911                 :            : 
     912                 :        252 : REGISTER_FAST_TEST(bitset_autotest, true, true, test_bitset);

Generated by: LCOV version 1.14