A microsecond-level performance profiling library for gint.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.4KB

  1. //---
  2. // libprof: A manual profiling library for gint
  3. //---
  4. #ifndef LIBPROF_LIBPROF
  5. #define LIBPROF_LIBPROF
  6. #include <stdint.h>
  7. //---
  8. // Initialization
  9. //---
  10. /* prof_init(): Initialize the profiler's data and timer
  11. Initializes [prof_rec] and [prof_time] (see below) with enough elements to
  12. hold all the context IDs. Context IDs should be numbered from 0 to [n-1];
  13. due to speed requirements array bounds are not checked so be careful.
  14. Also starts a timer to count time. The timer ID must be set to 0, 1 or 2 as
  15. the standard TMU is the most tweakable and precise. libprof automatically
  16. selects an accurate timer configuration.
  17. @n Number of different contexts (functions) that will be measured
  18. @timer Timer ID, see <gint/timer.h> to select one
  19. Returns non-zero if a setup error occurs. */
  20. int prof_init(int n, int timer);
  21. /* prof_quit(): Free the profiler's data and timer */
  22. void prof_quit(void);
  23. //---
  24. // Runtime time measurement
  25. //---
  26. /* Recursion depth of each function currently being executed */
  27. extern uint8_t *prof_rec;
  28. /* Time that has elapsed within each function; the value for a given function
  29. is only relevant when it is not executing, due to optimizations */
  30. extern uint32_t *prof_elapsed;
  31. /* Timer counter */
  32. extern uint32_t volatile *prof_tcnt;
  33. /* prof_enter(): Start counting time for a function
  34. This macro should be called at the start of the context scope. If the
  35. function was already executing then the deepest instance in the stack is
  36. used instead of creating a new counter. */
  37. #define prof_enter(ctx) { \
  38. if(!prof_rec[ctx]++) prof_elapsed[ctx] += *prof_tcnt; \
  39. }
  40. /* prof_leave(): Stop counting time for a function
  41. This should be called at the end of the context scope; it only actually
  42. stops if there is no deeper instance of the context in the stack. If there
  43. are not as exactly as many prof_leave()'s as prof_enter()'s then the
  44. resulting time measure will not be relevant at all. */
  45. #define prof_leave(ctx) { \
  46. if(!--prof_rec[ctx]) prof_elapsed[ctx] -= *prof_tcnt; \
  47. }
  48. /* prof_clear(): Clear a context's counter
  49. This operation is defined only if the context is not being profiled. */
  50. #define prof_clear(ctx) { \
  51. prof_elapsed[ctx] = 0; \
  52. }
  53. //---
  54. // Post-measurement analysis
  55. //---
  56. /* prof_time(): Time spent in a given context, in microseconds
  57. Should only be called when the context is not currently executing. */
  58. uint32_t prof_time(int ctx);
  59. #endif /* LIBPROF_LIBPROF */