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.

75 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. libprof automatically selects a TMU and
  15. tries to use TMU2 before TMU1 before TMU0 so that high-priority interrupts
  16. remain available, and sets an accurate clock configuration.
  17. @context_count Number of different contexts that will be measured
  18. Returns non-zero if a setup error occurs or no timer is available. */
  19. int prof_init(int context_count);
  20. /* prof_quit(): Free the profiler's data and timer */
  21. void prof_quit(void);
  22. //---
  23. // Runtime time measurement
  24. //---
  25. /* Recursion depth of each function currently being executed */
  26. extern uint8_t *prof_rec;
  27. /* Time that has elapsed within each function; the value for a given function
  28. is only relevant when it is not executing, due to optimizations */
  29. extern uint32_t *prof_elapsed;
  30. /* Timer counter */
  31. extern uint32_t volatile *prof_tcnt;
  32. /* prof_enter(): Start counting time for a function
  33. This macro should be called at the start of the context scope. If the
  34. function was already executing then the deepest instance in the stack is
  35. used instead of creating a new counter. */
  36. #define prof_enter(ctx) { \
  37. if(!prof_rec[ctx]++) prof_elapsed[ctx] += *prof_tcnt; \
  38. }
  39. /* prof_leave(): Stop counting time for a function
  40. This should be called at the end of the context scope; it only actually
  41. stops if there is no deeper instance of the context in the stack. If there
  42. are not as exactly as many prof_leave()'s as prof_enter()'s then the
  43. resulting time measure will not be relevant at all. */
  44. #define prof_leave(ctx) { \
  45. if(!--prof_rec[ctx]) prof_elapsed[ctx] -= *prof_tcnt; \
  46. }
  47. /* prof_clear(): Clear a context's counter
  48. This operation is defined only if the context is not being profiled. */
  49. #define prof_clear(ctx) { \
  50. prof_elapsed[ctx] = 0; \
  51. }
  52. //---
  53. // Post-measurement analysis
  54. //---
  55. /* prof_time(): Time spent in a given context, in microseconds
  56. Should only be called when the context is not currently executing. */
  57. uint32_t prof_time(int ctx);
  58. #endif /* LIBPROF_LIBPROF */