LCOV - code coverage report
Current view: top level - zephyr/sys - bitarray.h Coverage Total Hit
Test: new.info Lines: 94.7 % 19 18
Test Date: 2025-09-05 20:47:19

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2021 Intel Corporation
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef ZEPHYR_INCLUDE_SYS_BITARRAY_H_
       8              : #define ZEPHYR_INCLUDE_SYS_BITARRAY_H_
       9              : 
      10              : #ifdef __cplusplus
      11              : extern "C" {
      12              : #endif
      13              : 
      14              : #include <stddef.h>
      15              : #include <stdint.h>
      16              : 
      17              : #include <zephyr/kernel.h>
      18              : #include <zephyr/sys/util.h>
      19              : 
      20              : /**
      21              :  * @file
      22              :  *
      23              :  * @defgroup bitarray_apis Bit array
      24              :  * @ingroup datastructure_apis
      25              :  *
      26              :  * @brief Store and manipulate bits in a bit array.
      27              :  *
      28              :  * @{
      29              :  */
      30              : 
      31              : /** @cond INTERNAL_HIDDEN */
      32              : struct sys_bitarray {
      33              :         /* Number of bits */
      34              :         uint32_t num_bits;
      35              : 
      36              :         /* Number of bundles */
      37              :         uint32_t num_bundles;
      38              : 
      39              :         /* Bundle of bits */
      40              :         uint32_t *bundles;
      41              : 
      42              :         /* Spinlock guarding access to this bit array */
      43              :         struct k_spinlock lock;
      44              : };
      45              : /** @endcond */
      46              : 
      47              : /** Bitarray structure */
      48            1 : typedef struct sys_bitarray sys_bitarray_t;
      49              : 
      50              : /**
      51              :  * @brief Create a bitarray object.
      52              :  *
      53              :  * @param name Name of the bitarray object.
      54              :  * @param total_bits Total number of bits in this bitarray object.
      55              :  * @param sba_mod Modifier to the bitarray variables.
      56              :  */
      57              : #define _SYS_BITARRAY_DEFINE(name, total_bits, sba_mod)                 \
      58              :         sba_mod uint32_t _sys_bitarray_bundles_##name                   \
      59              :                 [DIV_ROUND_UP(DIV_ROUND_UP(total_bits, 8),              \
      60              :                                sizeof(uint32_t))] = {0};                \
      61              :         sba_mod sys_bitarray_t name = {                                 \
      62              :                 .num_bits = (total_bits),                               \
      63              :                 .num_bundles = DIV_ROUND_UP(                            \
      64              :                         DIV_ROUND_UP(total_bits, 8), sizeof(uint32_t)), \
      65              :                 .bundles = _sys_bitarray_bundles_##name,                \
      66              :         }
      67              : 
      68              : /**
      69              :  * @brief Create a bitarray object.
      70              :  *
      71              :  * @param name Name of the bitarray object.
      72              :  * @param total_bits Total number of bits in this bitarray object.
      73              :  */
      74            1 : #define SYS_BITARRAY_DEFINE(name, total_bits)                           \
      75              :         _SYS_BITARRAY_DEFINE(name, total_bits,)
      76              : 
      77              : /**
      78              :  * @brief Create a static bitarray object.
      79              :  *
      80              :  * @param name Name of the bitarray object.
      81              :  * @param total_bits Total number of bits in this bitarray object.
      82              :  */
      83            1 : #define SYS_BITARRAY_DEFINE_STATIC(name, total_bits)                    \
      84              :         _SYS_BITARRAY_DEFINE(name, total_bits, static)
      85              : 
      86              : /**
      87              :  * Set a bit in a bit array
      88              :  *
      89              :  * @param[in] bitarray Bitarray struct
      90              :  * @param[in] bit      The bit to be set
      91              :  *
      92              :  * @retval 0       Operation successful
      93              :  * @retval -EINVAL Invalid argument (e.g. bit to set exceeds
      94              :  *                 the number of bits in bit array, etc.)
      95              :  */
      96            1 : int sys_bitarray_set_bit(sys_bitarray_t *bitarray, size_t bit);
      97              : 
      98              : /**
      99              :  * Clear a bit in a bit array
     100              :  *
     101              :  * @param[in] bitarray Bitarray struct
     102              :  * @param[in] bit      The bit to be cleared
     103              :  *
     104              :  * @retval 0       Operation successful
     105              :  * @retval -EINVAL Invalid argument (e.g. bit to clear exceeds
     106              :  *                 the number of bits in bit array, etc.)
     107              :  */
     108            1 : int sys_bitarray_clear_bit(sys_bitarray_t *bitarray, size_t bit);
     109              : 
     110              : /**
     111              :  * Test whether a bit is set or not
     112              :  *
     113              :  * @param[in]  bitarray Bitarray struct
     114              :  * @param[in]  bit      The bit to be tested
     115              :  * @param[out] val      The value of the bit (0 or 1)
     116              :  *
     117              :  * @retval 0       Operation successful
     118              :  * @retval -EINVAL Invalid argument (e.g. bit to test exceeds
     119              :  *                 the number of bits in bit array, etc.)
     120              :  */
     121            1 : int sys_bitarray_test_bit(sys_bitarray_t *bitarray, size_t bit, int *val);
     122              : 
     123              : /**
     124              :  * Test the bit and set it
     125              :  *
     126              :  * @param[in]  bitarray Bitarray struct
     127              :  * @param[in]  bit      The bit to be tested and set
     128              :  * @param[out] prev_val Previous value of the bit (0 or 1)
     129              :  *
     130              :  * @retval 0       Operation successful
     131              :  * @retval -EINVAL Invalid argument (e.g. bit to test exceeds
     132              :  *                 the number of bits in bit array, etc.)
     133              :  */
     134            1 : int sys_bitarray_test_and_set_bit(sys_bitarray_t *bitarray, size_t bit, int *prev_val);
     135              : 
     136              : /**
     137              :  * Test the bit and clear it
     138              :  *
     139              :  * @param[in]  bitarray Bitarray struct
     140              :  * @param[in]  bit      The bit to be tested and cleared
     141              :  * @param[out] prev_val Previous value of the bit (0 or 1)
     142              :  *
     143              :  * @retval 0       Operation successful
     144              :  * @retval -EINVAL Invalid argument (e.g. bit to test exceeds
     145              :  *                 the number of bits in bit array, etc.)
     146              :  */
     147            1 : int sys_bitarray_test_and_clear_bit(sys_bitarray_t *bitarray, size_t bit, int *prev_val);
     148              : 
     149              : /**
     150              :  * Allocate bits in a bit array
     151              :  *
     152              :  * This finds a number of bits (@p num_bits) in a contiguous of
     153              :  * previously unallocated region. If such a region exists, the bits are
     154              :  * marked as allocated and the offset to the start of this region is
     155              :  * returned via @p offset.
     156              :  *
     157              :  * @param[in]  bitarray Bitarray struct
     158              :  * @param[in]  num_bits Number of bits to allocate
     159              :  * @param[out] offset   Offset to the start of allocated region if
     160              :  *                      successful
     161              :  *
     162              :  * @retval 0       Allocation successful
     163              :  * @retval -EINVAL Invalid argument (e.g. allocating more bits than
     164              :  *                 the bitarray has, trying to allocate 0 bits, etc.)
     165              :  * @retval -ENOSPC No contiguous region big enough to accommodate
     166              :  *                 the allocation
     167              :  */
     168            1 : int sys_bitarray_alloc(sys_bitarray_t *bitarray, size_t num_bits,
     169              :                        size_t *offset);
     170              : 
     171              : /**
     172              :  * Calculates the bit-wise XOR of two bitarrays in a region.
     173              :  * The result is stored in the first bitarray passed in (@p dst).
     174              :  * Both bitarrays must be of the same size.
     175              :  *
     176              :  * @param dst      Bitarray struct
     177              :  * @param other    Bitarray struct
     178              :  * @param num_bits Number of bits in the region, must be larger than 0
     179              :  * @param offset   Starting bit location
     180              :  *
     181              :  * @retval 0       Operation successful
     182              :  * @retval -EINVAL Invalid argument (e.g. out-of-bounds access, mismatching bitarrays, trying to xor
     183              :  * 0 bits, etc.)
     184              :  */
     185            1 : int sys_bitarray_xor(sys_bitarray_t *dst, sys_bitarray_t *other, size_t num_bits, size_t offset);
     186              : 
     187              : /**
     188              :  * Find nth bit set in region
     189              :  *
     190              :  * This counts the number of bits set (@p count) in a
     191              :  * region (@p offset, @p num_bits) and returns the index (@p found_at)
     192              :  * of the nth set bit, if it exists, as long with a zero return value.
     193              :  *
     194              :  * If it does not exist, @p found_at is not updated and the method returns
     195              :  *
     196              :  * @param[in]  bitarray Bitarray struct
     197              :  * @param[in]  n        Nth bit set to look for
     198              :  * @param[in]  num_bits Number of bits to check, must be larger than 0
     199              :  * @param[in]  offset   Starting bit position
     200              :  * @param[out] found_at Index of the nth bit set, if found
     201              :  *
     202              :  * @retval 0       Operation successful
     203              :  * @retval 1       Nth bit set was not found in region
     204              :  * @retval -EINVAL Invalid argument (e.g. out-of-bounds access, trying to count 0 bits, etc.)
     205              :  */
     206            1 : int sys_bitarray_find_nth_set(sys_bitarray_t *bitarray, size_t n, size_t num_bits, size_t offset,
     207              :                               size_t *found_at);
     208              : 
     209              : /**
     210              :  * Count bits set in a bit array region
     211              :  *
     212              :  * This counts the number of bits set (@p count) in a
     213              :  * region (@p offset, @p num_bits).
     214              :  *
     215              :  * @param[in]  bitarray Bitarray struct
     216              :  * @param[in]  num_bits Number of bits to check, must be larger than 0
     217              :  * @param[in]  offset   Starting bit position
     218              :  * @param[out] count    Number of bits set in the region if successful
     219              :  *
     220              :  * @retval 0       Operation successful
     221              :  * @retval -EINVAL Invalid argument (e.g. out-of-bounds access, trying to count 0 bits, etc.)
     222              :  */
     223            1 : int sys_bitarray_popcount_region(sys_bitarray_t *bitarray, size_t num_bits, size_t offset,
     224              :                                  size_t *count);
     225              : 
     226              : /**
     227              :  * Free bits in a bit array
     228              :  *
     229              :  * This marks the number of bits (@p num_bits) starting from @p offset
     230              :  * as no longer allocated.
     231              :  *
     232              :  * @param bitarray Bitarray struct
     233              :  * @param num_bits Number of bits to free
     234              :  * @param offset   Starting bit position to free
     235              :  *
     236              :  * @retval 0       Free is successful
     237              :  * @retval -EINVAL Invalid argument (e.g. try to free more bits than
     238              :  *                 the bitarray has, trying to free 0 bits, etc.)
     239              :  * @retval -EFAULT The bits in the indicated region are not all allocated.
     240              :  */
     241            1 : int sys_bitarray_free(sys_bitarray_t *bitarray, size_t num_bits,
     242              :                       size_t offset);
     243              : 
     244              : /**
     245              :  * Test if bits in a region is all set.
     246              :  *
     247              :  * This tests if the number of bits (@p num_bits) in region starting
     248              :  * from @p offset are all set.
     249              :  *
     250              :  * @param bitarray Bitarray struct
     251              :  * @param num_bits Number of bits to test
     252              :  * @param offset   Starting bit position to test
     253              :  *
     254              :  * @retval true    All bits are set.
     255              :  * @retval false   Not all bits are set.
     256              :  */
     257            1 : bool sys_bitarray_is_region_set(sys_bitarray_t *bitarray, size_t num_bits,
     258              :                                 size_t offset);
     259              : 
     260              : /**
     261              :  * Test if bits in a region is all cleared.
     262              :  *
     263              :  * This tests if the number of bits (@p num_bits) in region starting
     264              :  * from @p offset are all cleared.
     265              :  *
     266              :  * @param bitarray Bitarray struct
     267              :  * @param num_bits Number of bits to test
     268              :  * @param offset   Starting bit position to test
     269              :  *
     270              :  * @retval true    All bits are cleared.
     271              :  * @retval false   Not all bits are cleared.
     272              :  */
     273            1 : bool sys_bitarray_is_region_cleared(sys_bitarray_t *bitarray, size_t num_bits,
     274              :                                     size_t offset);
     275              : 
     276              : /**
     277              :  * Set all bits in a region.
     278              :  *
     279              :  * This sets the number of bits (@p num_bits) in region starting
     280              :  * from @p offset.
     281              :  *
     282              :  * @param bitarray Bitarray struct
     283              :  * @param num_bits Number of bits to test
     284              :  * @param offset   Starting bit position to test
     285              :  *
     286              :  * @retval 0       Operation successful
     287              :  * @retval -EINVAL Invalid argument (e.g. bit to set exceeds
     288              :  *                 the number of bits in bit array, etc.)
     289              :  */
     290            1 : int sys_bitarray_set_region(sys_bitarray_t *bitarray, size_t num_bits,
     291              :                             size_t offset);
     292              : 
     293              : /**
     294              :  * Test if all bits in a region are cleared/set and set/clear them
     295              :  * in a single atomic operation
     296              :  *
     297              :  * This checks if all the bits (@p num_bits) in region starting
     298              :  * from @p offset are in required state. If even one bit is not,
     299              :  * -EEXIST is returned.  If the whole region is set/cleared
     300              :  * it is set to opposite state. The check and set is performed as a single
     301              :  * atomic operation.
     302              :  *
     303              :  * @param bitarray Bitarray struct
     304              :  * @param num_bits Number of bits to test and set
     305              :  * @param offset   Starting bit position to test and set
     306              :  * @param to_set   if true the region will be set if all bits are cleared
     307              :  *                 if false the region will be cleard if all bits are set
     308              :  *
     309              :  * @retval 0       Operation successful
     310              :  * @retval -EINVAL Invalid argument (e.g. bit to set exceeds
     311              :  *                 the number of bits in bit array, etc.)
     312              :  * @retval -EEXIST at least one bit in the region is set/cleared,
     313              :  *                 operation cancelled
     314              :  */
     315            1 : int sys_bitarray_test_and_set_region(sys_bitarray_t *bitarray, size_t num_bits,
     316              :                                      size_t offset, bool to_set);
     317              : 
     318              : /**
     319              :  * Clear all bits in a region.
     320              :  *
     321              :  * This clears the number of bits (@p num_bits) in region starting
     322              :  * from @p offset.
     323              :  *
     324              :  * @param bitarray Bitarray struct
     325              :  * @param num_bits Number of bits to test
     326              :  * @param offset   Starting bit position to test
     327              :  *
     328              :  * @retval 0       Operation successful
     329              :  * @retval -EINVAL Invalid argument (e.g. bit to set exceeds
     330              :  *                 the number of bits in bit array, etc.)
     331              :  */
     332            1 : int sys_bitarray_clear_region(sys_bitarray_t *bitarray, size_t num_bits,
     333              :                               size_t offset);
     334              : 
     335              : /**
     336              :  * @}
     337              :  */
     338              : 
     339              : #ifdef __cplusplus
     340              : }
     341              : #endif
     342              : 
     343              : #endif /* ZEPHYR_INCLUDE_SYS_BITARRAY_H_ */
        

Generated by: LCOV version 2.0-1