1 /* 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 <kernel.h> 18 19 struct sys_bitarray { 20 /* Number of bits */ 21 uint32_t num_bits; 22 23 /* Number of bundles */ 24 uint32_t num_bundles; 25 26 /* Bundle of bits */ 27 uint32_t *bundles; 28 29 /* Spinlock guarding access to this bit array */ 30 struct k_spinlock lock; 31 }; 32 33 typedef struct sys_bitarray sys_bitarray_t; 34 35 /** 36 * @def SYS_BITARRAY_DEFINE 37 * 38 * @brief Create a bitarray object. 39 * 40 * @param name Name of the bitarray object. 41 * @param total_bits Total number of bits in this bitarray object. 42 */ 43 #define SYS_BITARRAY_DEFINE(name, total_bits) \ 44 uint32_t _sys_bitarray_bundles_##name \ 45 [(((total_bits + 8 - 1) / 8) + sizeof(uint32_t) - 1) \ 46 / sizeof(uint32_t)] = {0U}; \ 47 sys_bitarray_t name = { \ 48 .num_bits = total_bits, \ 49 .num_bundles = (((total_bits + 8 - 1) / 8) \ 50 + sizeof(uint32_t) - 1) \ 51 / sizeof(uint32_t), \ 52 .bundles = _sys_bitarray_bundles_##name, \ 53 } 54 55 /** 56 * Set a bit in a bit array 57 * 58 * @param[in] bitarray Bitarray struct 59 * @param[in] bit The bit to be set 60 * 61 * @retval 0 Operation successful 62 * @retval -EINVAL Invalid argument (e.g. bit to set exceeds 63 * the number of bits in bit array, etc.) 64 */ 65 int sys_bitarray_set_bit(sys_bitarray_t *bitarray, size_t bit); 66 67 /** 68 * Clear a bit in a bit array 69 * 70 * @param[in] bitarray Bitarray struct 71 * @param[in] bit The bit to be cleared 72 * 73 * @retval 0 Operation successful 74 * @retval -EINVAL Invalid argument (e.g. bit to clear exceeds 75 * the number of bits in bit array, etc.) 76 */ 77 int sys_bitarray_clear_bit(sys_bitarray_t *bitarray, size_t bit); 78 79 /** 80 * Test whether a bit is set or not 81 * 82 * @param[in] bitarray Bitarray struct 83 * @param[in] bit The bit to be tested 84 * @param[out] val The value of the bit (0 or 1) 85 * 86 * @retval 0 Operation successful 87 * @retval -EINVAL Invalid argument (e.g. bit to test exceeds 88 * the number of bits in bit array, etc.) 89 */ 90 int sys_bitarray_test_bit(sys_bitarray_t *bitarray, size_t bit, int *val); 91 92 /** 93 * Test the bit and set it 94 * 95 * @param[in] bitarray Bitarray struct 96 * @param[in] bit The bit to be tested and set 97 * @param[out] prev_val Previous value of the bit (0 or 1) 98 * 99 * @retval 0 Operation successful 100 * @retval -EINVAL Invalid argument (e.g. bit to test exceeds 101 * the number of bits in bit array, etc.) 102 */ 103 int sys_bitarray_test_and_set_bit(sys_bitarray_t *bitarray, size_t bit, int *prev_val); 104 105 /** 106 * Test the bit and clear it 107 * 108 * @param[in] bitarray Bitarray struct 109 * @param[in] bit The bit to be tested and cleared 110 * @param[out] prev_val Previous value of the bit (0 or 1) 111 * 112 * @retval 0 Operation successful 113 * @retval -EINVAL Invalid argument (e.g. bit to test exceeds 114 * the number of bits in bit array, etc.) 115 */ 116 int sys_bitarray_test_and_clear_bit(sys_bitarray_t *bitarray, size_t bit, int *prev_val); 117 118 /** 119 * Allocate bits in a bit array 120 * 121 * This finds a number of bits (@p num_bits) in a contiguous of 122 * previosly unallocated region. If such a region exists, the bits are 123 * marked as allocated and the offset to the start of this region is 124 * returned via @p offset. 125 * 126 * @param[in] bitarray Bitarray struct 127 * @param[in] num_bits Number of bits to allocate 128 * @param[out] offset Offset to the start of allocated region if 129 * successful 130 * 131 * @retval 0 Allocation successful 132 * @retval -EINVAL Invalid argument (e.g. allocating more bits than 133 * the bitarray has, trying to allocate 0 bits, etc.) 134 * @retval -ENOSPC No contiguous region big enough to accommodate 135 * the allocation 136 */ 137 int sys_bitarray_alloc(sys_bitarray_t *bitarray, size_t num_bits, 138 size_t *offset); 139 140 /** 141 * Free bits in a bit array 142 * 143 * This marks the number of bits (@p num_bits) starting from @p offset 144 * as no longer allocated. 145 * 146 * @param bitarray Bitarray struct 147 * @param num_bits Number of bits to free 148 * @param offset Starting bit position to free 149 * 150 * @retval 0 Free is successful 151 * @retval -EINVAL Invalid argument (e.g. try to free more bits than 152 * the bitarray has, trying to free 0 bits, etc.) 153 * @retval -EFAULT The bits in the indicated region are not all allocated. 154 */ 155 int sys_bitarray_free(sys_bitarray_t *bitarray, size_t num_bits, 156 size_t offset); 157 158 /** 159 * Test if bits in a region is all set. 160 * 161 * This tests if the number of bits (@p num_bits) in region starting 162 * from @p offset are all set. 163 * 164 * @param bitarray Bitarray struct 165 * @param num_bits Number of bits to test 166 * @param offset Starting bit position to test 167 * 168 * @retval true All bits are set. 169 * @retval false Not all bits are set. 170 */ 171 bool sys_bitarray_is_region_set(sys_bitarray_t *bitarray, size_t num_bits, 172 size_t offset); 173 174 /** 175 * Test if bits in a region is all cleared. 176 * 177 * This tests if the number of bits (@p num_bits) in region starting 178 * from @p offset are all cleared. 179 * 180 * @param bitarray Bitarray struct 181 * @param num_bits Number of bits to test 182 * @param offset Starting bit position to test 183 * 184 * @retval true All bits are cleared. 185 * @retval false Not all bits are cleared. 186 */ 187 bool sys_bitarray_is_region_cleared(sys_bitarray_t *bitarray, size_t num_bits, 188 size_t offset); 189 190 /** 191 * Set all bits in a region. 192 * 193 * This sets the number of bits (@p num_bits) in region starting 194 * from @p offset. 195 * 196 * @param bitarray Bitarray struct 197 * @param num_bits Number of bits to test 198 * @param offset Starting bit position to test 199 * 200 * @retval 0 Operation successful 201 * @retval -EINVAL Invalid argument (e.g. bit to set exceeds 202 * the number of bits in bit array, etc.) 203 */ 204 int sys_bitarray_set_region(sys_bitarray_t *bitarray, size_t num_bits, 205 size_t offset); 206 207 /** 208 * Clear all bits in a region. 209 * 210 * This clears the number of bits (@p num_bits) in region starting 211 * from @p offset. 212 * 213 * @param bitarray Bitarray struct 214 * @param num_bits Number of bits to test 215 * @param offset Starting bit position to test 216 * 217 * @retval 0 Operation successful 218 * @retval -EINVAL Invalid argument (e.g. bit to set exceeds 219 * the number of bits in bit array, etc.) 220 */ 221 int sys_bitarray_clear_region(sys_bitarray_t *bitarray, size_t num_bits, 222 size_t offset); 223 224 #ifdef __cplusplus 225 } 226 #endif 227 228 #endif /* ZEPHYR_INCLUDE_SYS_BITARRAY_H_ */ 229