mirror of
https://github.com/xcat2/xNBA.git
synced 2024-11-26 11:19:17 +00:00
Added basic profiling support
This commit is contained in:
parent
a677f1bfd3
commit
b4e559d7e2
78
src/include/gpxe/profile.h
Normal file
78
src/include/gpxe/profile.h
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef _GPXE_PROFILE_H
|
||||
#define _GPXE_PROFILE_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Profiling
|
||||
*
|
||||
*/
|
||||
|
||||
#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 */
|
Loading…
Reference in New Issue
Block a user