#include #include #include #include #include #include #include bool id_alloc_init (struct id_alloc* ida, size_t nbits) { size_t buffer_size = (nbits + 7) / 8; uint8_t* buffer = malloc (buffer_size); if (buffer == NULL) return false; bm_init (&ida->bm, buffer, nbits); ida->lock = SPIN_LOCK_INIT; return true; } void id_alloc_fini (struct id_alloc* ida) { free (ida->bm.base); ida->bm.base = NULL; ida->bm.nbits = 0; } int id_alloc (struct id_alloc* ida) { uint64_t fid; spin_lock (&ida->lock, &fid); size_t start = ida->next_id; size_t current = start; do { if (!bm_test (&ida->bm, current)) { bm_set (&ida->bm, current); ida->next_id = (current + 1) % ida->bm.nbits; spin_unlock (&ida->lock, fid); return (int)current; } current = (current + 1) % ida->bm.nbits; } while (current != start); spin_unlock (&ida->lock, fid); return -ST_OOM_ERROR; } void id_free (struct id_alloc* ida, int id) { uint64_t fid; if (id < 0) return; spin_lock (&ida->lock, &fid); bm_clear (&ida->bm, (size_t)id); spin_unlock (&ida->lock, fid); }