profile.h

Go to the documentation of this file.
00001 #ifndef _GPXE_PROFILE_H
00002 #define _GPXE_PROFILE_H
00003 
00004 /** @file
00005  *
00006  * Profiling
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER );
00011 
00012 #include <stdint.h>
00013 
00014 /**
00015  * A data structure for storing profiling information
00016  */
00017 union profiler {
00018         /** Timestamp (in CPU-specific "ticks") */
00019         uint64_t timestamp;
00020         /** Registers returned by rdtsc.
00021          *
00022          * This part should really be architecture-specific code.
00023          */
00024         struct {
00025                 uint32_t eax;
00026                 uint32_t edx;
00027         } rdtsc;
00028 };
00029 
00030 /**
00031  * Static per-object profiler, for use with simple_profile()
00032  */
00033 static union profiler simple_profiler;
00034 
00035 /**
00036  * Perform profiling
00037  *
00038  * @v profiler          Profiler data structure
00039  * @ret delta           Elapsed ticks since last call to profile().
00040  *
00041  * Call profile() both before and after the code you wish to measure.
00042  * The "after" call will return the measurement.  For example:
00043  *
00044  * @code
00045  *
00046  *     profile ( &profiler );
00047  *     ... do something here ...
00048  *     printf ( "It took %ld ticks to execute\n", profile ( &profiler ) );
00049  *
00050  * @endcode
00051  */
00052 static inline __attribute__ (( always_inline )) unsigned long
00053 profile ( union profiler *profiler ) {
00054         uint64_t last_timestamp = profiler->timestamp;
00055 
00056         __asm__ __volatile__ ( "rdtsc" :
00057                                "=a" ( profiler->rdtsc.eax ),
00058                                "=d" ( profiler->rdtsc.edx ) );
00059         return ( profiler->timestamp - last_timestamp );
00060 }
00061 
00062 /**
00063  * Perform profiling
00064  *
00065  * @ret delta           Elapsed ticks since last call to profile().
00066  *
00067  * When you only need one profiler, you can avoid the hassle of
00068  * creating your own @c profiler data structure by using
00069  * simple_profile() instead.
00070  *
00071  * simple_profile() is equivalent to profile(&simple_profiler), where
00072  * @c simple_profiler is a @c profiler data structure that is static
00073  * to each object which includes @c profile.h.
00074  */
00075 static inline __attribute__ (( always_inline )) unsigned long
00076 simple_profile ( void ) {
00077         return profile ( &simple_profiler );
00078 }
00079 
00080 #endif /* _GPXE_PROFILE_H */

Generated on Tue Apr 6 20:01:08 2010 for gPXE by  doxygen 1.5.7.1