From 858e88a1d014fa6368b1952710502002f9542137 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 19 Sep 2026 08:29:11 +0000 Subject: [PATCH] Allocate dmlist_create() on the caller's own DMOD_CURRENT_ALLOCATOR dmlist_create() used to require every caller to pass its own module name explicitly. Rename the underlying Built-in API to dmlist_create_ex(module_name) and add dmlist_create() back as a macro that forwards to it with DMOD_CURRENT_ALLOCATOR (see dmod's dmod_sal.h) - the identity of whoever calls it, whether that's a module or a system-side library. This matches how Dmod_Malloc/Dmod_Free already attribute allocations, and callers that do need to attribute a list to someone other than themselves can still call dmlist_create_ex() directly. Requires dmod's DMOD_CURRENT_ALLOCATOR system-side support (see the companion dmod PR). --- Makefile | 2 +- README.md | 39 ++++++++++++++++++++++++++------------- include/dmlist.h | 18 ++++++++++++++---- src/dmlist.c | 4 ++-- tests/CMakeLists.txt | 1 + tests/test_simple.c | 2 +- 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 1af7450..8019152 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ DMOD_INC_DIRS = include\ build/_deps/dmod-build DMOD_LIBS = dmod_inc DMOD_GEN_HEADERS_IN = -DMOD_DEFINITIONS = DMLIST_VERSION_STRING="== dmlist ver. 1.0 ==\n" +DMOD_DEFINITIONS = DMLIST_VERSION_STRING="== dmlist ver. 1.0 ==\n" DMOD_CURRENT_ALLOCATOR="dmlist" # ----------------------------------------------------------------------------- # Initialization of paths diff --git a/README.md b/README.md index 687d49f..feeed09 100644 --- a/README.md +++ b/README.md @@ -255,7 +255,7 @@ All simple tests completed! int main(void) { // 1. Create a list - dmlist_context_t* list = dmlist_create("main"); + dmlist_context_t* list = dmlist_create(); if (list == NULL) { return -1; } @@ -292,7 +292,7 @@ int main(void) { #include void string_list_example(void) { - dmlist_context_t* list = dmlist_create("string_module"); + dmlist_context_t* list = dmlist_create(); // Add strings to the list dmlist_push_back(list, "Hello"); @@ -329,7 +329,7 @@ int compare_ints(const void* a, const void* b) { } void find_example(void) { - dmlist_context_t* list = dmlist_create("search_module"); + dmlist_context_t* list = dmlist_create(); // Add some values int values[] = {10, 20, 30, 40, 50}; @@ -370,7 +370,7 @@ bool sum_accumulator(void* data, void* user_data) { } void iteration_example(void) { - dmlist_context_t* list = dmlist_create("iter_module"); + dmlist_context_t* list = dmlist_create(); // Add values int values[] = {1, 2, 3, 4, 5}; @@ -399,7 +399,7 @@ void iteration_example(void) { #include void insert_example(void) { - dmlist_context_t* list = dmlist_create("insert_module"); + dmlist_context_t* list = dmlist_create(); int values[] = {1, 2, 4, 5}; @@ -435,7 +435,7 @@ int compare_strings(const void* a, const void* b) { } void remove_example(void) { - dmlist_context_t* list = dmlist_create("remove_module"); + dmlist_context_t* list = dmlist_create(); // Add elements dmlist_push_back(list, "apple"); @@ -482,7 +482,7 @@ bool print_student(void* data, void* user_data) { } void struct_example(void) { - dmlist_context_t* list = dmlist_create("student_module"); + dmlist_context_t* list = dmlist_create(); // Create students Student s1 = {"Alice", 20, 85.5}; @@ -516,15 +516,28 @@ void struct_example(void) { #### `dmlist_create` ```c -dmlist_context_t* dmlist_create(const char* module_name); +dmlist_context_t* dmlist_create(void); ``` -Create a linked list context. +Create a linked list context, attributing its allocations to the caller's own +allocator (`DMOD_CURRENT_ALLOCATOR` - see `dmod_sal.h`). This is a macro around +`dmlist_create_ex()` and is what you want in almost all cases. + +- **Returns:** Pointer to the list context, or `NULL` if creation fails +- **Note:** All memory allocations for this list will be tracked under the caller's own name + +#### `dmlist_create_ex` + +```c +dmlist_context_t* dmlist_create_ex(const char* module_name); +``` + +Create a linked list context, attributing its allocations to an explicit owner +instead of the caller. - **Parameters:** - - `module_name`: Name of the module using the list (for memory tracking) + - `module_name`: Name to track this list's memory allocations under - **Returns:** Pointer to the list context, or `NULL` if creation fails -- **Note:** All memory allocations for this list will be tracked under `module_name` #### `dmlist_destroy` @@ -806,7 +819,7 @@ int compare_priority(const void* a, const void* b) { } void task_queue_example(void) { - dmlist_context_t* queue = dmlist_create("task_queue"); + dmlist_context_t* queue = dmlist_create(); // Add tasks Task t1 = {1, "Low priority task"}; @@ -843,7 +856,7 @@ typedef struct { History* history_create(void) { History* hist = (History*)Dmod_Malloc(sizeof(History), "history"); - hist->list = dmlist_create("history"); + hist->list = dmlist_create(); hist->max_size = MAX_HISTORY; return hist; } diff --git a/include/dmlist.h b/include/dmlist.h index 542af94..71ee255 100644 --- a/include/dmlist.h +++ b/include/dmlist.h @@ -47,13 +47,23 @@ typedef bool (*dmlist_iterator_func_t)(void* data, void* user_data); typedef int (*dmlist_compare_func_t)(const void* data1, const void* data2); /** - * @brief Create a linked list context. - * + * @brief Create a linked list context, attributing its allocations to an explicit owner. + * * @param module_name Name of the module using the list (for memory tracking). - * + * * @return Pointer to the list context, or NULL if creation fails. */ -DMOD_BUILTIN_API( dmlist, 1.0, dmlist_context_t*, _create, ( const char* module_name ) ); +DMOD_BUILTIN_API( dmlist, 1.0, dmlist_context_t*, _create_ex, ( const char* module_name ) ); + +/** + * @brief Create a linked list context, allocating on the caller's own allocator. + * + * Forwards to dmlist_create_ex() with DMOD_CURRENT_ALLOCATOR (see dmod_sal.h) - the + * identity of whoever is calling this macro, not dmlist itself - so every caller's + * list nodes are tracked, and bulk-freed on unload, under the caller's own name + * rather than under "dmlist". + */ +#define dmlist_create() dmlist_create_ex( DMOD_CURRENT_ALLOCATOR ) /** * @brief Destroy a linked list and free all its nodes. diff --git a/src/dmlist.c b/src/dmlist.c index a193caa..497550f 100644 --- a/src/dmlist.c +++ b/src/dmlist.c @@ -60,11 +60,11 @@ static void free_node( dmlist_node_t* node ) } } -DMOD_INPUT_API_DECLARATION( dmlist, 1.0, dmlist_context_t*, _create, ( const char* module_name ) ) +DMOD_INPUT_API_DECLARATION( dmlist, 1.0, dmlist_context_t*, _create_ex, ( const char* module_name ) ) { if( module_name == NULL ) { - DMOD_LOG_ERROR("dmlist: _create called with NULL module_name.\n"); + DMOD_LOG_ERROR("dmlist: _create_ex called with NULL module_name.\n"); return NULL; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8c2153e..9930e83 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,6 +4,7 @@ # Create a simple test executable add_executable(test_simple test_simple.c dmod_stubs.c) +dmod_set_current_allocator(test_simple) target_link_libraries(test_simple PRIVATE dmlist dmod_system) # Add test diff --git a/tests/test_simple.c b/tests/test_simple.c index 25d98b7..2414a10 100644 --- a/tests/test_simple.c +++ b/tests/test_simple.c @@ -17,7 +17,7 @@ int main(void) { // Test 1: Create printf("Create: "); - dmlist_context_t* list = dmlist_create("test"); + dmlist_context_t* list = dmlist_create(); if(list == NULL) { TEST_FAIL(); return 1;