ARAL: add destroy function and optimize ifdefs (#14121)
Costa Tsaousis committed
Dec 9, 2022 at 18:57 UTC
f330cca1077846e987edb0e29df3afc51df1c6cd
2 files changed
+77
-57
libnetdata/arrayalloc/arrayalloc.c
+62
-49
@@ -2,6 +2,14 @@
2
#include "arrayalloc.h"
3
#include "daemon/common.h"
4
5
+#ifdef NETDATA_TRACE_ALLOCATIONS
6
+#define TRACE_ALLOCATIONS_FUNCTION_DEFINITION_PARAMS , const char *file, const char *function, size_t line
7
+#define TRACE_ALLOCATIONS_FUNCTION_CALL_PARAMS , file, function, line
8
+#else
9
+#define TRACE_ALLOCATIONS_FUNCTION_DEFINITION_PARAMS
10
+#define TRACE_ALLOCATIONS_FUNCTION_CALL_PARAMS
11
+#endif
12
+
13
// max file size
14
#define ARAL_MAX_PAGE_SIZE_MMAP (1*1024*1024*1024)
15
@@ -38,7 +46,7 @@ static void arrayalloc_delete_leftover_files(const char *path, const char *requi
46
DIR *dir = opendir(path);
47
if(!dir) return;
48
41
- char fullpath[FILENAME_MAX + 1];
49
+ char full_path[FILENAME_MAX + 1];
50
size_t len = strlen(required_prefix);
51
52
struct dirent *de = NULL;
@@ -49,10 +57,10 @@ static void arrayalloc_delete_leftover_files(const char *path, const char *requi
57
if(strncmp(de->d_name, required_prefix, len) != 0)
58
continue;
59
52
- snprintfz(fullpath, FILENAME_MAX, "%s/%s", path, de->d_name);
53
- info("ARRAYALLOC: removing left-over file '%s'", fullpath);
54
- if(unlikely(unlink(fullpath) == -1))
55
- error("Cannot delete file '%s'", fullpath);
60
+ snprintfz(full_path, FILENAME_MAX, "%s/%s", path, de->d_name);
61
+ info("ARRAYALLOC: removing left-over file '%s'", full_path);
62
+ if(unlikely(unlink(full_path) == -1))
63
+ error("Cannot delete file '%s'", full_path);
64
}
65
66
closedir(dir);
@@ -66,7 +74,7 @@ static void arrayalloc_init(ARAL *ar) {
74
netdata_mutex_lock(&mutex);
75
76
if(!ar->internal.initialized) {
69
- netdata_mutex_init(&ar->internal.mutex);
77
+ netdata_spinlock_init(&ar->internal.spinlock);
78
79
long int page_size = sysconf(_SC_PAGE_SIZE);
80
if (unlikely(page_size == -1))
@@ -167,7 +175,7 @@ static inline ARAL_PAGE *find_page_with_allocation_internal_check(ARAL *ar, void
175
// ----------------------------------------------------------------------------
176
// find a page with a free slot (there shouldn't be any)
177
170
-#ifdef NETDATA_INTERNAL_CHECKS
178
+#ifdef NETDATA_ARRAYALLOC_INTERNAL_CHECKS
179
static inline ARAL_PAGE *find_page_with_free_slots_internal_check(ARAL *ar) {
180
ARAL_PAGE *page;
181
@@ -186,11 +194,7 @@ static inline ARAL_PAGE *find_page_with_free_slots_internal_check(ARAL *ar) {
194
}
195
#endif
196
189
-#ifdef NETDATA_TRACE_ALLOCATIONS
190
-static void arrayalloc_add_page(ARAL *ar, const char *file, const char *function, size_t line) {
191
-#else
192
-static void arrayalloc_add_page(ARAL *ar) {
193
-#endif
197
+static void arrayalloc_add_page(ARAL *ar TRACE_ALLOCATIONS_FUNCTION_DEFINITION_PARAMS) {
198
if(unlikely(!ar->internal.initialized))
199
arrayalloc_init(ar);
200
@@ -212,7 +216,7 @@ static void arrayalloc_add_page(ARAL *ar) {
216
}
217
else {
218
#ifdef NETDATA_TRACE_ALLOCATIONS
215
- page->data = mallocz_int(page->size, file, function, line);
219
+ page->data = mallocz_int(page->size TRACE_ALLOCATIONS_FUNCTION_CALL_PARAMS);
220
#else
221
page->data = mallocz(page->size);
222
#endif
@@ -233,43 +237,72 @@ static void arrayalloc_add_page(ARAL *ar) {
237
238
static void arrayalloc_lock(ARAL *ar) {
239
if(!ar->internal.lockless)
236
- netdata_mutex_lock(&ar->internal.mutex);
240
+ netdata_spinlock_lock(&ar->internal.spinlock);
241
}
242
243
static void arrayalloc_unlock(ARAL *ar) {
244
if(!ar->internal.lockless)
241
- netdata_mutex_unlock(&ar->internal.mutex);
245
+ netdata_spinlock_unlock(&ar->internal.spinlock);
246
}
247
244
-ARAL *arrayalloc_create(size_t element_size, size_t elements, const char *filename, char **cache_dir, bool mmap) {
248
+ARAL *arrayalloc_create(size_t element_size, size_t elements, const char *filename, char **cache_dir, bool mmap, bool lockless) {
249
ARAL *ar = callocz(1, sizeof(ARAL));
250
ar->requested_element_size = element_size;
251
ar->initial_elements = elements;
252
ar->filename = filename;
253
ar->cache_dir = cache_dir;
254
ar->use_mmap = mmap;
255
+ ar->internal.lockless = lockless;
256
return ar;
257
}
258
259
+void arrayalloc_del_page(ARAL *ar, ARAL_PAGE *page TRACE_ALLOCATIONS_FUNCTION_DEFINITION_PARAMS) {
260
+
261
+ DOUBLE_LINKED_LIST_REMOVE_UNSAFE(ar->internal.pages, page, prev, next);
262
+
263
+ // free it
264
+ if (ar->internal.mmap) {
265
+ netdata_munmap(page->data, page->size);
266
+
267
+ if (unlikely(unlink(page->filename) == 1))
268
+ error("Cannot delete file '%s'", page->filename);
269
+
270
+ freez((void *)page->filename);
271
+ }
272
+ else {
273
#ifdef NETDATA_TRACE_ALLOCATIONS
255
-void *arrayalloc_mallocz_int(ARAL *ar, const char *file, const char *function, size_t line) {
274
+ freez_int(page->data TRACE_ALLOCATIONS_FUNCTION_CALL_PARAMS);
275
#else
257
-void *arrayalloc_mallocz(ARAL *ar) {
276
+ freez(page->data);
277
#endif
278
+ }
279
+
280
+ freez(page);
281
+}
282
+
283
+void arrayalloc_destroy_internal(ARAL *ar TRACE_ALLOCATIONS_FUNCTION_DEFINITION_PARAMS) {
284
+ arrayalloc_lock(ar);
285
+
286
+ while(ar->internal.pages)
287
+ arrayalloc_del_page(ar, ar->internal.pages TRACE_ALLOCATIONS_FUNCTION_CALL_PARAMS);
288
+
289
+ arrayalloc_unlock(ar);
290
+ freez(ar);
291
+}
292
+
293
+void *arrayalloc_mallocz_internal(ARAL *ar TRACE_ALLOCATIONS_FUNCTION_DEFINITION_PARAMS) {
294
+
295
if(unlikely(!ar->internal.initialized))
296
arrayalloc_init(ar);
297
298
arrayalloc_lock(ar);
299
300
if(unlikely(!ar->internal.pages || !ar->internal.pages->free_list)) {
301
+#ifdef NETDATA_ARRAYALLOC_INTERNAL_CHECKS
302
internal_fatal(find_page_with_free_slots_internal_check(ar) != NULL,
303
"ARRAYALLOC: first page does not have any free slots, but there is another that has!");
267
-
268
-#ifdef NETDATA_TRACE_ALLOCATIONS
269
- arrayalloc_add_page(ar, file, function, line);
270
-#else
271
- arrayalloc_add_page(ar);
304
#endif
305
+ arrayalloc_add_page(ar TRACE_ALLOCATIONS_FUNCTION_CALL_PARAMS);
306
}
307
308
ARAL_PAGE *page = ar->internal.pages;
@@ -321,11 +354,8 @@ void *arrayalloc_mallocz(ARAL *ar) {
354
return (void *)found_fr;
355
}
356
324
-#ifdef NETDATA_TRACE_ALLOCATIONS
325
-void arrayalloc_freez_int(ARAL *ar, void *ptr, const char *file, const char *function, size_t line) {
326
-#else
327
-void arrayalloc_freez(ARAL *ar, void *ptr) {
328
-#endif
357
+void arrayalloc_freez_internal(ARAL *ar, void *ptr TRACE_ALLOCATIONS_FUNCTION_DEFINITION_PARAMS) {
358
+
359
if(unlikely(!ptr)) return;
360
arrayalloc_lock(ar);
361
@@ -373,26 +403,9 @@ void arrayalloc_freez(ARAL *ar, void *ptr) {
403
page->free_list = fr;
404
405
// if the page is empty, release it
376
- if(!page->used_elements) {
377
- DOUBLE_LINKED_LIST_REMOVE_UNSAFE(ar->internal.pages, page, prev, next);
378
-
379
- // free it
380
- if(ar->internal.mmap) {
381
- netdata_munmap(page->data, page->size);
382
- if (unlikely(unlink(page->filename) == 1))
383
- error("Cannot delete file '%s'", page->filename);
384
- freez((void *)page->filename);
385
- }
386
- else {
387
-#ifdef NETDATA_TRACE_ALLOCATIONS
388
- freez_int(page->data, file, function, line);
389
-#else
390
- freez(page->data);
391
-#endif
392
- }
406
+ if(!page->used_elements)
407
+ arrayalloc_del_page(ar, page TRACE_ALLOCATIONS_FUNCTION_CALL_PARAMS);
408
394
- freez(page);
395
- }
409
else if(page != ar->internal.pages) {
410
// move the page with free item first
411
// so that the next allocation will use this page
@@ -405,7 +418,7 @@ void arrayalloc_freez(ARAL *ar, void *ptr) {
418
419
int aral_unittest(size_t elements) {
420
char *cache_dir = "/tmp/";
408
- ARAL *ar = arrayalloc_create(20, 10, "test-aral", &cache_dir, false);
421
+ ARAL *ar = arrayalloc_create(20, 10, "test-aral", &cache_dir, false, false);
422
423
void *pointers[elements];
424
@@ -442,7 +455,7 @@ int aral_unittest(size_t elements) {
455
return 1;
456
}
457
445
- size_t ops = 0;
458
+ size_t ops = 0; (void)ops;
459
size_t increment = elements / 10;
460
size_t allocated = 0;
461
for(size_t all = increment; all <= elements ; all += increment) {
libnetdata/arrayalloc/arrayalloc.h
+15
-8
@@ -22,26 +22,33 @@ typedef struct arrayalloc {
22
size_t natural_page_size;
23
size_t allocation_multiplier;
24
size_t max_alloc_size;
25
- netdata_mutex_t mutex;
25
+ SPINLOCK spinlock;
26
struct arrayalloc_page *pages;
27
} internal;
28
} ARAL;
29
30
-ARAL *arrayalloc_create(size_t element_size, size_t elements, const char *filename, char **cache_dir, bool mmap);
30
+ARAL *arrayalloc_create(size_t element_size, size_t elements, const char *filename, char **cache_dir, bool mmap, bool lockless);
31
int aral_unittest(size_t elements);
32
33
#ifdef NETDATA_TRACE_ALLOCATIONS
34
35
-#define arrayalloc_mallocz(ar) arrayalloc_mallocz_int(ar, __FILE__, __FUNCTION__, __LINE__)
36
-#define arrayalloc_freez(ar, ptr) arrayalloc_freez_int(ar, ptr, __FILE__, __FUNCTION__, __LINE__)
35
+#define arrayalloc_mallocz(ar) arrayalloc_mallocz_internal(ar, __FILE__, __FUNCTION__, __LINE__)
36
+#define arrayalloc_freez(ar, ptr) arrayalloc_freez_internal(ar, ptr, __FILE__, __FUNCTION__, __LINE__)
37
+#define arrayalloc_destroy(ar) arrayalloc_destroy_internal(ar, __FILE__, __FUNCTION__, __LINE__)
38
38
-void *arrayalloc_mallocz_int(ARAL *ar, const char *file, const char *function, size_t line);
39
-void arrayalloc_freez_int(ARAL *ar, void *ptr, const char *file, const char *function, size_t line);
39
+void *arrayalloc_mallocz_internal(ARAL *ar, const char *file, const char *function, size_t line);
40
+void arrayalloc_freez_internal(ARAL *ar, void *ptr, const char *file, const char *function, size_t line);
41
+void arrayalloc_destroy_internal(ARAL *ar, const char *file, const char *function, size_t line);
42
43
#else // NETDATA_TRACE_ALLOCATIONS
44
43
-void *arrayalloc_mallocz(ARAL *ar);
44
-void arrayalloc_freez(ARAL *ar, void *ptr);
45
+#define arrayalloc_mallocz(ar) arrayalloc_mallocz_internal(ar)
46
+#define arrayalloc_freez(ar, ptr) arrayalloc_freez_internal(ar, ptr)
47
+#define arrayalloc_destroy(ar) arrayalloc_destroy_internal(ar)
48
+
49
+void *arrayalloc_mallocz_internal(ARAL *ar);
50
+void arrayalloc_freez_internal(ARAL *ar, void *ptr);
51
+void arrayalloc_destroy_internal(ARAL *ar);
52
53
#endif // NETDATA_TRACE_ALLOCATIONS
54