implement a C++'ish destructor - free callback for each item in array

This commit is contained in:
mykola2312 2024-09-01 18:38:37 +03:00
parent 3f4745d440
commit 27fc37d6cf
2 changed files with 31 additions and 12 deletions

View file

@ -690,15 +690,24 @@ typedef struct {
void* items; void* items;
unsigned count; unsigned count;
} __mlist_proto_t; } __mlist_proto_t;
typedef void (*__mlist_callback_t)(__mlist_proto_t*);
#define __MLIST_LIST_SIZEOF sizeof(__mlist_proto_t) #define __MLIST_LIST_SIZEOF sizeof(__mlist_proto_t)
#define __MLIST_ITEM_SIZE(list_type) __MLIST_##list_type##_ITEM_SIZE #define __MLIST_ITEM_SIZE(list_type) __MLIST_##list_type##_ITEM_SIZE
#define __MLIST_ITEM_CALLBACK_TYPE(list_type) __MLIST_##list_type##_ITEM_CALLBACK_TYPE
#define __MLIST_ITEM_CALLBACK(list_type) __MLIST_##list_type##_ITEM_CALLBACK
// declare typedef struct with name "list_type" that would have field // declare typedef struct with name "list_type" that would have field
// item pointer of type "item_type" and name "item_name" with count field // item pointer of type "item_type" and name "item_name" with count field
// of name "count_name". For example: // of name "count_name". For example:
// MLIST_DECLARE(procstat_modules_t, procstat_module_t, modules, module_count); // MLIST_DECLARE(procstat_modules_t, procstat_module_t, modules, module_count, NULL);
#define MLIST_DECLARE(list_type, item_type, item_name, count_name) \ // if "item_callback" is non-null, it would be called on each item before
// freeing item array
#define MLIST_DECLARE(list_type, item_type, item_name, count_name, item_callback) \
static const unsigned __MLIST_ITEM_SIZE(list_type) = sizeof(item_type); \ static const unsigned __MLIST_ITEM_SIZE(list_type) = sizeof(item_type); \
typedef void (*__MLIST_ITEM_CALLBACK_TYPE(list_type))(item_type*); \
__MLIST_ITEM_CALLBACK_TYPE(list_type) __MLIST_ITEM_CALLBACK(list_type) = item_callback; \
typedef struct { \ typedef struct { \
item_type* item_name; \ item_type* item_name; \
unsigned count; \ unsigned count; \
@ -718,14 +727,26 @@ typedef struct {
} }
// calculate address for last item, useful right after MLIST_ADD. You should // calculate address for last item, useful right after MLIST_ADD. You should
// cast it to your item_type // cast it to your item_type
#define MLIST_AT(list_type, list, idx) \
((uint8_t*)((__mlist_proto_t*)list)->items + (idx) * __MLIST_ITEM_SIZE(list_type))
#define MLIST_LAST(list_type, list) \ #define MLIST_LAST(list_type, list) \
((uint8_t*)((__mlist_proto_t*)list)->items \ MLIST_AT(list_type, list, (((__mlist_proto_t*)list)->count - 1))
+ (((__mlist_proto_t*)list)->count - 1) * __MLIST_ITEM_SIZE(list_type))
// free mlist structure with item array (if any allocated) // free mlist structure with item array (if any allocated)
#define MLIST_FREE(list) \ #define MLIST_FREE(list_type, list) \
{ \ { \
__mlist_proto_t* l = (__mlist_proto_t*)list; \ __mlist_proto_t* l = (__mlist_proto_t*)list; \
if (l->items) free(l->items); \ if (l->items) \
{ \
if (__MLIST_ITEM_CALLBACK(list_type)) \
{ \
for (unsigned i = 0; i < l->count; i++) \
{ \
((__mlist_callback_t)__MLIST_ITEM_CALLBACK( \
list_type))((__mlist_proto_t*)MLIST_AT(list_type, list, i)); \
} \
} \
free(l->items); \
} \
free(l); \ free(l); \
} }

View file

@ -3,6 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <blackjack/mlist.h>
typedef enum { typedef enum {
UNINTERRUPTABLE_SLEEP = 'D', UNINTERRUPTABLE_SLEEP = 'D',
@ -89,10 +90,7 @@ typedef struct {
unsigned map_count; unsigned map_count;
} procstat_module_t; } procstat_module_t;
typedef struct { MLIST_DECLARE(procstat_modules_t, procstat_module_t, modules, module_count);
procstat_module_t* modules;
unsigned module_count;
} procstat_modules_t;
// analyze file mappings and parse them into modules // analyze file mappings and parse them into modules
// that way, we can figure where libc.so.6 loaded in memory // that way, we can figure where libc.so.6 loaded in memory