#include "rvprof_internal.h" static void rvprof_atexit_handler(void){ if(g_rvprof.initialized) rvprof_context_cleanup(); } static void register_atexit_handler(void){ static int registered = 0; if (!registered){ atexit(rvprof_atexit_handler); registered = 1; } } void rvprof_init(const char* output_file){ if (g_rvprof.initialized) return; // enable usage of cygnus hooks, disable with RVPROF_DISABLE_HOOKS env variable g_rvprof.config.enable_hooks = 1; // merge regions of same names in output, disable with RVPROF_DISABLE_MERGE env variable g_rvprof.config.merge_regions =1; // set output file name, auto-detected, override with RVPROF_OUTPUT env variable g_rvprof.config.output_filename = NULL; // set program name, auto-detected g_rvprof.config.program_name = NULL; char* disable_hooks = getenv("RVPROF_DISABLE_HOOKS"); if (disable_hooks && strcmp(disable_hooks, "1") == 0){ g_rvprof.config.enable_hooks = 0; } char* disable_merge = getenv("RVPROF_DISABLE_MERGE"); if (disable_merge && strcmp(disable_merge, "1") == 0){ g_rvprof.config.merge_regions = 0; } char* env_output = getenv("RVPROF_OUTPUT"); const char* filename; // determine output filename if (output_file && strlen(output_file) > 0){ filename = output_file; } else if (env_output && strlen(env_output) > 0){ filename = env_output; } else { filename = rvprof_utils_generate_output_filename(); } g_rvprof.output_file = fopen(filename, "w"); if(!g_rvprof.output_file) return; rvprof_error_t timing_result = rvprof_timing_init(); if (timing_result != RVPROF_SUCCESS) return; rvprof_symbols_init(g_rvprof.config.program_name); // in case symbol resolution fails, just addresses are printed later // rest of global state g_rvprof.stack_ptr = -1; g_rvprof.initialized = 1; g_rvprof.auto_initialized = 0; g_rvprof.total_program_time = 0; g_rvprof.total_program_cycles = 0; g_rvprof.total_memory_allocated = 0; // initialize dynamic arrays with zeros memset(&g_rvprof.regions, 0, sizeof(g_rvprof.regions)); memset(&g_rvprof.functions, 0, sizeof(g_rvprof.functions)); memset(&g_rvprof.stacks,0,sizeof(g_rvprof.stacks)); // register atexit handler to automate cleanup register_atexit_handler(); } void rvprof_set_program_name(const char* program_name){ if (g_rvprof.config.program_name){ rvprof_free(g_rvprof.config.program_name, strlen(g_rvprof.config.program_name)+1); } if (program_name) { g_rvprof.config.program_name = rvprof_malloc(strlen(program_name)+1); if (g_rvprof.config.program_name) { strcpy(g_rvprof.config.program_name, program_name); } } }