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 "unit.h" 13 } 14 15 #include <compat/sys/mutex.h> 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 KASSERT(idStore->idBuffer->root_size == 0, 66 ("ID-Store: %s: some ids are still in use..", __func__)); 67 68 radix_bitmap_destroy(idStore->idBuffer); 69 mtx_unlock(idStore->storeMutex); 70 71 free(idStore); 72 idStore = NULL; 73 } 74 75 76 int 77 alloc_unr(struct unrhdr* idStore) 78 { 79 int id; 80 81 KASSERT(idStore != NULL, 82 ("ID-Store: %s: NULL pointer as argument.", __func__)); 83 84 mtx_lock(idStore->storeMutex); 85 86 radix_slot_t slotIndex; 87 id = ID_STORE_FULL; 88 89 slotIndex = radix_bitmap_alloc(idStore->idBuffer, 1); 90 if (slotIndex != RADIX_SLOT_NONE) 91 id = slotIndex + idStore->idBias; 92 93 mtx_unlock(idStore->storeMutex); 94 95 return id; 96 } 97 98 99 void 100 free_unr(struct unrhdr* idStore, u_int identity) 101 { 102 KASSERT(idStore != NULL, 103 ("ID-Store: %s: NULL pointer as argument.", __func__)); 104 105 mtx_lock(idStore->storeMutex); 106 107 uint32 slotIndex = (int32)identity - idStore->idBias; 108 KASSERT(slotIndex >= 0, ("ID-Store: %s(%p, %u): second " 109 "parameter is not in interval.", __func__, idStore, identity)); 110 111 radix_bitmap_dealloc(idStore->idBuffer, slotIndex, 1); 112 113 mtx_unlock(idStore->storeMutex); 114 } 115