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.

profile.h 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #ifndef _IPXE_PROFILE_H
  2. #define _IPXE_PROFILE_H
  3. /** @file
  4. *
  5. * Profiling
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  9. #include <bits/profile.h>
  10. #include <ipxe/tables.h>
  11. #ifdef NDEBUG
  12. #define PROFILING 0
  13. #else
  14. #define PROFILING 1
  15. #endif
  16. /**
  17. * A data structure for storing profiling information
  18. */
  19. struct profiler {
  20. /** Name */
  21. const char *name;
  22. /** Start timestamp */
  23. unsigned long started;
  24. /** Stop timestamp */
  25. unsigned long stopped;
  26. /** Number of samples */
  27. unsigned int count;
  28. /** Mean sample value (scaled) */
  29. unsigned long mean;
  30. /** Mean sample value MSB
  31. *
  32. * This is the highest bit set in the raw (unscaled) value
  33. * (i.e. one less than would be returned by flsl(raw_mean)).
  34. */
  35. unsigned int mean_msb;
  36. /** Accumulated variance (scaled) */
  37. unsigned long long accvar;
  38. /** Accumulated variance MSB
  39. *
  40. * This is the highest bit set in the raw (unscaled) value
  41. * (i.e. one less than would be returned by flsll(raw_accvar)).
  42. */
  43. unsigned int accvar_msb;
  44. };
  45. /** Profiler table */
  46. #define PROFILERS __table ( struct profiler, "profilers" )
  47. /** Declare a profiler */
  48. #if PROFILING
  49. #define __profiler __table_entry ( PROFILERS, 01 )
  50. #else
  51. #define __profiler
  52. #endif
  53. extern unsigned long profile_excluded;
  54. extern void profile_update ( struct profiler *profiler, unsigned long sample );
  55. extern unsigned long profile_mean ( struct profiler *profiler );
  56. extern unsigned long profile_variance ( struct profiler *profiler );
  57. extern unsigned long profile_stddev ( struct profiler *profiler );
  58. /**
  59. * Get start time
  60. *
  61. * @v profiler Profiler
  62. * @ret started Start time
  63. */
  64. static inline __attribute__ (( always_inline )) unsigned long
  65. profile_started ( struct profiler *profiler ) {
  66. /* If profiling is active then return start time */
  67. if ( PROFILING ) {
  68. return ( profiler->started + profile_excluded );
  69. } else {
  70. return 0;
  71. }
  72. }
  73. /**
  74. * Get stop time
  75. *
  76. * @v profiler Profiler
  77. * @ret stopped Stop time
  78. */
  79. static inline __attribute__ (( always_inline )) unsigned long
  80. profile_stopped ( struct profiler *profiler ) {
  81. /* If profiling is active then return start time */
  82. if ( PROFILING ) {
  83. return ( profiler->stopped + profile_excluded );
  84. } else {
  85. return 0;
  86. }
  87. }
  88. /**
  89. * Get elapsed time
  90. *
  91. * @v profiler Profiler
  92. * @ret elapsed Elapsed time
  93. */
  94. static inline __attribute__ (( always_inline )) unsigned long
  95. profile_elapsed ( struct profiler *profiler ) {
  96. /* If profiling is active then return elapsed time */
  97. if ( PROFILING ) {
  98. return ( profile_stopped ( profiler ) -
  99. profile_started ( profiler ) );
  100. } else {
  101. return 0;
  102. }
  103. }
  104. /**
  105. * Start profiling
  106. *
  107. * @v profiler Profiler
  108. * @v started Start timestamp
  109. */
  110. static inline __attribute__ (( always_inline )) void
  111. profile_start_at ( struct profiler *profiler, unsigned long started ) {
  112. /* If profiling is active then record start timestamp */
  113. if ( PROFILING )
  114. profiler->started = ( started - profile_excluded );
  115. }
  116. /**
  117. * Stop profiling
  118. *
  119. * @v profiler Profiler
  120. * @v stopped Stop timestamp
  121. */
  122. static inline __attribute__ (( always_inline )) void
  123. profile_stop_at ( struct profiler *profiler, unsigned long stopped ) {
  124. /* If profiling is active then record end timestamp and update stats */
  125. if ( PROFILING ) {
  126. profiler->stopped = ( stopped - profile_excluded );
  127. profile_update ( profiler, profile_elapsed ( profiler ) );
  128. }
  129. }
  130. /**
  131. * Start profiling
  132. *
  133. * @v profiler Profiler
  134. */
  135. static inline __attribute__ (( always_inline )) void
  136. profile_start ( struct profiler *profiler ) {
  137. /* If profiling is active then record start timestamp */
  138. if ( PROFILING )
  139. profile_start_at ( profiler, profile_timestamp() );
  140. }
  141. /**
  142. * Stop profiling
  143. *
  144. * @v profiler Profiler
  145. */
  146. static inline __attribute__ (( always_inline )) void
  147. profile_stop ( struct profiler *profiler ) {
  148. /* If profiling is active then record end timestamp and update stats */
  149. if ( PROFILING )
  150. profile_stop_at ( profiler, profile_timestamp() );
  151. }
  152. /**
  153. * Exclude time from other ongoing profiling results
  154. *
  155. * @v profiler Profiler
  156. */
  157. static inline __attribute__ (( always_inline )) void
  158. profile_exclude ( struct profiler *profiler ) {
  159. /* If profiling is active then update accumulated excluded time */
  160. if ( PROFILING )
  161. profile_excluded += profile_elapsed ( profiler );
  162. }
  163. /**
  164. * Record profiling sample in custom units
  165. *
  166. * @v profiler Profiler
  167. * @v sample Profiling sample
  168. */
  169. static inline __attribute__ (( always_inline )) void
  170. profile_custom ( struct profiler *profiler, unsigned long sample ) {
  171. /* If profiling is active then update stats */
  172. if ( PROFILING )
  173. profile_update ( profiler, sample );
  174. }
  175. #endif /* _IPXE_PROFILE_H */