1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk/bit_array.h" 37 #include "spdk/bit_pool.h" 38 #include "spdk/env.h" 39 40 #include "spdk/likely.h" 41 #include "spdk/util.h" 42 43 typedef uint64_t spdk_bit_array_word; 44 #define SPDK_BIT_ARRAY_WORD_TZCNT(x) (__builtin_ctzll(x)) 45 #define SPDK_BIT_ARRAY_WORD_POPCNT(x) (__builtin_popcountll(x)) 46 #define SPDK_BIT_ARRAY_WORD_C(x) ((spdk_bit_array_word)(x)) 47 #define SPDK_BIT_ARRAY_WORD_BYTES sizeof(spdk_bit_array_word) 48 #define SPDK_BIT_ARRAY_WORD_BITS (SPDK_BIT_ARRAY_WORD_BYTES * 8) 49 #define SPDK_BIT_ARRAY_WORD_INDEX_SHIFT spdk_u32log2(SPDK_BIT_ARRAY_WORD_BITS) 50 #define SPDK_BIT_ARRAY_WORD_INDEX_MASK ((1u << SPDK_BIT_ARRAY_WORD_INDEX_SHIFT) - 1) 51 52 struct spdk_bit_array { 53 uint32_t bit_count; 54 spdk_bit_array_word words[]; 55 }; 56 57 struct spdk_bit_array * 58 spdk_bit_array_create(uint32_t num_bits) 59 { 60 struct spdk_bit_array *ba = NULL; 61 62 spdk_bit_array_resize(&ba, num_bits); 63 64 return ba; 65 } 66 67 void 68 spdk_bit_array_free(struct spdk_bit_array **bap) 69 { 70 struct spdk_bit_array *ba; 71 72 if (!bap) { 73 return; 74 } 75 76 ba = *bap; 77 *bap = NULL; 78 spdk_free(ba); 79 } 80 81 static inline uint32_t 82 bit_array_word_count(uint32_t num_bits) 83 { 84 return (num_bits + SPDK_BIT_ARRAY_WORD_BITS - 1) >> SPDK_BIT_ARRAY_WORD_INDEX_SHIFT; 85 } 86 87 static inline spdk_bit_array_word 88 bit_array_word_mask(uint32_t num_bits) 89 { 90 assert(num_bits < SPDK_BIT_ARRAY_WORD_BITS); 91 return (SPDK_BIT_ARRAY_WORD_C(1) << num_bits) - 1; 92 } 93 94 int 95 spdk_bit_array_resize(struct spdk_bit_array **bap, uint32_t num_bits) 96 { 97 struct spdk_bit_array *new_ba; 98 uint32_t old_word_count, new_word_count; 99 size_t new_size; 100 101 /* 102 * Max number of bits allowed is UINT32_MAX - 1, because we use UINT32_MAX to denote 103 * when a set or cleared bit cannot be found. 104 */ 105 if (!bap || num_bits == UINT32_MAX) { 106 return -EINVAL; 107 } 108 109 new_word_count = bit_array_word_count(num_bits); 110 new_size = offsetof(struct spdk_bit_array, words) + new_word_count * SPDK_BIT_ARRAY_WORD_BYTES; 111 112 /* 113 * Always keep one extra word with a 0 and a 1 past the actual required size so that the 114 * find_first functions can just keep going until they match. 115 */ 116 new_size += SPDK_BIT_ARRAY_WORD_BYTES; 117 118 new_ba = (struct spdk_bit_array *)spdk_realloc(*bap, new_size, 64); 119 if (!new_ba) { 120 return -ENOMEM; 121 } 122 123 /* 124 * Set up special extra word (see above comment about find_first_clear). 125 * 126 * This is set to 0b10 so that find_first_clear will find a 0 at the very first 127 * bit past the end of the buffer, and find_first_set will find a 1 at the next bit 128 * past that. 129 */ 130 new_ba->words[new_word_count] = 0x2; 131 132 if (*bap == NULL) { 133 old_word_count = 0; 134 new_ba->bit_count = 0; 135 } else { 136 old_word_count = bit_array_word_count(new_ba->bit_count); 137 } 138 139 if (new_word_count > old_word_count) { 140 /* Zero out new entries */ 141 memset(&new_ba->words[old_word_count], 0, 142 (new_word_count - old_word_count) * SPDK_BIT_ARRAY_WORD_BYTES); 143 } else if (new_word_count == old_word_count && num_bits < new_ba->bit_count) { 144 /* Make sure any existing partial last word is cleared beyond the new num_bits. */ 145 uint32_t last_word_bits; 146 spdk_bit_array_word mask; 147 148 last_word_bits = num_bits & SPDK_BIT_ARRAY_WORD_INDEX_MASK; 149 mask = bit_array_word_mask(last_word_bits); 150 new_ba->words[old_word_count - 1] &= mask; 151 } 152 153 new_ba->bit_count = num_bits; 154 *bap = new_ba; 155 return 0; 156 } 157 158 uint32_t 159 spdk_bit_array_capacity(const struct spdk_bit_array *ba) 160 { 161 return ba->bit_count; 162 } 163 164 static inline int 165 bit_array_get_word(const struct spdk_bit_array *ba, uint32_t bit_index, 166 uint32_t *word_index, uint32_t *word_bit_index) 167 { 168 if (spdk_unlikely(bit_index >= ba->bit_count)) { 169 return -EINVAL; 170 } 171 172 *word_index = bit_index >> SPDK_BIT_ARRAY_WORD_INDEX_SHIFT; 173 *word_bit_index = bit_index & SPDK_BIT_ARRAY_WORD_INDEX_MASK; 174 175 return 0; 176 } 177 178 bool 179 spdk_bit_array_get(const struct spdk_bit_array *ba, uint32_t bit_index) 180 { 181 uint32_t word_index, word_bit_index; 182 183 if (bit_array_get_word(ba, bit_index, &word_index, &word_bit_index)) { 184 return false; 185 } 186 187 return (ba->words[word_index] >> word_bit_index) & 1U; 188 } 189 190 int 191 spdk_bit_array_set(struct spdk_bit_array *ba, uint32_t bit_index) 192 { 193 uint32_t word_index, word_bit_index; 194 195 if (bit_array_get_word(ba, bit_index, &word_index, &word_bit_index)) { 196 return -EINVAL; 197 } 198 199 ba->words[word_index] |= (SPDK_BIT_ARRAY_WORD_C(1) << word_bit_index); 200 return 0; 201 } 202 203 void 204 spdk_bit_array_clear(struct spdk_bit_array *ba, uint32_t bit_index) 205 { 206 uint32_t word_index, word_bit_index; 207 208 if (bit_array_get_word(ba, bit_index, &word_index, &word_bit_index)) { 209 /* 210 * Clearing past the end of the bit array is a no-op, since bit past the end 211 * are implicitly 0. 212 */ 213 return; 214 } 215 216 ba->words[word_index] &= ~(SPDK_BIT_ARRAY_WORD_C(1) << word_bit_index); 217 } 218 219 static inline uint32_t 220 bit_array_find_first(const struct spdk_bit_array *ba, uint32_t start_bit_index, 221 spdk_bit_array_word xor_mask) 222 { 223 uint32_t word_index, first_word_bit_index; 224 spdk_bit_array_word word, first_word_mask; 225 const spdk_bit_array_word *words, *cur_word; 226 227 if (spdk_unlikely(start_bit_index >= ba->bit_count)) { 228 return ba->bit_count; 229 } 230 231 word_index = start_bit_index >> SPDK_BIT_ARRAY_WORD_INDEX_SHIFT; 232 words = ba->words; 233 cur_word = &words[word_index]; 234 235 /* 236 * Special case for first word: skip start_bit_index % SPDK_BIT_ARRAY_WORD_BITS bits 237 * within the first word. 238 */ 239 first_word_bit_index = start_bit_index & SPDK_BIT_ARRAY_WORD_INDEX_MASK; 240 first_word_mask = bit_array_word_mask(first_word_bit_index); 241 242 word = (*cur_word ^ xor_mask) & ~first_word_mask; 243 244 /* 245 * spdk_bit_array_resize() guarantees that an extra word with a 1 and a 0 will always be 246 * at the end of the words[] array, so just keep going until a word matches. 247 */ 248 while (word == 0) { 249 word = *++cur_word ^ xor_mask; 250 } 251 252 return ((uintptr_t)cur_word - (uintptr_t)words) * 8 + SPDK_BIT_ARRAY_WORD_TZCNT(word); 253 } 254 255 256 uint32_t 257 spdk_bit_array_find_first_set(const struct spdk_bit_array *ba, uint32_t start_bit_index) 258 { 259 uint32_t bit_index; 260 261 bit_index = bit_array_find_first(ba, start_bit_index, 0); 262 263 /* 264 * If we ran off the end of the array and found the 1 bit in the extra word, 265 * return UINT32_MAX to indicate no actual 1 bits were found. 266 */ 267 if (bit_index >= ba->bit_count) { 268 bit_index = UINT32_MAX; 269 } 270 271 return bit_index; 272 } 273 274 uint32_t 275 spdk_bit_array_find_first_clear(const struct spdk_bit_array *ba, uint32_t start_bit_index) 276 { 277 uint32_t bit_index; 278 279 bit_index = bit_array_find_first(ba, start_bit_index, SPDK_BIT_ARRAY_WORD_C(-1)); 280 281 /* 282 * If we ran off the end of the array and found the 0 bit in the extra word, 283 * return UINT32_MAX to indicate no actual 0 bits were found. 284 */ 285 if (bit_index >= ba->bit_count) { 286 bit_index = UINT32_MAX; 287 } 288 289 return bit_index; 290 } 291 292 uint32_t 293 spdk_bit_array_count_set(const struct spdk_bit_array *ba) 294 { 295 const spdk_bit_array_word *cur_word = ba->words; 296 uint32_t word_count = bit_array_word_count(ba->bit_count); 297 uint32_t set_count = 0; 298 299 while (word_count--) { 300 /* 301 * No special treatment is needed for the last (potentially partial) word, since 302 * spdk_bit_array_resize() makes sure the bits past bit_count are cleared. 303 */ 304 set_count += SPDK_BIT_ARRAY_WORD_POPCNT(*cur_word++); 305 } 306 307 return set_count; 308 } 309 310 uint32_t 311 spdk_bit_array_count_clear(const struct spdk_bit_array *ba) 312 { 313 return ba->bit_count - spdk_bit_array_count_set(ba); 314 } 315 316 void 317 spdk_bit_array_store_mask(const struct spdk_bit_array *ba, void *mask) 318 { 319 uint32_t size, i; 320 uint32_t num_bits = spdk_bit_array_capacity(ba); 321 322 size = num_bits / CHAR_BIT; 323 memcpy(mask, ba->words, size); 324 325 for (i = 0; i < num_bits % CHAR_BIT; i++) { 326 if (spdk_bit_array_get(ba, i + size * CHAR_BIT)) { 327 ((uint8_t *)mask)[size] |= (1U << i); 328 } else { 329 ((uint8_t *)mask)[size] &= ~(1U << i); 330 } 331 } 332 } 333 334 void 335 spdk_bit_array_load_mask(struct spdk_bit_array *ba, const void *mask) 336 { 337 uint32_t size, i; 338 uint32_t num_bits = spdk_bit_array_capacity(ba); 339 340 size = num_bits / CHAR_BIT; 341 memcpy(ba->words, mask, size); 342 343 for (i = 0; i < num_bits % CHAR_BIT; i++) { 344 if (((uint8_t *)mask)[size] & (1U << i)) { 345 spdk_bit_array_set(ba, i + size * CHAR_BIT); 346 } else { 347 spdk_bit_array_clear(ba, i + size * CHAR_BIT); 348 } 349 } 350 } 351 352 void 353 spdk_bit_array_clear_mask(struct spdk_bit_array *ba) 354 { 355 uint32_t size, i; 356 uint32_t num_bits = spdk_bit_array_capacity(ba); 357 358 size = num_bits / CHAR_BIT; 359 memset(ba->words, 0, size); 360 361 for (i = 0; i < num_bits % CHAR_BIT; i++) { 362 spdk_bit_array_clear(ba, i + size * CHAR_BIT); 363 } 364 } 365 366 struct spdk_bit_pool { 367 struct spdk_bit_array *array; 368 uint32_t lowest_free_bit; 369 uint32_t free_count; 370 }; 371 372 struct spdk_bit_pool * 373 spdk_bit_pool_create(uint32_t num_bits) 374 { 375 struct spdk_bit_pool *pool = NULL; 376 struct spdk_bit_array *array; 377 378 array = spdk_bit_array_create(num_bits); 379 if (array == NULL) { 380 return NULL; 381 } 382 383 pool = calloc(1, sizeof(*pool)); 384 if (pool == NULL) { 385 spdk_bit_array_free(&array); 386 return NULL; 387 } 388 389 pool->array = array; 390 pool->lowest_free_bit = 0; 391 pool->free_count = num_bits; 392 393 return pool; 394 } 395 396 struct spdk_bit_pool * 397 spdk_bit_pool_create_from_array(struct spdk_bit_array *array) 398 { 399 struct spdk_bit_pool *pool = NULL; 400 401 pool = calloc(1, sizeof(*pool)); 402 if (pool == NULL) { 403 return NULL; 404 } 405 406 pool->array = array; 407 pool->lowest_free_bit = spdk_bit_array_find_first_clear(array, 0); 408 pool->free_count = spdk_bit_array_count_clear(array); 409 410 return pool; 411 } 412 413 void 414 spdk_bit_pool_free(struct spdk_bit_pool **ppool) 415 { 416 struct spdk_bit_pool *pool; 417 418 if (!ppool) { 419 return; 420 } 421 422 pool = *ppool; 423 *ppool = NULL; 424 if (pool != NULL) { 425 spdk_bit_array_free(&pool->array); 426 free(pool); 427 } 428 } 429 430 int 431 spdk_bit_pool_resize(struct spdk_bit_pool **ppool, uint32_t num_bits) 432 { 433 struct spdk_bit_pool *pool; 434 int rc; 435 436 assert(ppool != NULL); 437 438 pool = *ppool; 439 rc = spdk_bit_array_resize(&pool->array, num_bits); 440 if (rc) { 441 return rc; 442 } 443 444 pool->lowest_free_bit = spdk_bit_array_find_first_clear(pool->array, 0); 445 pool->free_count = spdk_bit_array_count_clear(pool->array); 446 447 return 0; 448 } 449 450 uint32_t 451 spdk_bit_pool_capacity(const struct spdk_bit_pool *pool) 452 { 453 return spdk_bit_array_capacity(pool->array); 454 } 455 456 bool 457 spdk_bit_pool_is_allocated(const struct spdk_bit_pool *pool, uint32_t bit_index) 458 { 459 return spdk_bit_array_get(pool->array, bit_index); 460 } 461 462 uint32_t 463 spdk_bit_pool_allocate_bit(struct spdk_bit_pool *pool) 464 { 465 uint32_t bit_index = pool->lowest_free_bit; 466 467 if (bit_index == UINT32_MAX) { 468 return UINT32_MAX; 469 } 470 471 spdk_bit_array_set(pool->array, bit_index); 472 pool->lowest_free_bit = spdk_bit_array_find_first_clear(pool->array, bit_index); 473 pool->free_count--; 474 return bit_index; 475 } 476 477 void 478 spdk_bit_pool_free_bit(struct spdk_bit_pool *pool, uint32_t bit_index) 479 { 480 assert(spdk_bit_array_get(pool->array, bit_index) == true); 481 482 spdk_bit_array_clear(pool->array, bit_index); 483 if (pool->lowest_free_bit > bit_index) { 484 pool->lowest_free_bit = bit_index; 485 } 486 pool->free_count++; 487 } 488 489 uint32_t 490 spdk_bit_pool_count_allocated(const struct spdk_bit_pool *pool) 491 { 492 return spdk_bit_array_capacity(pool->array) - pool->free_count; 493 } 494 495 uint32_t 496 spdk_bit_pool_count_free(const struct spdk_bit_pool *pool) 497 { 498 return pool->free_count; 499 } 500 501 void 502 spdk_bit_pool_store_mask(const struct spdk_bit_pool *pool, void *mask) 503 { 504 spdk_bit_array_store_mask(pool->array, mask); 505 } 506 507 void 508 spdk_bit_pool_load_mask(struct spdk_bit_pool *pool, const void *mask) 509 { 510 spdk_bit_array_load_mask(pool->array, mask); 511 pool->lowest_free_bit = spdk_bit_array_find_first_clear(pool->array, 0); 512 pool->free_count = spdk_bit_array_count_clear(pool->array); 513 } 514 515 void 516 spdk_bit_pool_free_all_bits(struct spdk_bit_pool *pool) 517 { 518 spdk_bit_array_clear_mask(pool->array); 519 pool->lowest_free_bit = 0; 520 pool->free_count = spdk_bit_array_capacity(pool->array); 521 } 522