1/* 2 * Copyright 2009 Colin G��nther, coling@gmx.de 3 * Copyright 2018, Haiku, Inc. 4 * All rights reserved. Distributed under the terms of the MIT license. 5 */ 6 7 8/*! Implementation of a number allocator.*/ 9 10 11extern "C" { 12#include <sys/mutex.h> 13 14#include "unit.h" 15} 16 17#include <stdlib.h> 18#include <util/RadixBitmap.h> 19 20 21#define ID_STORE_FULL -1 22 23 24extern struct mtx gIdStoreLock; 25 26 27struct unrhdr* 28new_unrhdr(int low, int high, struct mtx* mutex) 29{ 30 struct unrhdr* idStore; 31 uint32 maxIdCount = high - low + 1; 32 33 KASSERT(low <= high, 34 ("ID-Store: use error: %s(%u, %u)", __func__, low, high)); 35 36 idStore = (unrhdr*)malloc(sizeof *idStore); 37 if (idStore == NULL) 38 return NULL; 39 40 idStore->idBuffer = radix_bitmap_create(maxIdCount); 41 if (idStore->idBuffer == NULL) { 42 free(idStore); 43 return NULL; 44 } 45 46 if (mutex) 47 idStore->storeMutex = mutex; 48 else 49 idStore->storeMutex = &gIdStoreLock; 50 51 idStore->idBias = low; 52 53 return idStore; 54} 55 56 57void 58delete_unrhdr(struct unrhdr* idStore) 59{ 60 KASSERT(idStore != NULL, 61 ("ID-Store: %s: NULL pointer as argument.", __func__)); 62 63 mtx_lock(idStore->storeMutex); 64 65 radix_bitmap_destroy(idStore->idBuffer); 66 mtx_unlock(idStore->storeMutex); 67 68 free(idStore); 69 idStore = NULL; 70} 71 72 73int 74alloc_unr(struct unrhdr* idStore) 75{ 76 int id; 77 78 KASSERT(idStore != NULL, 79 ("ID-Store: %s: NULL pointer as argument.", __func__)); 80 81 mtx_lock(idStore->storeMutex); 82 83 radix_slot_t slotIndex; 84 id = ID_STORE_FULL; 85 86 slotIndex = radix_bitmap_alloc(idStore->idBuffer, 1); 87 if (slotIndex != RADIX_SLOT_NONE) 88 id = slotIndex + idStore->idBias; 89 90 mtx_unlock(idStore->storeMutex); 91 92 return id; 93} 94 95 96void 97free_unr(struct unrhdr* idStore, u_int identity) 98{ 99 KASSERT(idStore != NULL, 100 ("ID-Store: %s: NULL pointer as argument.", __func__)); 101 102 mtx_lock(idStore->storeMutex); 103 104 uint32 slotIndex = (int32)identity - idStore->idBias; 105 KASSERT(slotIndex >= 0, ("ID-Store: %s(%p, %u): second " 106 "parameter is not in interval.", __func__, idStore, identity)); 107 108 radix_bitmap_dealloc(idStore->idBuffer, slotIndex, 1); 109 110 mtx_unlock(idStore->storeMutex); 111} 112