#include #include #include #include #include #include /* Recursion depth of each function currently being executed */ uint8_t *prof_rec = NULL; /* Time that has elapsed within each function; the value for a given function is only relevant when it is not executing, due to optimizations */ uint32_t *prof_elapsed = NULL; /* Timer counter */ uint32_t volatile *prof_tcnt = NULL; /* Timer ID */ static int prof_timer; /* prof_init(): Initialize the profiler's data and timer */ int prof_init(int n, int timer) { if((unsigned)timer >= 3) return 1; prof_rec = malloc(n * sizeof *prof_rec); prof_elapsed = malloc(n * sizeof *prof_elapsed); int status = timer_setup(timer, 0xffffffff, timer_Po_4, NULL, NULL); if(!prof_rec || !prof_elapsed || status < 0) { prof_quit(); return 1; } /* Fix the configuration done by gint by disabling the interrupt */ if(isSH3()) { SH7705_TMU.TMU[timer].TCR.UNIE = 0; prof_tcnt = &SH7705_TMU.TMU[timer].TCNT; } else { SH7305_TMU.TMU[timer].TCR.UNIE = 0; prof_tcnt = &SH7305_TMU.TMU[timer].TCNT; } timer_start(timer); prof_timer = timer; return 0; } /* prof_quit(): Free the profiler's data and timer */ void prof_quit(void) { timer_stop(prof_timer); free(prof_rec); free(prof_time); } //--- // Post-measurement analysis //--- /* prof_time(): Time spent in a given context, in microseconds */ uint32_t prof_time(int ctx) { int Pphi = clock_freq()->Pphi_f; uint64_t time = prof_elapsed[ctx]; return (time * 4 * 1000000) / Pphi; }