diff --git a/src/rvprof_core.c b/src/rvprof_core.c index 0528f4f..6e407d5 100644 --- a/src/rvprof_core.c +++ b/src/rvprof_core.c @@ -135,3 +135,48 @@ void rvprof_region_begin(const char* name){ } +void rvprof_region_end(const char* name){ + if (!g_rvprof.initialized || g_rvprof.stack_ptr < 0){ + return; + } + + region_t* region = &g_rvprof.regions.data[g_rvprof.stack_ptr]; + + // make sure name matches + if (strcmp(region->name, name) !=0) return; + + // end timing + uint64_t end_time_ns = rvprof_timing_get_current(); + uint64_t end_cycles = rvprof_timing_get_cycles(); + uint64_t elapsed_time = end_time_ns - region->start_time_ns; + uint64_t elapsed_cycles = (end_cycles > region->start_cycles) ? (end_cycles - region->start_cycles) : 0; + + // update region statistics + if (region->function_id >= 0){ + function_stats_t* stats = &g_rvprof.functions.data[region->function_id]; + uint64_t exclusive_time = elapsed_time - region->child_time; + uint64_t exclusive_cycles = (elapsed_cycles > region->child_cycles) ? (elapsed_cycles - region->child_cycles) : 0; \ + + stats->total_inclusive_time += elapsed_time; + stats->total_exclusive_time += exclusive_time; + + stats->total_inclusive_cycles += elapsed_cycles; + stats->total_exclusive_cycles += exclusive_cycles; + } + + // update parent statistics + if (g_rvprof.stack_ptr > 0) { + g_rvprof.regions.data[g_rvprof.stack_ptr-1].child_time += elapsed_time; + g_rvprof.regions.data[g_rvprof.stack_ptr-1].child_cycles += elapsed_cycles; + } else { + // this is the top-level region, updatre total program stats + if (elapsed_time > g_rvprof.total_program_time){ + g_rvprof.total_program_time = elapsed_time; + g_rvprof.total_program_cycles = elapsed_cycles; + } + } + + // region ended: decrease stack pointer + g_rvprof.stack_ptr--; +} +