@cryptotaxi247 / netdata-1 / commits / f330cca10

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