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