diff --git a/src/rvprof_memory.c b/src/rvprof_memory.c index 23e38dc..8a58553 100644 --- a/src/rvprof_memory.c +++ b/src/rvprof_memory.c @@ -1,2 +1,56 @@ #include "rvprof_internal.h" +// custom malloc, realloc and free help us tracking the memory footprint of rvprof + +void* rvprof_malloc(size_t size){ + void* ptr = malloc(size); + if (ptr) g_rvprof.total_memory_allocated += size; + return ptr; +} + +void* rvprof_realloc(void* ptr, size_t old_size, size_t new_size){ + void* new_ptr = realloc(ptr, new_size); + if (new_ptr) g_rvprof.total_memory_allocated += (new_size - old_size); + return new_ptr; +} + +void rvprof_free(void* ptr, size_t size){ + if(ptr){ + free(ptr); + g_rvprof.total_memory_allocated -= size; + } +} + +// DYNAMIC ARRAY MANAGEMENT + +// used for cleanup callbacks +typedef void* (*cleanup_item_fn_t)(void* item); + +// generic ensure_capacity implementation, independent of actual array type +// maybe if switching to C++ in the future, we may move from pre-processor magic to templates +#define IMPLEMENT_ARRAY_ENSURE_CAPACITY(type, name, initial_size) \ +int name##_array_ensure_capacity(name##_array_t* arr, int needed){ \ + if (needed >= arr-> capacity){ \ + int new_capacity; \ + if (arr->capacity == 0){ \ + new_capacity = initial_size; \ + } else { \ + new_capacity = arr->capacity; \ + } \ + \ + while (new_capacity <= needed){ \ + new_capacity *= GROWTH_FACTOR; \ + } \ + \ + size_t old_size = arr->capacity * sizeof(type); \ + size_t new_size = new_capacity * sizeof(type); \ + type* new_data = rvprof_realloc(arr->data, old_size, new_size); \ + if(!new_data){ \ + return RVPROF_ERROR_MEMORY; \ + }\ + \ + arr->data = new_data; \ + arr->capacity = new_capacity; \ + }\ + return RVPROF_SUCCESS;\ +}\