1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- #ifndef _GPXE_PROFILE_H
- #define _GPXE_PROFILE_H
-
- /** @file
- *
- * Profiling
- *
- */
-
- FILE_LICENCE ( GPL2_OR_LATER );
-
- #include <stdint.h>
-
- /**
- * A data structure for storing profiling information
- */
- union profiler {
- /** Timestamp (in CPU-specific "ticks") */
- uint64_t timestamp;
- /** Registers returned by rdtsc.
- *
- * This part should really be architecture-specific code.
- */
- struct {
- uint32_t eax;
- uint32_t edx;
- } rdtsc;
- };
-
- /**
- * Static per-object profiler, for use with simple_profile()
- */
- static union profiler simple_profiler;
-
- /**
- * Perform profiling
- *
- * @v profiler Profiler data structure
- * @ret delta Elapsed ticks since last call to profile().
- *
- * Call profile() both before and after the code you wish to measure.
- * The "after" call will return the measurement. For example:
- *
- * @code
- *
- * profile ( &profiler );
- * ... do something here ...
- * printf ( "It took %ld ticks to execute\n", profile ( &profiler ) );
- *
- * @endcode
- */
- static inline __attribute__ (( always_inline )) unsigned long
- profile ( union profiler *profiler ) {
- uint64_t last_timestamp = profiler->timestamp;
-
- __asm__ __volatile__ ( "rdtsc" :
- "=a" ( profiler->rdtsc.eax ),
- "=d" ( profiler->rdtsc.edx ) );
- return ( profiler->timestamp - last_timestamp );
- }
-
- /**
- * Perform profiling
- *
- * @ret delta Elapsed ticks since last call to profile().
- *
- * When you only need one profiler, you can avoid the hassle of
- * creating your own @c profiler data structure by using
- * simple_profile() instead.
- *
- * simple_profile() is equivalent to profile(&simple_profiler), where
- * @c simple_profiler is a @c profiler data structure that is static
- * to each object which includes @c profile.h.
- */
- static inline __attribute__ (( always_inline )) unsigned long
- simple_profile ( void ) {
- return profile ( &simple_profiler );
- }
-
- #endif /* _GPXE_PROFILE_H */
|