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 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #ifndef _GPXE_PROFILE_H
  2. #define _GPXE_PROFILE_H
  3. /** @file
  4. *
  5. * Profiling
  6. *
  7. */
  8. #include <stdint.h>
  9. /**
  10. * A data structure for storing profiling information
  11. */
  12. union profiler {
  13. /** Timestamp (in CPU-specific "ticks") */
  14. uint64_t timestamp;
  15. /** Registers returned by rdtsc.
  16. *
  17. * This part should really be architecture-specific code.
  18. */
  19. struct {
  20. uint32_t eax;
  21. uint32_t edx;
  22. } rdtsc;
  23. };
  24. /**
  25. * Static per-object profiler, for use with simple_profile()
  26. */
  27. static union profiler simple_profiler;
  28. /**
  29. * Perform profiling
  30. *
  31. * @v profiler Profiler data structure
  32. * @ret delta Elapsed ticks since last call to profile().
  33. *
  34. * Call profile() both before and after the code you wish to measure.
  35. * The "after" call will return the measurement. For example:
  36. *
  37. * @code
  38. *
  39. * profile ( &profiler );
  40. * ... do something here ...
  41. * printf ( "It took %ld ticks to execute\n", profile ( &profiler ) );
  42. *
  43. * @endcode
  44. */
  45. static inline __attribute__ (( always_inline )) unsigned long
  46. profile ( union profiler *profiler ) {
  47. uint64_t last_timestamp = profiler->timestamp;
  48. __asm__ __volatile__ ( "rdtsc" :
  49. "=a" ( profiler->rdtsc.eax ),
  50. "=d" ( profiler->rdtsc.edx ) );
  51. return ( profiler->timestamp - last_timestamp );
  52. }
  53. /**
  54. * Perform profiling
  55. *
  56. * @ret delta Elapsed ticks since last call to profile().
  57. *
  58. * When you only need one profiler, you can avoid the hassle of
  59. * creating your own @c profiler data structure by using
  60. * simple_profile() instead.
  61. *
  62. * simple_profile() is equivalent to profile(&simple_profiler), where
  63. * @c simple_profiler is a @c profiler data structure that is static
  64. * to each object which includes @c profile.h.
  65. */
  66. static inline __attribute__ (( always_inline )) unsigned long
  67. simple_profile ( void ) {
  68. return profile ( &simple_profiler );
  69. }
  70. #endif /* _GPXE_PROFILE_H */