57
57
#include <stdbool.h>
58
58
#include <stddef.h>
59
59
60
+ #include "base_alloc.h"
61
+ #include "base_alloc_linear.h"
60
62
#include "critnib.h"
61
63
#include "utils_common.h"
62
64
#include "utils_concurrency.h"
@@ -126,7 +128,11 @@ struct critnib {
126
128
127
129
uint64_t remove_count ;
128
130
129
- struct os_mutex_t * mutex ; /* writes/removes */
131
+ struct os_mutex_t mutex ; /* writes/removes */
132
+
133
+ umf_ba_linear_pool_t * pool_linear ;
134
+ umf_ba_pool_t * pool_nodes ;
135
+ umf_ba_pool_t * pool_leaves ;
130
136
};
131
137
132
138
/*
@@ -176,37 +182,63 @@ static inline unsigned slice_index(word key, sh_t shift) {
176
182
* critnib_new -- allocates a new critnib structure
177
183
*/
178
184
struct critnib * critnib_new (void ) {
179
- struct critnib * c = Zalloc (sizeof (struct critnib ));
180
- if (!c ) {
185
+ umf_ba_linear_pool_t * pool_linear =
186
+ umf_ba_linear_create (0 /* minimal pool size */ );
187
+ if (!pool_linear ) {
181
188
return NULL ;
182
189
}
183
190
184
- c -> mutex = util_mutex_create ();
185
- if (!c -> mutex ) {
186
- free (c );
187
- return NULL ;
191
+ struct critnib * c =
192
+ umf_ba_linear_alloc (pool_linear , sizeof (struct critnib ));
193
+ if (!c ) {
194
+ goto err_destroy_pool_linear ;
195
+ }
196
+
197
+ c -> pool_linear = pool_linear ;
198
+
199
+ void * mutex_ptr = util_mutex_init (& c -> mutex );
200
+ if (!mutex_ptr ) {
201
+ goto err_destroy_pool_linear ;
202
+ }
203
+
204
+ c -> pool_nodes = umf_ba_create (sizeof (struct critnib_node ));
205
+ if (!c -> pool_nodes ) {
206
+ goto err_util_mutex_destroy ;
207
+ }
208
+
209
+ c -> pool_leaves = umf_ba_create (sizeof (struct critnib_leaf ));
210
+ if (!c -> pool_leaves ) {
211
+ goto err_destroy_pool_nodes ;
188
212
}
189
213
190
214
VALGRIND_HG_DRD_DISABLE_CHECKING (& c -> root , sizeof (c -> root ));
191
215
VALGRIND_HG_DRD_DISABLE_CHECKING (& c -> remove_count , sizeof (c -> remove_count ));
192
216
193
217
return c ;
218
+
219
+ err_destroy_pool_nodes :
220
+ umf_ba_destroy (c -> pool_nodes );
221
+ err_util_mutex_destroy :
222
+ util_mutex_destroy_not_free (& c -> mutex );
223
+ err_destroy_pool_linear :
224
+ umf_ba_linear_destroy (pool_linear ); // free all its allocations and destroy
225
+ return NULL ;
194
226
}
195
227
196
228
/*
197
229
* internal: delete_node -- recursively free (to malloc) a subtree
198
230
*/
199
- static void delete_node (struct critnib_node * __restrict n ) {
231
+ static void delete_node (struct critnib * c , struct critnib_node * __restrict n ) {
200
232
if (is_leaf (n )) {
201
- Free ( to_leaf (n ));
233
+ umf_ba_free ( c -> pool_leaves , to_leaf (n ));
202
234
} else {
203
235
for (int i = 0 ; i < SLNODES ; i ++ ) {
204
236
if (n -> child [i ]) {
205
- delete_node (n -> child [i ]);
237
+ delete_node (c , n -> child [i ]);
206
238
}
207
239
}
208
240
209
- Free ( n );
241
+ umf_ba_free ( c -> pool_nodes , n );
210
242
}
211
243
}
212
244
@@ -215,29 +247,35 @@ static void delete_node(struct critnib_node *__restrict n) {
215
247
*/
216
248
void critnib_delete (struct critnib * c ) {
217
249
if (c -> root ) {
218
- delete_node (c -> root );
250
+ delete_node (c , c -> root );
219
251
}
220
252
221
- util_mutex_destroy (c -> mutex );
253
+ // mutex is freed in umf_ba_linear_destroy(c->pool_linear) at the end
254
+ util_mutex_destroy_not_free (& c -> mutex );
222
255
223
256
for (struct critnib_node * m = c -> deleted_node ; m ;) {
224
257
struct critnib_node * mm = m -> child [0 ];
225
- Free ( m );
258
+ umf_ba_free ( c -> pool_nodes , m );
226
259
m = mm ;
227
260
}
228
261
229
262
for (struct critnib_leaf * k = c -> deleted_leaf ; k ;) {
230
263
struct critnib_leaf * kk = k -> value ;
231
- Free ( k );
264
+ umf_ba_free ( c -> pool_leaves , k );
232
265
k = kk ;
233
266
}
234
267
235
268
for (int i = 0 ; i < DELETED_LIFE ; i ++ ) {
236
- Free ( c -> pending_del_nodes [i ]);
237
- Free ( c -> pending_del_leaves [i ]);
269
+ umf_ba_free ( c -> pool_nodes , c -> pending_del_nodes [i ]);
270
+ umf_ba_free ( c -> pool_leaves , c -> pending_del_leaves [i ]);
238
271
}
239
272
240
- Free (c );
273
+ umf_ba_destroy (c -> pool_nodes );
274
+ umf_ba_destroy (c -> pool_leaves );
275
+ umf_ba_linear_destroy (
276
+ c -> pool_linear ); // free all its allocations and destroy
277
+
278
+ // 'c' was freed in umf_ba_linear_destroy(c->pool_linear)
241
279
}
242
280
243
281
/*
@@ -264,7 +302,7 @@ static void free_node(struct critnib *__restrict c,
264
302
*/
265
303
static struct critnib_node * alloc_node (struct critnib * __restrict c ) {
266
304
if (!c -> deleted_node ) {
267
- return Malloc ( sizeof ( struct critnib_node ) );
305
+ return umf_ba_alloc ( c -> pool_nodes );
268
306
}
269
307
270
308
struct critnib_node * n = c -> deleted_node ;
@@ -295,7 +333,7 @@ static void free_leaf(struct critnib *__restrict c,
295
333
*/
296
334
static struct critnib_leaf * alloc_leaf (struct critnib * __restrict c ) {
297
335
if (!c -> deleted_leaf ) {
298
- return Malloc ( sizeof ( struct critnib_leaf ) );
336
+ return umf_ba_alloc ( c -> pool_leaves );
299
337
}
300
338
301
339
struct critnib_leaf * k = c -> deleted_leaf ;
@@ -317,11 +355,11 @@ static struct critnib_leaf *alloc_leaf(struct critnib *__restrict c) {
317
355
* Takes a global write lock but doesn't stall any readers.
318
356
*/
319
357
int critnib_insert (struct critnib * c , word key , void * value , int update ) {
320
- util_mutex_lock (c -> mutex );
358
+ util_mutex_lock (& c -> mutex );
321
359
322
360
struct critnib_leaf * k = alloc_leaf (c );
323
361
if (!k ) {
324
- util_mutex_unlock (c -> mutex );
362
+ util_mutex_unlock (& c -> mutex );
325
363
326
364
return ENOMEM ;
327
365
}
@@ -337,7 +375,7 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
337
375
if (!n ) {
338
376
c -> root = kn ;
339
377
340
- util_mutex_unlock (c -> mutex );
378
+ util_mutex_unlock (& c -> mutex );
341
379
342
380
return 0 ;
343
381
}
@@ -355,7 +393,7 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
355
393
n = prev ;
356
394
store (& n -> child [slice_index (key , n -> shift )], kn );
357
395
358
- util_mutex_unlock (c -> mutex );
396
+ util_mutex_unlock (& c -> mutex );
359
397
360
398
return 0 ;
361
399
}
@@ -369,10 +407,10 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
369
407
370
408
if (update ) {
371
409
to_leaf (n )-> value = value ;
372
- util_mutex_unlock (c -> mutex );
410
+ util_mutex_unlock (& c -> mutex );
373
411
return 0 ;
374
412
} else {
375
- util_mutex_unlock (c -> mutex );
413
+ util_mutex_unlock (& c -> mutex );
376
414
return EEXIST ;
377
415
}
378
416
}
@@ -384,7 +422,7 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
384
422
if (!m ) {
385
423
free_leaf (c , to_leaf (kn ));
386
424
387
- util_mutex_unlock (c -> mutex );
425
+ util_mutex_unlock (& c -> mutex );
388
426
389
427
return ENOMEM ;
390
428
}
@@ -400,7 +438,7 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
400
438
m -> path = key & path_mask (sh );
401
439
store (parent , m );
402
440
403
- util_mutex_unlock (c -> mutex );
441
+ util_mutex_unlock (& c -> mutex );
404
442
405
443
return 0 ;
406
444
}
@@ -412,7 +450,7 @@ void *critnib_remove(struct critnib *c, word key) {
412
450
struct critnib_leaf * k ;
413
451
void * value = NULL ;
414
452
415
- util_mutex_lock (c -> mutex );
453
+ util_mutex_lock (& c -> mutex );
416
454
417
455
struct critnib_node * n = c -> root ;
418
456
if (!n ) {
@@ -482,7 +520,7 @@ void *critnib_remove(struct critnib *c, word key) {
482
520
c -> pending_del_leaves [del ] = k ;
483
521
484
522
not_found :
485
- util_mutex_unlock (c -> mutex );
523
+ util_mutex_unlock (& c -> mutex );
486
524
return value ;
487
525
}
488
526
@@ -805,9 +843,9 @@ static int iter(struct critnib_node *__restrict n, word min, word max,
805
843
void critnib_iter (critnib * c , uintptr_t min , uintptr_t max ,
806
844
int (* func )(uintptr_t key , void * value , void * privdata ),
807
845
void * privdata ) {
808
- util_mutex_lock (c -> mutex );
846
+ util_mutex_lock (& c -> mutex );
809
847
if (c -> root ) {
810
848
iter (c -> root , min , max , func , privdata );
811
849
}
812
- util_mutex_unlock (c -> mutex );
850
+ util_mutex_unlock (& c -> mutex );
813
851
}
0 commit comments