49 #include <sys/ptrace.h> 50 #include <sys/resource.h> 52 #include <sys/types.h> 68 #define MAX_EVT_NAME_LEN 256 69 #define NUM_PMCS PFMLIB_MAX_PMCS 70 #define NUM_PMDS PFMLIB_MAX_PMDS 71 #define FMT_NAME PFM_DFL_SMPL_NAME 72 #define BPL ( sizeof( uint64_t ) << 3 ) 75 #define SYM_NAME_MAX_LENGTH 10000 76 #define MAX_OUTPUT_FILENAME_LENGTH 1024 77 #define MAX_EVENT_NAME_LENGTH 500 78 #define MAX_PREFIX_NAME_LENGTH 1024 79 #define FILENAME_MAX_LENGTH 1024 81 #define MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS 4 83 #define cpuid( func, ax, bx, cx, dx ) \ 84 __asm__ __volatile__( "cpuid" : "=a"( ax ), "=b"( bx ), "=c"( cx ), "=d"( dx ) : "a"( func ) ); 87 static uint64_t collected_samples, collected_partial;
91 static size_t entry_size;
92 static unsigned int num_smpl_pmds;
107 template <
typename T>
108 inline T function_cast(
void* p ) {
114 return caster.function;
119 typedef void ( *pfm_stop_t )( int );
121 typedef void ( *pfm_self_stop_t )( int );
122 pfm_self_stop_t pfm_self_stop{
nullptr};
123 typedef os_err_t ( *pfm_restart_t )( int );
125 typedef int ( *pfm_read_pmds_t )( int,
pfarg_pmd_t*, int );
127 typedef pfm_err_t ( *pfm_initialize_t )();
143 typedef char* ( *pfm_strerror_t )( int );
147 typedef pfm_err_t ( *pfm_get_num_counters_t )(
unsigned int* );
149 static PFMon& instance() {
return s_instance; }
157 handle = dlopen(
"libpfm.so", RTLD_NOW );
164 pfm_start = function_cast<pfm_start_t>( dlsym( handle,
"pfm_start" ) );
165 pfm_stop = function_cast<pfm_stop_t>( dlsym( handle,
"pfm_stop" ) );
166 pfm_self_stop = function_cast<pfm_self_stop_t>( dlsym( handle,
"pfm_stop" ) );
167 pfm_restart = function_cast<pfm_restart_t>( dlsym( handle,
"pfm_restart" ) );
168 pfm_read_pmds = function_cast<pfm_read_pmds_t>( dlsym( handle,
"pfm_read_pmds" ) );
169 pfm_initialize = function_cast<pfm_initialize_t>( dlsym( handle,
"pfm_initialize" ) );
170 pfm_find_full_event = function_cast<pfm_find_full_event_t>( dlsym( handle,
"pfm_find_full_event" ) );
171 pfm_dispatch_events = function_cast<pfm_dispatch_events_t>( dlsym( handle,
"pfm_dispatch_events" ) );
172 pfm_create_context = function_cast<pfm_create_context_t>( dlsym( handle,
"pfm_create_context" ) );
173 pfm_write_pmcs = function_cast<pfm_write_pmcs_t>( dlsym( handle,
"pfm_write_pmcs" ) );
174 pfm_write_pmds = function_cast<pfm_write_pmds_t>( dlsym( handle,
"pfm_write_pmds" ) );
175 pfm_load_context = function_cast<pfm_load_context_t>( dlsym( handle,
"pfm_load_context" ) );
176 pfm_strerror = function_cast<pfm_strerror_t>( dlsym( handle,
"pfm_strerror" ) );
177 pfm_set_options = function_cast<pfm_set_options_t>( dlsym( handle,
"pfm_set_options" ) );
178 pfm_get_num_counters = function_cast<pfm_get_num_counters_t>( dlsym( handle,
"pfm_get_num_counters" ) );
186 if ( handle ) dlclose( handle );
189 static PFMon s_instance;
192 PFMon PFMon::s_instance;
227 # pragma warning( push ) 228 # pragma warning( disable : 593 ) 232 int sse4_2_mask = 1 << 20;
233 if (
c & sse4_2_mask )
238 # pragma warning( pop ) 284 ,
m_pfm( PFMon::instance() )
402 return bv[rnum >>
LBPL] & ( 1UL << ( rnum & (
BPL - 1 ) ) ) ? 1 : 0;
432 memset( &
ctx, 0,
sizeof(
ctx ) );
433 memset( &
inp, 0,
sizeof(
inp ) );
435 memset(
pd, 0,
sizeof(
pd ) );
436 memset(
pc, 0,
sizeof(
pc ) );
465 error() <<
"ERROR: cannot dispatch events: " <<
m_pfm.pfm_strerror(
ret ) <<
". Aborting..." <<
endmsg;
475 fd =
m_pfm.pfm_create_context( &
ctx, NULL, 0, 0 );
476 if (
fd == -1 ) {
error() <<
"ERROR: Context not created. Aborting..." <<
endmsg; }
478 error() <<
"ERROR: Could not write pmcs. Aborting..." <<
endmsg;
481 error() <<
"ERROR: Could not write pmds. Aborting..." <<
endmsg;
485 error() <<
"ERROR: Could not load context. Aborting..." <<
endmsg;
500 results[
i][( alg_stack.top().first )->
name()].push_back( alg_stack.top().second[
i] +
pd[
i].
reg_value );
526 if (
c ==
':' )
c =
'-';
533 FILE* outfile = fopen(
filename.c_str(),
"w" );
535 fprintf( outfile,
"NHM " );
537 fprintf( outfile,
"WSM " );
539 fprintf( outfile,
"CORE " );
543 it != ( results[
i] ).
end(); it++ ) {
544 fprintf( outfile,
"%s\n", ( it->first ).c_str() );
546 fprintf( outfile,
"%lu\n", *j );
554 if ( !
m_pfm.loaded ) {
555 error() <<
"pfm library could not be loaded" <<
endmsg;
583 error() <<
"ERROR: Unsupported processor family " <<
family <<
". aborting..." <<
endmsg;
600 printf(
"skipping identical set of samples...\n" );
605 pos = (
unsigned long)ent;
606 entry = collected_samples;
610 ( ( samples[ent->
ovfl_pmd] )[( alg_stack.top().first )->
name()] )[(
unsigned long)( ent->
ip )]++;
616 collected_samples = entry;
618 if ( last_count != hdr->
hdr_count && ( last_count || last_overflow == 0 ) ) { collected_partial += hdr->
hdr_count; }
628 PFMon& pfm = PFMon::instance();
632 if (
fd != ctx_fd ) {
635 if ( pfm.pfm_read_pmds(
fd, pd_smpl + 1, 1 ) == -1 ) {
640 if ( r !=
sizeof(
msg ) ) {
641 if ( r == -1 && errno == EINTR ) {
642 printf(
"read interrupted, retrying\n" );
649 switch (
msg.type ) {
653 if ( pfm.pfm_restart(
fd ) ) {
654 if ( errno != EBUSY ) {
657 printf(
"pfm_restart: task probably terminated \n" );
682 error() <<
"ERROR: Cannot initialize library: " <<
m_pfm.pfm_strerror(
ret ) <<
". Aborting..." <<
endmsg;
684 struct sigaction act;
685 memset( &act, 0,
sizeof( act ) );
688 sigaction( SIGIO, &act, 0 );
689 memset( &
ctx, 0,
sizeof(
ctx ) );
691 memset( &
inp, 0,
sizeof(
inp ) );
693 memset( pd_smpl, 0,
sizeof( pd_smpl ) );
694 memset(
pc, 0,
sizeof(
pc ) );
724 error() <<
"ERROR: cannot configure events: " <<
m_pfm.pfm_strerror(
ret ) <<
". Aborting..." <<
endmsg;
733 pfm_bv_set( pd_smpl[0].reg_smpl_pmds, pd_smpl[
i].reg_num );
751 if ( ctx_fd == -1 ) {
752 if ( errno == ENOSYS ) {
753 error() <<
"ERROR: Your kernel does not have performance monitoring support! Aborting..." <<
endmsg;
755 error() <<
"ERROR: Can't create PFM context " << strerror( errno ) <<
". Aborting..." <<
endmsg;
759 error() <<
"ERROR: cannot mmap sampling buffer: " << strerror( errno ) <<
". Aborting..." <<
endmsg;
763 error() <<
"ERROR: invalid buffer format version. Aborting..." <<
endmsg;
766 error() <<
"ERROR: pfm_write_pmcs error errno " << strerror( errno ) <<
". Aborting..." <<
endmsg;
769 error() <<
"ERROR: pfm_write_pmds error errno " << strerror( errno ) <<
". Aborting..." <<
endmsg;
773 error() <<
"ERROR: pfm_load_context error errno " << strerror( errno ) <<
". Aborting..." <<
endmsg;
775 ret = fcntl( ctx_fd, F_SETFL, fcntl( ctx_fd, F_GETFL, 0 ) | O_ASYNC );
776 if (
ret == -1 ) {
error() <<
"ERROR: cannot set ASYNC: " << strerror( errno ) <<
". Aborting..." <<
endmsg; }
777 ret = fcntl( ctx_fd, F_SETOWN, getpid() );
778 if (
ret == -1 ) {
error() <<
"ERROR: cannot setown: " << strerror( errno ) <<
". Aborting..." <<
endmsg; }
780 m_pfm.pfm_start( ctx_fd, NULL );
788 m_pfm.pfm_self_stop( ctx_fd );
792 if (
ret ) {
error() <<
"Cannot unmap buffer: %s" << strerror( errno ) <<
endmsg; }
808 if (
c ==
':' )
c =
'-';
814 gzFile outfile = gzopen(
filename.c_str(),
"wb" );
815 if ( outfile != NULL ) {
817 gzprintf( outfile,
"NHM " );
819 gzprintf( outfile,
"WSM " );
821 gzprintf( outfile,
"CORE " );
825 error() <<
"ERROR: gzputs err: " << gzerror( outfile, &
err ) <<
". Aborting..." <<
endmsg;
828 it != samples[
i].end(); it++ ) {
829 unsigned long long sum = 0;
834 if ( gzprintf( outfile,
"%s%%%llu\n", ( it->first ).c_str(), sum ) < (
int)( ( it->first ).length() ) ) {
835 error() <<
"ERROR: gzputs err: " << gzerror( outfile, &
err ) <<
". Aborting..." <<
endmsg;
842 const char* symbolName;
846 if ( sym_addr != NULL ) {
849 if ( symbolName != NULL && strlen( symbolName ) > 0 ) {
850 strcpy( sym_name, symbolName );
851 strcat( sym_name,
" " );
853 strcpy( sym_name,
"??? " );
855 if ( libName != NULL && strlen( libName ) > 0 ) {
856 strcat( sym_name, libName );
857 strcat( sym_name,
" " );
859 strcat( sym_name,
"??? " );
861 sprintf( sym_name + strlen( sym_name ),
"%d ", libOffset );
862 if ( strlen( sym_name ) <= 0 ) {
error() <<
"ERROR: Symbol name length is zero. Aborting..." <<
endmsg; }
864 strcpy( sym_name,
"??? ??? 0 " );
867 strcpy( sym_name,
"??? ??? 0 " );
869 if ( gzprintf( outfile,
"%s %d\n", sym_name, jt->second ) < (
int)strlen( sym_name ) ) {
870 error() <<
"ERROR: gzputs err: " << gzerror( outfile, &
err ) <<
endmsg;
942 if ( !alg_stack.empty() ) {
959 if ( !
alg ) {
return; }
970 if ( !alg_stack.empty() ) {
pfmlib_reg_t pfp_pmds[PFMLIB_MAX_PMDS]
pfmlib_core_input_param_t params
os_err_t pfm_write_pmds(int fd, pfarg_pmd_t *pmds, int count)
virtual StatusCode finalize()
#define PFM_REGFL_OVFL_NOTIFY
#define MAX_PREFIX_NAME_LENGTH
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
os_err_t pfm_create_context(pfarg_ctx_t *ctx, char *smpl_name, void *smpl_arg, size_t smpl_size)
PerfMonAuditor(const std::string &name, ISvcLocator *pSvc)
char * pfm_strerror(int code)
static void * tosymbol(void *address)
bool inv[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS]
constexpr static const auto SUCCESS
pfm_err_t pfm_get_num_counters(unsigned int *num)
#define SYM_NAME_MAX_LENGTH
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Details::PropertyBase &prop)
Declare a property.
def read(f, regex='.*', skipevents=0)
unsigned long long uint64_t
void i_afterExecute(INamedInterface *alg)
unsigned short int uint16_t
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
os_err_t pfm_write_pmcs(int fd, pfarg_pmc_t *pmcs, int count)
Performance Monitoring Auditor that uses Perfmon2 library to monitor algorithms.
pfm_err_t pfm_dispatch_events(pfmlib_input_param_t *p, void *model_in, pfmlib_output_param_t *q, void *model_out)
unsigned int pfp_pmc_count
pfmlib_options_t pfmlib_options
unsigned long long reg_value
unsigned int pfp_pmd_count
std::string first_alg_name
pfm_err_t pfm_find_full_event(const char *str, pfmlib_event_t *e)
StatusCode finalize() override
#define MAX_EVENT_NAME_LENGTH
pfmlib_nhm_input_param_t nhm_params
int detect_unavail_pmu_regs(int fd, pfmlib_regmask_t *r_pmcs, pfmlib_regmask_t *r_pmds)
#define DECLARE_COMPONENT(type)
#define PFM_VERSION_MAJOR(x)
void pfm_bv_copy(uint64_t *d, uint64_t *j, uint16_t n)
GaudiUtils::VectorMap< const INamedInterface *, int > Map
int detect_unavail_pmcs(int fd, pfmlib_regmask_t *r_pmcs)
void pfm_bv_set(uint64_t *bv, uint16_t rnum)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
os_err_t pfm_restart(int fd)
std::string event_str[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS]
This class is used for returning status codes from appropriate routines.
pfmlib_output_param_t outp
void after(StandardEventType, INamedInterface *, const StatusCode &) override
static bool symbol(void *address, const char *&sym, const char *&lib, int &offset, int &liboffset)
char event_cstr[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS][MAX_EVENT_NAME_LENGTH]
void after(StandardEventType evt, INamedInterface *alg, const StatusCode &sc) override
os_err_t pfm_start(int fd, pfarg_start_t *start)
pfm_err_t pfm_initialize(void)
PerfMonAuditor & operator=(const PerfMonAuditor &)
char prefix_cstr[MAX_PREFIX_NAME_LENGTH]
IInterface compliant class extending IInterface with the name() method.
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
int pfm_bv_isset(uint64_t *bv, uint16_t rnum)
unsigned int start_at_event
static void process_smpl_buf(pfm_dfl_smpl_hdr_t *hdr, size_t entry_size)
os_err_t pfm_load_context(int fd, pfarg_load_t *load)
#define cpuid(func, ax, bx, cx, dx)
const std::string & name() const override
constexpr static const auto FAILURE
pfm_dfl_smpl_arg_t buf_arg
static void sigio_handler(int, siginfo_t *, void *)
os_err_t pfm_read_pmds(int fd, pfarg_pmd_t *pmds, int count)
pfmlib_reg_t pfp_pmcs[PFMLIB_MAX_PMCS]
StatusCode initialize() override
MsgStream & err() const
shortcut for the method msgStream(MSG::ERROR)
void i_beforeExecute(INamedInterface *alg)
virtual StatusCode initialize()
AttribStringParser::Iterator begin(const AttribStringParser &parser)
#define MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS
void i_afterInitialize(INamedInterface *alg)
void i_beforeInitialize(INamedInterface *alg)
unsigned int cmask[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS]
os_err_t pfm_stop(int fd)
virtual ~PerfMonAuditor()
void before(StandardEventType, INamedInterface *) override
The following methods are meant to be implemented by the child class...
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
void before(StandardEventType evt, INamedInterface *alg) override
pfm_err_t pfm_set_options(pfmlib_options_t *opt)
Base class from which all concrete auditor classes should be derived.