diff --git a/src/rvprof_memory.c b/src/rvprof_memory.c index 5ff015a..58b11e0 100644 --- a/src/rvprof_memory.c +++ b/src/rvprof_memory.c @@ -114,3 +114,88 @@ IMPLEMENT_DYNAMIC_ARRAY(function_stats_t, function_stats, INITIAL_FUNCTIONS, cle IMPLEMENT_DYNAMIC_ARRAY(stack_info_t, stack_info, INITIAL_STACKS, cleanup_stack_info) + +// SPECIALIZED ARRAY OPERATIONS +// maybe also move to macros to remove reduncancies later + +int rvprof_memory_add_stack_id_to_function(int func_id, int stack_id) { + if (func_id < 0 || func_id >= g_rvprof.functions.size || stack_id < 0) { + return RVPROF_ERROR_INVALID_STATE; + } + + function_stats_t* stats = &g_rvprof.functions.data[func_id]; + + for (int i = 0; i < stats->num_stack_ids; i++) { + if (stats->stack_ids[i] == stack_id) { + return RVPROF_SUCCESS; // already exists + } + } + + // ensure capacity for new stack ID + if (stats->num_stack_ids >= stats->max_stack_ids) { + int new_size = stats->max_stack_ids == 0 ? 4 : stats->max_stack_ids * 2; + size_t old_size = stats->max_stack_ids * sizeof(int); + size_t new_size_bytes = new_size * sizeof(int); + int* new_stack_ids = rvprof_realloc(stats->stack_ids, old_size, new_size_bytes); + if (!new_stack_ids) { + return RVPROF_ERROR_MEMORY; + } + stats->stack_ids = new_stack_ids; + stats->max_stack_ids = new_size; + } + + // add new stack ID + stats->stack_ids[stats->num_stack_ids] = stack_id; + stats->num_stack_ids++; + + return RVPROF_SUCCESS; +} + +int rvprof_memory_add_caller_to_function(int func_id, const char* caller) { + if (func_id < 0 || func_id >= g_rvprof.functions.size || !caller) { + return RVPROF_ERROR_INVALID_STATE; + } + + function_stats_t* stats = &g_rvprof.functions.data[func_id]; + + for (int i = 0; i < stats->num_callers; i++) { + if (strcmp(stats->callers[i], caller) == 0) { + return RVPROF_SUCCESS; // already exists + } + } + + // ensure capacity for new caller + if (stats->num_callers >= stats->max_callers) { + int new_size = stats->max_callers == 0 ? 4 : stats->max_callers * 2; + size_t old_size = stats->max_callers * sizeof(char*); + size_t new_size_bytes = new_size * sizeof(char*); + char** new_callers = rvprof_realloc(stats->callers, old_size, new_size_bytes); + if (!new_callers) { + return RVPROF_ERROR_MEMORY; + } + stats->callers = new_callers; + stats->max_callers = new_size; + } + + char* caller_copy = rvprof_malloc(strlen(caller) + 1); + if (!caller_copy) { + return RVPROF_ERROR_MEMORY; + } + strcpy(caller_copy, caller); + + stats->callers[stats->num_callers] = caller_copy; + stats->num_callers++; + + // update the caller field based on number of callers + if (stats->num_callers == 1) { + // only one caller: use it + strncpy(stats->caller, caller, MAX_NAME_LEN - 1); + stats->caller[MAX_NAME_LEN - 1] = '\0'; + } else { + // multiple callers: use "various" + strncpy(stats->caller, "various", MAX_NAME_LEN - 1); + stats->caller[MAX_NAME_LEN - 1] = '\0'; + } + + return RVPROF_SUCCESS; +} \ No newline at end of file