xref: /haiku/src/libs/compat/freebsd_network/unit.cpp (revision 52f7c9389475e19fc21487b38064b4390eeb6fea)
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