LCOV - code coverage report
Current view: top level - zephyr/sys - bitarray.h Hit Total Coverage
Test: new.info Lines: 18 19 94.7 %
Date: 2024-12-22 00:14:23

          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 1.14