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 11 extern "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 24 extern struct mtx gIdStoreLock; 25 26 27 struct unrhdr* 28 new_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 57 void 58 delete_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 73 int 74 alloc_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 96 void 97 free_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