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.6KB

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