2019-07-17 19:00:49 +02:00
|
|
|
//---
|
|
|
|
// libprof: A manual profiling library for gint
|
|
|
|
//---
|
|
|
|
|
|
|
|
#ifndef LIBPROF_LIBPROF
|
|
|
|
#define LIBPROF_LIBPROF
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
//---
|
|
|
|
// Initialization
|
|
|
|
//---
|
|
|
|
|
|
|
|
/* prof_init(): Initialize the profiler's data and timer
|
|
|
|
|
|
|
|
Initializes [prof_rec] and [prof_time] (see below) with enough elements to
|
|
|
|
hold all the context IDs. Context IDs should be numbered from 0 to [n-1];
|
|
|
|
due to speed requirements array bounds are not checked so be careful.
|
|
|
|
|
2020-06-20 23:20:20 +02:00
|
|
|
Also starts a timer to count time. libprof automatically selects a TMU and
|
|
|
|
tries to use TMU2 before TMU1 before TMU0 so that high-priority interrupts
|
|
|
|
remain available, and sets an accurate clock configuration.
|
|
|
|
|
|
|
|
@context_count Number of different contexts that will be measured
|
|
|
|
Returns non-zero if a setup error occurs or no timer is available. */
|
|
|
|
int prof_init(int context_count);
|
2019-07-17 19:00:49 +02:00
|
|
|
|
|
|
|
/* prof_quit(): Free the profiler's data and timer */
|
|
|
|
void prof_quit(void);
|
|
|
|
|
|
|
|
//---
|
|
|
|
// Runtime time measurement
|
|
|
|
//---
|
|
|
|
|
|
|
|
/* Recursion depth of each function currently being executed */
|
|
|
|
extern uint8_t *prof_rec;
|
|
|
|
/* Time that has elapsed within each function; the value for a given function
|
|
|
|
is only relevant when it is not executing, due to optimizations */
|
|
|
|
extern uint32_t *prof_elapsed;
|
|
|
|
/* Timer counter */
|
|
|
|
extern uint32_t volatile *prof_tcnt;
|
|
|
|
|
|
|
|
/* prof_enter(): Start counting time for a function
|
|
|
|
This macro should be called at the start of the context scope. If the
|
|
|
|
function was already executing then the deepest instance in the stack is
|
|
|
|
used instead of creating a new counter. */
|
|
|
|
#define prof_enter(ctx) { \
|
|
|
|
if(!prof_rec[ctx]++) prof_elapsed[ctx] += *prof_tcnt; \
|
|
|
|
}
|
|
|
|
|
|
|
|
/* prof_leave(): Stop counting time for a function
|
|
|
|
This should be called at the end of the context scope; it only actually
|
|
|
|
stops if there is no deeper instance of the context in the stack. If there
|
|
|
|
are not as exactly as many prof_leave()'s as prof_enter()'s then the
|
|
|
|
resulting time measure will not be relevant at all. */
|
|
|
|
#define prof_leave(ctx) { \
|
|
|
|
if(!--prof_rec[ctx]) prof_elapsed[ctx] -= *prof_tcnt; \
|
|
|
|
}
|
|
|
|
|
|
|
|
/* prof_clear(): Clear a context's counter
|
|
|
|
This operation is defined only if the context is not being profiled. */
|
|
|
|
#define prof_clear(ctx) { \
|
|
|
|
prof_elapsed[ctx] = 0; \
|
|
|
|
}
|
|
|
|
|
|
|
|
//---
|
|
|
|
// Post-measurement analysis
|
|
|
|
//---
|
|
|
|
|
|
|
|
/* prof_time(): Time spent in a given context, in microseconds
|
|
|
|
Should only be called when the context is not currently executing. */
|
|
|
|
uint32_t prof_time(int ctx);
|
|
|
|
|
|
|
|
#endif /* LIBPROF_LIBPROF */
|