#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 = -1; /* prof_init(): Initialize the profiler's data and timer */ int prof_init(int context_count) { prof_rec = malloc(context_count * sizeof *prof_rec); prof_elapsed = malloc(context_count * sizeof *prof_elapsed); /* Get a TMU with the exact constant 0xffffffff */ int timer = -1; for(int t = 2; t >= 0 && timer == -1; t--) { timer = timer_setup(t, 0xffffffff, NULL); } if(!prof_rec || !prof_elapsed || timer == -1) { 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) { if(prof_timer >= 0) timer_stop(prof_timer); if(prof_rec) free(prof_rec); if(prof_elapsed) free(prof_elapsed); prof_timer = -1; prof_rec = NULL; prof_elapsed = NULL; } //--- // 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; }