Gaudi Framework, version v22r1

Home   Generated: Mon Feb 28 2011

PerfMonAuditor.cpp

Go to the documentation of this file.
00001 // $Id: PerfMonAuditor.cpp,v 0.1 2009/10/28 Daniele Francesco Kruse $
00002 // ============================================================================
00003 // CVS tag $Name:  $, version $Revision: 0.1 $
00004 // ============================================================================
00005 
00006 #include "GaudiKernel/Auditor.h"
00007 #include "GaudiKernel/IToolSvc.h"
00008 #include "GaudiKernel/IIncidentListener.h"
00009 #include "GaudiKernel/IIncidentSvc.h"
00010 #include "GaudiKernel/IToolSvc.h"
00011 #include "GaudiKernel/VectorMap.h"
00012 #include "GaudiKernel/HashMap.h"
00013 #include "GaudiKernel/AudFactory.h"
00014 #include "GaudiKernel/MsgStream.h"
00015 
00016 /*BEGIN: perfmon*/
00017 #include <iostream>
00018 #include <string>
00019 #include <cstring>
00020 #include <fstream>
00021 #include <perfmon/pfmlib.h>
00022 #include <perfmon/pfmlib_core.h>
00023 #include <perfmon/pfmlib_intel_nhm.h>
00024 #include <vector>
00025 #include <map>
00026 #include <utility>
00027 #include <sstream>
00028 
00029 #include <perfmon/perfmon.h>
00030 #include <perfmon/perfmon_dfl_smpl.h>
00031 
00033 
00035 
00036 
00037 
00038 #include <sys/types.h>
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <stdarg.h>
00042 #include <errno.h>
00043 #include <unistd.h>
00044 #include <string.h>
00045 #include <signal.h>
00046 #include <stdarg.h>
00047 #include <stdint.h>
00048 #include <getopt.h>
00049 #include <time.h>
00050 #include <sys/ptrace.h>
00051 #include <sys/wait.h>
00052 #include <sys/mman.h>
00053 #include <sys/time.h>
00054 #include <sys/resource.h>
00055 #include <unistd.h>
00056 #include <fcntl.h>
00057 #include <zlib.h>
00058 
00059 #include <algorithm>
00060 #include <list>
00061 #include <stack>
00062 #include <cmath>
00063 #include <sys/stat.h>
00064 #include "IgHook_IgHookTrace.h"
00065 
00066 // dlopen (link with -ldl)
00067 #include <dlfcn.h>
00068 
00069 
00070 #define MAX_EVT_NAME_LEN 256
00071 #define NUM_PMCS PFMLIB_MAX_PMCS
00072 #define NUM_PMDS PFMLIB_MAX_PMDS
00073 #define FMT_NAME PFM_DFL_SMPL_NAME
00074 #define BPL (sizeof(uint64_t)<<3)
00075 #define LBPL 6
00076 
00077 #define SYM_NAME_MAX_LENGTH 10000
00078 #define MAX_OUTPUT_FILENAME_LENGTH 1024
00079 #define MAX_EVENT_NAME_LENGTH 500
00080 #define MAX_PREFIX_NAME_LENGTH 1024
00081 #define FILENAME_MAX_LENGTH 1024
00082 
00083 #define MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS 4
00084 
00085 #define cpuid(func,ax,bx,cx,dx) __asm__ __volatile__ ("cpuid": "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func));
00086 
00087 
00088 static pfarg_pmd_t pd_smpl[NUM_PMDS];
00089 static uint64_t collected_samples, collected_partial;
00090 static int ctx_fd;
00091 static pfm_dfl_smpl_hdr_t *hdr;
00092 static uint64_t ovfl_count;
00093 static size_t entry_size;
00094 static unsigned int num_smpl_pmds;
00095 static std::vector<std::map<std::string, std::map<unsigned long, unsigned int> > > samples(MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS); //a map of modules each containing numbers of samples of their addresses
00096 static std::vector<std::map<std::string, std::vector<unsigned long int> > > results(MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS); //a map of modules and their result values across multiple events
00097 static uint64_t last_overflow;
00098 static uint64_t last_count;
00099 static std::string current_module;
00100 static int sp[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
00101 
00102 static std::stack<std::pair<INamedInterface *, std::vector<unsigned long int> > > alg_stack;
00103 /*END: perfmon*/
00104 
00105 
00106 
00107 namespace {
00108   class PFMon {
00109   public:
00110     bool loaded;
00111     typedef void (*pfm_stop_t)(int);
00112     pfm_stop_t pfm_stop;
00113     typedef void (*pfm_self_stop_t)(int);
00114     pfm_self_stop_t pfm_self_stop;
00115     typedef os_err_t (*pfm_restart_t)(int);
00116     pfm_restart_t pfm_restart;
00117     typedef int (*pfm_read_pmds_t)(int, pfarg_pmd_t*, int);
00118     pfm_read_pmds_t pfm_read_pmds;
00119     typedef pfm_err_t (*pfm_initialize_t)();
00120     pfm_initialize_t pfm_initialize;
00121     typedef pfm_err_t (*pfm_find_full_event_t)(const char *, pfmlib_event_t *);
00122     pfm_find_full_event_t pfm_find_full_event;
00123     typedef pfm_err_t (*pfm_dispatch_events_t)(pfmlib_input_param_t *, void *, pfmlib_output_param_t *, void *);
00124     pfm_dispatch_events_t pfm_dispatch_events;
00125     typedef os_err_t (*pfm_create_context_t)(pfarg_ctx_t *, char *, void *, size_t);
00126     pfm_create_context_t pfm_create_context;
00127     typedef os_err_t (*pfm_write_pmcs_t)(int, pfarg_pmc_t *, int);
00128     pfm_write_pmcs_t pfm_write_pmcs;
00129     typedef os_err_t (*pfm_write_pmds_t)(int, pfarg_pmd_t *, int);
00130     pfm_write_pmds_t pfm_write_pmds;
00131     typedef os_err_t (*pfm_load_context_t)(int, pfarg_load_t *);
00132     pfm_load_context_t pfm_load_context;
00133     typedef os_err_t (*pfm_start_t)(int fd, pfarg_start_t *);
00134     pfm_start_t pfm_start;
00135     typedef char* (*pfm_strerror_t)(int);
00136     pfm_strerror_t pfm_strerror;
00137     typedef pfm_err_t (*pfm_set_options_t)(pfmlib_options_t *);
00138     pfm_set_options_t pfm_set_options;
00139     typedef pfm_err_t (*pfm_get_num_counters_t)(unsigned int *);
00140     pfm_get_num_counters_t pfm_get_num_counters;
00141     static PFMon &instance() {
00142       return s_instance;
00143     }
00144   private:
00145     // static void failure() { throw 1; }
00146 
00147     void* handle;
00148 
00149     PFMon() {
00150       handle = dlopen("libpfm.so", RTLD_NOW);
00151       if (handle) { loaded = true; } else { loaded = false; }
00152       if (loaded) {
00153         pfm_start = (pfm_start_t) dlsym(handle, "pfm_start");
00154         pfm_stop = (pfm_stop_t) dlsym(handle, "pfm_stop");
00155         pfm_self_stop = (pfm_self_stop_t) dlsym(handle, "pfm_stop"); //it's the same
00156         pfm_restart = (pfm_restart_t) dlsym(handle, "pfm_restart");
00157         pfm_read_pmds = (pfm_read_pmds_t) dlsym(handle, "pfm_read_pmds");
00158         pfm_initialize = (pfm_initialize_t) dlsym(handle, "pfm_initialize");
00159         pfm_find_full_event = (pfm_find_full_event_t) dlsym(handle, "pfm_find_full_event");
00160         pfm_dispatch_events = (pfm_dispatch_events_t) dlsym(handle, "pfm_dispatch_events");
00161         pfm_create_context = (pfm_create_context_t) dlsym(handle, "pfm_create_context");
00162         pfm_write_pmcs = (pfm_write_pmcs_t) dlsym(handle, "pfm_write_pmcs");
00163         pfm_write_pmds = (pfm_write_pmds_t) dlsym(handle, "pfm_write_pmds");
00164         pfm_load_context = (pfm_load_context_t) dlsym(handle, "pfm_load_context");
00165         pfm_strerror = (pfm_strerror_t) dlsym(handle, "pfm_strerror");
00166         pfm_set_options = (pfm_set_options_t) dlsym(handle, "pfm_set_options");
00167         pfm_get_num_counters = (pfm_get_num_counters_t) dlsym(handle, "pfm_get_num_counters");
00168       } else {
00169         // pfm_start = pfm_stop = pfm_self_stop = pfm_restart = pfm_read_pmds = pfm_initialize = pfm_find_full_event = pfm_dispatch_events = pfm_create_context = pfm_write_pmcs = pfm_write_pmds = pfm_load_context = pfm_strerror = pfm_set_options = pfm_get_num_counters = failure;
00170       }
00171     }
00172     ~PFMon() {
00173       if (handle) dlclose(handle);
00174     }
00175 
00176     static PFMon s_instance;
00177   };
00178 
00179   PFMon PFMon::s_instance;
00180 }
00181 
00182 
00183 
00184 // ============================================================================
00185 // GaudiAlg
00186 // ============================================================================
00187 // ============================================================================
00197 class PerfMonAuditor: virtual public Auditor
00198 {
00199  public:
00200   virtual void before(StandardEventType evt, INamedInterface* alg);
00201   virtual void after(StandardEventType evt, INamedInterface* alg, const StatusCode &sc);
00202   using Auditor::before;
00203   using Auditor::after;
00204 
00205  private:
00206   void i_beforeInitialize(INamedInterface* alg);
00207   void i_afterInitialize(INamedInterface* alg);
00208   void i_beforeExecute(INamedInterface* alg);
00209   void i_afterExecute(INamedInterface* alg);
00210 
00211  public:
00212   virtual StatusCode initialize();
00213   virtual StatusCode finalize();
00214   int is_nehalem() {
00215 #ifdef __ICC
00216 // Disable ICC remark #593: variable "x" was set but never used
00217 #pragma warning(push)
00218 #pragma warning(disable:593)
00219 #endif
00220     int a,b,c,d;
00221     cpuid(1,a,b,c,d);
00222     int sse4_2_mask = 1 << 20;
00223     if(c & sse4_2_mask) return 1; else return 0;
00224 #ifdef __ICC
00225 #pragma warning(pop)
00226 #endif
00227   }
00228 
00229  private:
00230   PFMon &m_pfm;
00231 /*
00232   typedef void (*pfm_stop_t)(int);
00233   pfm_stop_t pfm_stop;
00234   typedef void (*pfm_self_stop_t)(int);
00235   pfm_self_stop_t pfm_self_stop;
00236 
00237   typedef os_err_t (*pfm_restart_t)(int);
00238   pfm_restart_t pfm_restart;
00239 
00240   //typedef int (*pfm_read_pmds_t)(int, pfarg_pmd_t*, int);
00241   //pfm_read_pmds_t pfm_read_pmds;
00242 
00243   typedef pfm_err_t (*pfm_initialize_t)();
00244   pfm_initialize_t pfm_initialize;
00245   typedef pfm_err_t (*pfm_find_full_event_t)(const char *, pfmlib_event_t *);
00246   pfm_find_full_event_t pfm_find_full_event;
00247   typedef pfm_err_t (*pfm_dispatch_events_t)(pfmlib_input_param_t *, void *, pfmlib_output_param_t *, void *);
00248   pfm_dispatch_events_t pfm_dispatch_events;
00249   typedef os_err_t (*pfm_create_context_t)(pfarg_ctx_t *, char *, void *, size_t);
00250   pfm_create_context_t pfm_create_context;
00251   typedef os_err_t (*pfm_write_pmcs_t)(int, pfarg_pmc_t *, int);
00252   pfm_write_pmcs_t pfm_write_pmcs;
00253   typedef os_err_t (*pfm_write_pmds_t)(int, pfarg_pmd_t *, int);
00254   pfm_write_pmds_t pfm_write_pmds;
00255   typedef os_err_t (*pfm_load_context_t)(int, pfarg_load_t *);
00256   pfm_load_context_t pfm_load_context;
00257   typedef os_err_t (*pfm_start_t)(int fd, pfarg_start_t *);
00258   pfm_start_t pfm_start;
00259   typedef char* (*pfm_strerror_t)(int);
00260   pfm_strerror_t pfm_strerror;
00261   typedef pfm_err_t (*pfm_set_options_t)(pfmlib_options_t *);
00262   pfm_set_options_t pfm_set_options;
00263   typedef pfm_err_t (*pfm_get_num_counters_t)(unsigned int *);
00264   pfm_get_num_counters_t pfm_get_num_counters;
00265 */
00266 
00267 
00268  public:
00269   PerfMonAuditor(const std::string& name, ISvcLocator* pSvc):     // standard constructor
00270    Auditor(name, pSvc),
00271    m_pfm(PFMon::instance()),
00272    m_map(),
00273    m_indent(0),
00274    m_inEvent(false)
00275   {
00276 is_nehalem_ret = is_nehalem();
00277 declareProperty("EVENT0", event_str[0]);
00278 declareProperty("EVENT1", event_str[1]);
00279 declareProperty("EVENT2", event_str[2]);
00280 declareProperty("EVENT3", event_str[3]);
00281 declareProperty("FAMILY", family);
00282 declareProperty("PREFIX", prefix);
00283 declareProperty("INV0", inv[0]);
00284 declareProperty("INV1", inv[1]);
00285 declareProperty("INV2", inv[2]);
00286 declareProperty("INV3", inv[3]);
00287 declareProperty("CMASK0", cmask[0]);
00288 declareProperty("CMASK1", cmask[1]);
00289 declareProperty("CMASK2", cmask[2]);
00290 declareProperty("CMASK3", cmask[3]);
00291 declareProperty("SP0", sp[0]);
00292 declareProperty("SP1", sp[1]);
00293 declareProperty("SP2", sp[2]);
00294 declareProperty("SP3", sp[3]);
00295 declareProperty("SAMPLE", sampling);
00296 declareProperty("START_AT_EVENT", start_at_event);
00297 declareProperty("IS_NEHALEM", is_nehalem_ret);
00298 
00299 // MsgStream log(msgSvc(), name());
00300 
00302 /*
00303 // loading functions from PFM library
00304   void* handle = dlopen("libpfm.so", RTLD_NOW);
00305     if (!handle) {
00306 //      log << MSG::ERROR << "Cannot open library: " << dlerror() << endmsg;
00307     }
00308   typedef void (*hello_t)();
00309     hello_t hello = (hello_t) dlsym(handle, "hello");
00310     if (!hello) {
00311 //        log << MSG::ERROR << "Cannot load symbol 'hello': " << dlerror() << endmsg;
00312         dlclose(handle);
00313     }
00314 
00315     pfm_start = (pfm_start_t) dlsym(handle, "pfm_start");
00316     pfm_stop = (pfm_stop_t) dlsym(handle, "pfm_stop");
00317     pfm_self_stop = (pfm_self_stop_t) dlsym(handle, "pfm_stop"); //it's the same
00318     pfm_restart = (pfm_restart_t) dlsym(handle, "pfm_restart");
00319     //pfm_read_pmds = (pfm_read_pmds_t) dlsym(handle, "pfm_read_pmds");
00320     pfm_initialize = (pfm_initialize_t) dlsym(handle, "pfm_initialize");
00321     pfm_find_full_event = (pfm_find_full_event_t) dlsym(handle, "pfm_find_full_event");
00322     pfm_dispatch_events = (pfm_dispatch_events_t) dlsym(handle, "pfm_dispatch_events");
00323     pfm_create_context = (pfm_create_context_t) dlsym(handle, "pfm_create_context");
00324     pfm_write_pmcs = (pfm_write_pmcs_t) dlsym(handle, "pfm_write_pmcs");
00325     pfm_write_pmds = (pfm_write_pmds_t) dlsym(handle, "pfm_write_pmds");
00326     pfm_load_context = (pfm_load_context_t) dlsym(handle, "pfm_load_context");
00327     pfm_strerror = (pfm_strerror_t) dlsym(handle, "pfm_strerror");
00328     pfm_set_options = (pfm_set_options_t) dlsym(handle, "pfm_set_options");
00329     pfm_get_num_counters = (pfm_get_num_counters_t) dlsym(handle, "pfm_get_num_counters");
00330     // use it to do the calculation
00331 //    log << MSG::INFO << "Calling hello..." << endmsg;
00332 //    hello();
00333 
00334     // close the library
00335 //    log << MSG::INFO << "Closing library..." << endmsg;
00336     dlclose(handle);
00337 */
00338 
00340 
00341   }
00342 
00343   virtual ~PerfMonAuditor() {}                                    // virtual destructor
00344 
00345  private:
00346   PerfMonAuditor();                                               // the default constructor is disabled
00347   PerfMonAuditor(const PerfMonAuditor&);                          // copy constructor is disabled
00348   PerfMonAuditor& operator=(const PerfMonAuditor&);               // assignement operator is disabled
00349 
00350  private:
00351   typedef GaudiUtils::VectorMap<const INamedInterface*,int> Map;
00352   Map m_map;
00353   int m_indent;                                                   // indentation level
00354   bool m_inEvent;                                                 // "In event" flag
00355 
00356  private:
00357     int is_nehalem_ret;
00358 
00359     pfmlib_input_param_t inp;
00360     pfmlib_output_param_t outp;
00361     pfarg_ctx_t ctx;
00362     pfarg_pmd_t pd[NUM_PMDS];
00363     pfarg_pmc_t pc[NUM_PMCS];
00364     pfarg_load_t load_arg;
00365     int fd;
00366     unsigned int i;
00367     int ret;
00368     void startpm();
00369     void pausepm();
00370     void stoppm();
00371     void finalizepm();
00372     std::string event_str[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
00373     std::string prefix;
00374     std::string family;
00375     char event_cstr[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS][MAX_EVENT_NAME_LENGTH];
00376     char prefix_cstr[MAX_PREFIX_NAME_LENGTH];
00377     unsigned int ph_ev_count;
00378     bool inv[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
00379     unsigned int cmask[MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS];
00380     unsigned int start_at_event;
00381     pfmlib_core_input_param_t params;
00382     pfmlib_nhm_input_param_t nhm_params;
00383     int used_counters_number;
00384     bool nehalem;
00385     bool westmere;
00386     bool core;
00387 
00388     bool sampling;
00389     int detect_unavail_pmu_regs(int fd, pfmlib_regmask_t *r_pmcs, pfmlib_regmask_t *r_pmds);
00390     int detect_unavail_pmcs(int fd, pfmlib_regmask_t *r_pmcs){return detect_unavail_pmu_regs(fd, r_pmcs, NULL);}
00391     void pfm_bv_set(uint64_t *bv, uint16_t rnum){bv[rnum>>LBPL] |= 1UL << (rnum&(BPL-1));}
00392     int pfm_bv_isset(uint64_t *bv, uint16_t rnum){return bv[rnum>>LBPL] & (1UL <<(rnum&(BPL-1))) ? 1 : 0;}
00393     void pfm_bv_copy(uint64_t *d, uint64_t *j, uint16_t n){if(n<=BPL) *d = *j; else {memcpy(d, j, (n>>LBPL)*sizeof(uint64_t));}}
00394     static void process_smpl_buf(pfm_dfl_smpl_hdr_t *hdr, size_t entry_size);
00395     static void sigio_handler(int, struct siginfo *, struct sigcontext *); // dlopen ==>
00396     //void sigio_handler(int, struct siginfo *, struct sigcontext *);
00397     void start_smpl();
00398     void stop_smpl();
00399     void finalize_smpl();
00400     pfm_dfl_smpl_arg_t buf_arg;
00401     pfarg_load_t load_args;
00402     void *buf_addr;
00403     unsigned num_counters;
00404     unsigned int max_pmd;
00405     pfmlib_options_t pfmlib_options;
00406 
00407 
00408   int level;
00409 
00410   bool first_alg;
00411   std::string first_alg_name;
00412   bool event_count_reached;
00413 
00414 
00415 };
00416 
00417 void PerfMonAuditor::startpm()
00418 {
00419    MsgStream log(msgSvc(), name());
00420    memset(&ctx,0, sizeof(ctx));
00421    memset(&inp,0, sizeof(inp));
00422    memset(&outp,0, sizeof(outp));
00423    memset(pd, 0, sizeof(pd));
00424    memset(pc, 0, sizeof(pc));
00425    memset(&load_arg, 0, sizeof(load_arg));
00426    memset(&params, 0, sizeof(params));
00427    memset(&nhm_params, 0, sizeof(nhm_params));
00428 
00429    for(int i=0; i<used_counters_number; i++)
00430    {
00431     ret = m_pfm.pfm_find_full_event(event_cstr[i], &inp.pfp_events[i]);
00432     if(ret != PFMLIB_SUCCESS)
00433     {
00434      log << MSG::ERROR << "ERROR: cannot find event: " << event_cstr[i] << ". Aborting..." << endmsg;
00435     }
00436    }
00437    inp.pfp_dfl_plm = PFM_PLM3;
00438    inp.pfp_event_count = 4;
00439    for(int i=0; i<used_counters_number; i++)
00440    {
00441     if(inv[i])
00442     {
00443      (params.pfp_core_counters[i]).flags |= PFM_CORE_SEL_INV;
00444      (nhm_params.pfp_nhm_counters[i]).flags |= PFM_NHM_SEL_INV;
00445     }
00446     if(cmask[i]>0)
00447     {
00448      (params.pfp_core_counters[i]).cnt_mask = cmask[i];
00449      (nhm_params.pfp_nhm_counters[i]).cnt_mask = cmask[i];
00450     }
00451    }
00452    if(nehalem || westmere)
00453    {
00454     ret = m_pfm.pfm_dispatch_events(&inp, &nhm_params, &outp, NULL);
00455    }
00456    else
00457    {
00458     ret = m_pfm.pfm_dispatch_events(&inp, &params, &outp, NULL);
00459    }
00460    if(ret != PFMLIB_SUCCESS)
00461    {
00462     log << MSG::ERROR << "ERROR: cannot dispatch events: " << m_pfm.pfm_strerror(ret) << ". Aborting..." << endmsg;
00463    }
00464    for(unsigned int i=0; i<outp.pfp_pmc_count; i++)
00465    {
00466     pc[i].reg_num = outp.pfp_pmcs[i].reg_num;
00467     pc[i].reg_value = outp.pfp_pmcs[i].reg_value;
00468    }
00469    for(unsigned int i=0; i<outp.pfp_pmd_count; i++)
00470    {
00471     pd[i].reg_num = outp.pfp_pmds[i].reg_num;
00472     pd[i].reg_value = 0;
00473    }
00474    fd = m_pfm.pfm_create_context(&ctx, NULL, 0, 0);
00475    if(fd == -1)
00476    {
00477     log << MSG::ERROR << "ERROR: Context not created. Aborting..." << endmsg;
00478    }
00479    if(m_pfm.pfm_write_pmcs(fd, pc, outp.pfp_pmc_count) == -1)
00480    {
00481     log << MSG::ERROR << "ERROR: Could not write pmcs. Aborting..." << endmsg;
00482    }
00483    if(m_pfm.pfm_write_pmds(fd, pd, outp.pfp_pmd_count) == -1)
00484    {
00485     log << MSG::ERROR << "ERROR: Could not write pmds. Aborting..." << endmsg;
00486    }
00487    load_arg.load_pid = getpid();
00488    if(m_pfm.pfm_load_context(fd, &load_arg) == -1)
00489    {
00490     log << MSG::ERROR << "ERROR: Could not load context. Aborting..." << endmsg;
00491 //  MsgStream log(msgSvc(), name());
00492 //  log << MSG::ERROR << "Could not read pmds" << endmsg;
00493    }
00494 
00495    m_pfm.pfm_start(fd, NULL);
00496 }
00497 
00498 
00499 
00500 
00501 
00502    // stoppm()
00503    // const ModuleDescription& desc : description of the module that just finished its execution (we are only interested in its name)
00504    // stops the counting calling pfm_stop() and stores the counting results into the "results" map
00505 void PerfMonAuditor::stoppm()
00506 {
00507  MsgStream log(msgSvc(), name());
00508  m_pfm.pfm_stop(fd);
00509  if(m_pfm.pfm_read_pmds(fd, pd, inp.pfp_event_count) == -1)
00510  {
00511   log << MSG::ERROR << "Could not read pmds" << endmsg;
00512  }
00513    for(int i=0; i<used_counters_number; i++)
00514    {
00515  results[i][(alg_stack.top().first)->name()].push_back(alg_stack.top().second[i] + pd[i].reg_value);
00516    }
00517 
00518  close(fd);
00519 }
00520 
00521 
00522 void PerfMonAuditor::pausepm()
00523 {
00524  MsgStream log(msgSvc(), name());
00525  m_pfm.pfm_stop(fd);
00526  if(m_pfm.pfm_read_pmds(fd, pd, inp.pfp_event_count) == -1)
00527  {
00528   log << MSG::ERROR << "Could not read pmds" << endmsg;
00529  }
00530 
00531    for(int i=0; i<used_counters_number; i++)
00532    {
00533  alg_stack.top().second[i] += pd[i].reg_value;
00534    }
00535 
00536  close(fd);
00537 }
00538 
00539 
00540    // finalizepm()
00541    // called when all the countings of the current event are finished, it dumps the results
00542    // into the output file corresponding to the event being counted
00543 void PerfMonAuditor::finalizepm()
00544 {
00545  MsgStream log(msgSvc(), name());
00546    log << MSG::INFO << "start of finalizepm ucn:" << used_counters_number << endmsg;
00547    char filename[MAX_OUTPUT_FILENAME_LENGTH];
00548    char to_cat[50];
00549    FILE *outfile;
00550    for(int i=0; i<used_counters_number; i++)
00551    {
00552     bzero(filename, MAX_OUTPUT_FILENAME_LENGTH);
00553     sprintf(filename, "%s_%s", prefix_cstr, event_cstr[i]);
00554     for(int j=0; j<(int)strlen(filename); j++)
00555     {
00556      if(filename[j]==':')
00557      {
00558       filename[j]='-';
00559      }
00560     }
00561     bzero(to_cat, 50);
00562     if(inv[i])
00563     {
00564      strcpy(to_cat, "_INV_1");
00565     }
00566     if(cmask[i]>0)
00567     {
00568      sprintf(to_cat, "%s_CMASK_%d", to_cat, cmask[i]);
00569     }
00570     sprintf(filename, "%s%s.txt", filename, to_cat);
00571     log << MSG::INFO << "Filename:" << filename << endmsg;
00572     outfile = fopen(filename, "w");
00573     if(nehalem)
00574     {
00575      fprintf(outfile, "NHM ");
00576     }
00577     else if(westmere)
00578     {
00579      fprintf(outfile, "WSM ");
00580     }
00581     else if(core)
00582     {
00583      fprintf(outfile, "CORE ");
00584     }
00585     fprintf(outfile, "%s %d %d %d\n", event_cstr[i], cmask[i], inv[i], sp[i]);
00586     for(std::map<std::string, std::vector<unsigned long int> >::iterator it=(results[i]).begin(); it!=(results[i]).end(); it++)
00587     {
00588      fprintf(outfile, "%s\n", (it->first).c_str());
00589      for(std::vector<unsigned long int>::iterator j=(it->second).begin(); j!=(it->second).end(); j++)
00590      {
00591       fprintf(outfile, "%lu\n", *j);
00592      }
00593     }
00594     fclose(outfile);
00595    }
00596 }
00597 
00598 StatusCode PerfMonAuditor::initialize()
00599 {
00600  MsgStream log(msgSvc(), name());
00601 
00602  if (!m_pfm.loaded) {
00603   log << MSG::ERROR << "pfm library could not be loaded" << endmsg;
00604   return false;
00605  }
00606 
00607  log << MSG::INFO << "Initializing..." << endmsg;
00608  StatusCode sc = Auditor::initialize() ;
00609  if(sc.isFailure())
00610  {
00611   return sc;
00612  }
00613    used_counters_number = 0;
00614    for(int i=0; i<MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS; i++)
00615    {
00616     if(event_str[i].length()>0) used_counters_number++;
00617    }
00618    for(int i=0; i<MAX_NUMBER_OF_PROGRAMMABLE_COUNTERS; i++)
00619    {
00620     strcpy(event_cstr[i], event_str[i].c_str());
00621    }
00622    strcpy(prefix_cstr, prefix.c_str());
00623 
00624  if(m_pfm.pfm_initialize() != PFMLIB_SUCCESS)
00625  {
00626  log << MSG::ERROR << "Cannot initialize perfmon!!" << endmsg;
00627  }
00628  ph_ev_count = 0;
00629  first_alg = true;
00630  event_count_reached = false;
00631  nehalem = false;
00632  core = false;
00633  westmere = false;
00634  if(family.compare("CORE")==0) core = true;
00635  else if(family.compare("NEHALEM")==0) nehalem = true;
00636  else if(family.compare("WESTMERE")==0) westmere = true;
00637  else
00638  {
00639   log << MSG::ERROR << "ERROR: Unsupported processor family " << family  << ". aborting..." << endmsg;
00640  }
00641 
00642  log << MSG::INFO << "Initialized!" << endmsg;
00643  return StatusCode::SUCCESS ;
00644 }
00645 
00646    // process_smpl_buf()
00647    // pfm_dfl_smpl_hdr_t *hdr : pointer to header of the buffer containing addresses sampled during the sampling process
00648    // size_t entry_size       : size of each entry, used to navigate through the various entries
00649    // called when the sampling buffer is full, saves the samples into memory ("samples" map)
00650 void PerfMonAuditor::process_smpl_buf(pfm_dfl_smpl_hdr_t *hdr, size_t entry_size)
00651 {
00653    pfm_dfl_smpl_entry_t *ent;
00654    size_t pos, count;
00655    uint64_t entry;
00656    if(hdr->hdr_overflows == last_overflow && hdr->hdr_count == last_count)
00657    {
00658     printf("skipping identical set of samples...\n");
00659     return;
00660    }
00661    count = hdr->hdr_count;
00662    ent = (pfm_dfl_smpl_entry_t *)(hdr+1);
00663    pos = (unsigned long)ent;
00664    entry = collected_samples;
00665    while(count--)
00666    {
00667     //if(ent->ovfl_pmd>=0 && ent->ovfl_pmd<=3)
00668     if(ent->ovfl_pmd<=3)
00669     {
00670      ((samples[ent->ovfl_pmd])[(alg_stack.top().first)->name()])[(unsigned long)(ent->ip)]++;
00671     }
00672     pos += entry_size;
00673     ent = (pfm_dfl_smpl_entry_t *)pos;
00674     entry++;
00675    }
00676    collected_samples = entry;
00677    last_overflow = hdr->hdr_overflows;
00678    if (last_count != hdr->hdr_count && (last_count || last_overflow == 0))
00679    {
00680     collected_partial += hdr->hdr_count;
00681    }
00682    last_count = hdr->hdr_count;
00683  return;
00684 }
00685 
00686    // sigio_handler()
00687    // int n                 : signal number of the signal being delivered
00688    // struct siginfo *info  : pointer to a siginfo_t structure containing info about the signal
00689    // struct sigcontext *sc : context of the signal, NULL in our case
00690    // signal handler used to catch sampling buffer overflows. When they occur it calls the process_smpl_buf() function
00691 void PerfMonAuditor::sigio_handler(int /*n*/, struct siginfo */*info*/, struct sigcontext */*sc*/)
00692 {
00693    //MsgStream log(msgSvc(), name());
00694    PFMon& pfm = PFMon::instance();
00695    pfarg_msg_t msg;
00696    int fd = ctx_fd;
00697    int r;
00698    if(fd != ctx_fd)
00699    {
00700     //log << MSG::ERROR << "ERROR: handler does not get valid file descriptor. Aborting..." << endmsg;
00701    }
00702    if(pfm.pfm_read_pmds(fd, pd_smpl+1, 1) == -1)
00703    {
00704     //log << MSG::ERROR << "ERROR: pfm_read_pmds: " << strerror(errno) << ". Aborting..." << endmsg;
00705    }
00706    while(true)
00707    {
00708     r = read(fd, &msg, sizeof(msg));
00709     if(r!=sizeof(msg))
00710     {
00711      if(r==-1 && errno==EINTR)
00712      {
00713       printf("read interrupted, retrying\n");
00714       continue;
00715      }
00716      //log << MSG::ERROR << "ERROR: cannot read overflow message: " << strerror(errno) << ". Aborting..." << endmsg;
00717     }
00718     break;
00719    }
00720    switch(msg.type)
00721    {
00722     case PFM_MSG_OVFL: // the sampling buffer is full
00723      process_smpl_buf(hdr, entry_size);
00724      ovfl_count++;
00725      if(pfm.pfm_restart(fd))
00726      {
00727       if(errno!=EBUSY)
00728       {
00729        //log << MSG::ERROR << "ERROR: pfm_restart error errno " << errno << ". Aborting..." << endmsg;
00730       }
00731       else
00732       {
00733        printf("pfm_restart: task probably terminated \n");
00734       }
00735      }
00736      break;
00737     default:
00738      //log << MSG::ERROR << "ERROR: unknown message type " << msg.type << ". Aborting..." << endmsg;
00739      break;
00740    }
00741 
00742 }
00743 
00744 
00745 
00746 
00747 
00748 
00749 
00750    // start_smpl()
00751    // const ModuleDescription& desc : description of the module that is just starting its execution (we are only interested in its name)
00752    // initializes all the necessary structures to start the sampling, calling pfm_self_start()
00753 void PerfMonAuditor::start_smpl()
00754 {
00755    MsgStream log(msgSvc(), name());
00756    ovfl_count = 0;
00757    num_smpl_pmds = 0;
00758    last_overflow = ~0;
00759    max_pmd = 0;
00760    memset(&pfmlib_options, 0, sizeof(pfmlib_options));
00761    pfmlib_options.pfm_debug   = 0;
00762    pfmlib_options.pfm_verbose = 0;
00763    m_pfm.pfm_set_options(&pfmlib_options);
00764    ret = m_pfm.pfm_initialize();
00765    if(ret != PFMLIB_SUCCESS)
00766    {
00767     log << MSG::ERROR << "ERROR: Cannot initialize library: " << m_pfm.pfm_strerror(ret) << ". Aborting..." << endmsg;
00768    }
00769    struct sigaction act;
00770    memset(&act, 0, sizeof(act));
00771    act.sa_handler = (sig_t)sigio_handler; // dlopen() ==>
00772    //act.sa_handler = (sig_t)&sigio_handler;
00773    sigaction(SIGIO, &act, 0);
00774    memset(&ctx, 0, sizeof(ctx));
00775    memset(&buf_arg, 0, sizeof(buf_arg));
00776    memset(&inp,0, sizeof(inp));
00777    memset(&outp,0, sizeof(outp));
00778    memset(pd_smpl, 0, sizeof(pd_smpl));
00779    memset(pc, 0, sizeof(pc));
00780    memset(&load_args, 0, sizeof(load_args));
00781    m_pfm.pfm_get_num_counters(&num_counters);
00782    memset(&params, 0, sizeof(params));
00783    memset(&nhm_params, 0, sizeof(nhm_params));
00784 
00785    for(int i=0; i<used_counters_number; i++)
00786    {
00787     ret = m_pfm.pfm_find_full_event(event_cstr[i], &inp.pfp_events[i]);
00788     if(ret != PFMLIB_SUCCESS)
00789     {
00790      log << MSG::ERROR << "ERROR: cannot find event: " << event_cstr[i] << ". Aborting..." << endmsg;
00791     }
00792    }
00793    inp.pfp_dfl_plm = PFM_PLM3;
00794    inp.pfp_event_count = 4;
00795    for(int i=0; i<used_counters_number; i++)
00796    {
00797     if(inv[i])
00798     {
00799      (params.pfp_core_counters[i]).flags |= PFM_CORE_SEL_INV;
00800      (nhm_params.pfp_nhm_counters[i]).flags |= PFM_NHM_SEL_INV;
00801     }
00802     if(cmask[i]>0)
00803     {
00804      (params.pfp_core_counters[i]).cnt_mask = cmask[i];
00805      (nhm_params.pfp_nhm_counters[i]).cnt_mask = cmask[i];
00806     }
00807    }
00808    if(nehalem || westmere)
00809    {
00810     ret = m_pfm.pfm_dispatch_events(&inp, &nhm_params, &outp, NULL);
00811    }
00812    else
00813    {
00814     ret = m_pfm.pfm_dispatch_events(&inp, &params, &outp, NULL);
00815    }
00816    if(ret != PFMLIB_SUCCESS)
00817    {
00818     log << MSG::ERROR << "ERROR: cannot configure events: " << m_pfm.pfm_strerror(ret) << ". Aborting..." << endmsg;
00819    }
00820    for(unsigned int i=0; i<outp.pfp_pmc_count; i++)
00821    {
00822     pc[i].reg_num   = outp.pfp_pmcs[i].reg_num;
00823     pc[i].reg_value = outp.pfp_pmcs[i].reg_value;
00824    }
00825    for(unsigned int i=0; i<outp.pfp_pmd_count; i++)
00826    {
00827     pd_smpl[i].reg_num = outp.pfp_pmds[i].reg_num;
00828     if(i)
00829     {
00830      pfm_bv_set(pd_smpl[0].reg_smpl_pmds, pd_smpl[i].reg_num);
00831      if(pd_smpl[i].reg_num>max_pmd)
00832      {
00833       max_pmd = pd_smpl[i].reg_num;
00834      }
00835      num_smpl_pmds++;
00836     }
00837    }
00838    for(int i=0; i<used_counters_number; i++)
00839    {
00840     pd_smpl[i].reg_flags |= PFM_REGFL_OVFL_NOTIFY | PFM_REGFL_RANDOM;
00841     pfm_bv_copy(pd_smpl[i].reg_reset_pmds, pd_smpl[i].reg_smpl_pmds, max_pmd);
00842     pd_smpl[i].reg_value = (uint64_t)(sp[i] * -1);
00843     pd_smpl[i].reg_short_reset = (uint64_t)(sp[i] * -1);
00844     pd_smpl[i].reg_long_reset = (uint64_t)(sp[i] * -1);
00845     pd_smpl[i].reg_random_seed = 5; //tocheck
00846     pd_smpl[i].reg_random_mask = 0xff; //tocheck
00847    }
00848    entry_size = sizeof(pfm_dfl_smpl_entry_t)+(num_smpl_pmds<<3);
00849    ctx.ctx_flags = 0;
00850    buf_arg.buf_size = 3*getpagesize()+512;
00851    ctx_fd = m_pfm.pfm_create_context(&ctx, (char *)FMT_NAME, &buf_arg, sizeof(buf_arg));
00852    if(ctx_fd==-1)
00853    {
00854     if(errno==ENOSYS)
00855     {
00856      log << MSG::ERROR << "ERROR: Your kernel does not have performance monitoring support! Aborting..." << endmsg;
00857     }
00858     log << MSG::ERROR << "ERROR: Can't create PFM context " << strerror(errno) << ". Aborting..." << endmsg;
00859    }
00860    buf_addr = mmap(NULL, (size_t)buf_arg.buf_size, PROT_READ, MAP_PRIVATE, ctx_fd, 0);
00861    if(buf_addr==MAP_FAILED)
00862    {
00863     log << MSG::ERROR << "ERROR: cannot mmap sampling buffer: " << strerror(errno) << ". Aborting..." << endmsg;
00864    }
00865    hdr = (pfm_dfl_smpl_hdr_t *)buf_addr;
00866    if(PFM_VERSION_MAJOR(hdr->hdr_version)<1)
00867    {
00868     log << MSG::ERROR << "ERROR: invalid buffer format version. Aborting..." << endmsg;
00869    }
00870    if(m_pfm.pfm_write_pmcs(ctx_fd, pc, outp.pfp_pmc_count))
00871    {
00872     log << MSG::ERROR << "ERROR: pfm_write_pmcs error errno " << strerror(errno) << ". Aborting..." << endmsg;
00873    }
00874    if(m_pfm.pfm_write_pmds(ctx_fd, pd_smpl, outp.pfp_pmd_count))
00875    {
00876     log << MSG::ERROR << "ERROR: pfm_write_pmds error errno " << strerror(errno) << ". Aborting..." << endmsg;
00877    }
00878    load_args.load_pid = getpid();
00879    if(m_pfm.pfm_load_context(ctx_fd, &load_args))
00880    {
00881     log << MSG::ERROR << "ERROR: pfm_load_context error errno " << strerror(errno) << ". Aborting..." << endmsg;
00882    }
00883    ret = fcntl(ctx_fd, F_SETFL, fcntl(ctx_fd, F_GETFL, 0) | O_ASYNC);
00884    if(ret == -1)
00885    {
00886     log << MSG::ERROR << "ERROR: cannot set ASYNC: " << strerror(errno) << ". Aborting..." << endmsg;
00887    }
00888    ret = fcntl(ctx_fd, F_SETOWN, getpid());
00889    if(ret == -1)
00890    {
00891     log << MSG::ERROR << "ERROR: cannot setown: " << strerror(errno) << ". Aborting..." << endmsg;
00892    }
00893    //pfm_self_start(ctx_fd); ==>
00894    m_pfm.pfm_start(ctx_fd, NULL);
00895   }
00896 
00897 
00898    // stop_smpl()
00899    // const ModuleDescription& desc : description of the module that just finished its execution (we are only interested in its name)
00900    // stops the sampling and calls process_smpl_buf() one last time to process all the remaining samples
00901 void PerfMonAuditor::stop_smpl()
00902   {
00903  MsgStream log(msgSvc(), name());
00904    m_pfm.pfm_self_stop(ctx_fd);
00905    process_smpl_buf(hdr, entry_size);
00906    close(ctx_fd);
00907    ret = munmap(hdr, (size_t)buf_arg.buf_size);
00908    if(ret)
00909    {
00910   log << MSG::ERROR << "Cannot unmap buffer: %s" << strerror(errno) << endmsg;
00911    }
00912    return;
00913   }
00914 
00915 
00916 
00917    // finalize_smpl()
00918    // processes the sampling results in order to find library and offset of each sampled address, using the symbol() and tosymbol() functions,
00919    // and then dumps the new found information into gzipped output files, to be processed later
00920 void PerfMonAuditor::finalize_smpl()
00921 {
00922    MsgStream log(msgSvc(), name());
00923    char filename[MAX_OUTPUT_FILENAME_LENGTH];
00924    bzero(filename, MAX_OUTPUT_FILENAME_LENGTH);
00925    char to_cat[50];
00926    gzFile outfile;
00927    int err;
00928    for(int i=0; i<used_counters_number; i++)
00929    {
00930     sprintf(filename, "%s_%s", prefix_cstr, event_cstr[i]);
00931     for(int j=0; j<(int)strlen(filename); j++)
00932     {
00933      if(filename[j]==':')
00934      {
00935       filename[j]='-';
00936      }
00937     }
00938     bzero(to_cat, 50);
00939     if(inv[i])
00940     {
00941      strcpy(to_cat, "_INV_1");
00942     }
00943     if(cmask[i]>0)
00944     {
00945      sprintf(to_cat, "%s_CMASK_%d", to_cat, cmask[i]);
00946     }
00947     sprintf(filename, "%s%s.txt.gz", filename, to_cat);
00948     outfile = gzopen(filename, "wb");
00949     if(outfile!=NULL)
00950     {
00951      if(nehalem)
00952      {
00953       gzprintf(outfile, "NHM ");
00954      }
00955      else if(westmere)
00956      {
00957       gzprintf(outfile, "WSM ");
00958      }
00959      else if(core)
00960      {
00961       gzprintf(outfile, "CORE ");
00962      }
00963      if(gzprintf(outfile, "%s %d %d %d\n", event_cstr[i], cmask[i], inv[i], sp[i]) < (int)strlen(event_cstr[i]))
00964      {
00965       log << MSG::ERROR << "ERROR: gzputs err: " << gzerror(outfile, &err) << ". Aborting..." << endmsg;
00966      }
00967      for(std::map<std::string, std::map<unsigned long, unsigned int> >::iterator it=samples[i].begin(); it!=samples[i].end(); it++)
00968      {
00969       unsigned long long sum = 0;
00970       for(std::map<unsigned long, unsigned int>::iterator jt=(it->second).begin(); jt!=(it->second).end(); jt++)
00971       {
00972        sum += jt->second;
00973       }
00974       if(gzprintf(outfile, "%s%%%llu\n", (it->first).c_str(), sum) < (int)((it->first).length()))
00975       {
00976        log << MSG::ERROR << "ERROR: gzputs err: " << gzerror(outfile, &err) << ". Aborting..." << endmsg;
00977       }
00978       for(std::map<unsigned long, unsigned int>::iterator jt=(it->second).begin(); jt!=(it->second).end(); jt++)
00979       {
00980        char sym_name[SYM_NAME_MAX_LENGTH];
00981        bzero(sym_name, SYM_NAME_MAX_LENGTH);
00982        const char *libName;
00983        const char *symbolName;
00984        int libOffset = 0;
00985        int offset = 0;
00986        void *sym_addr = IgHookTrace::tosymbol((void *)(jt->first));
00987        if(sym_addr != NULL)
00988        {
00989         bool success = IgHookTrace::symbol(sym_addr, symbolName, libName, offset, libOffset);
00990         if(success)
00991         {
00992          if(symbolName!=NULL && strlen(symbolName)>0)
00993          {
00994           strcpy(sym_name, symbolName);
00995           strcat(sym_name, " ");
00996          }
00997          else
00998          {
00999           strcpy(sym_name, "??? ");
01000          }
01001          if(libName!=NULL && strlen(libName)>0)
01002          {
01003           strcat(sym_name, libName);
01004           strcat(sym_name, " ");
01005          }
01006          else
01007          {
01008           strcat(sym_name, "??? ");
01009          }
01010          sprintf(sym_name, "%s%d ", sym_name, libOffset);
01011          if(strlen(sym_name)<=0)
01012          {
01013           log << MSG::ERROR << "ERROR: Symbol name length is zero. Aborting..." << endmsg;
01014          }
01015         }
01016         else
01017         {
01018          strcpy(sym_name,"??? ??? 0 ");
01019         }
01020        }
01021        else
01022        {
01023         strcpy(sym_name,"??? ??? 0 ");
01024        }
01025        if(gzprintf(outfile, "%s %d\n", sym_name, jt->second) < (int)strlen(sym_name))
01026        {
01027         log << MSG::ERROR << "ERROR: gzputs err: " << gzerror(outfile, &err) << endmsg;
01028        }
01029       }
01030      }
01031     }
01032     else
01033     {
01034      log << MSG::ERROR << "ERROR: Could not open file: " << filename << ". Aborting..." << endmsg;
01035     }
01036     gzclose(outfile);
01037    }
01038   }
01039 
01040 
01041 
01042 StatusCode PerfMonAuditor::finalize()
01043 {
01044  if(sampling == 0) finalizepm();
01045  else finalize_smpl();
01046  return Auditor::finalize();
01047 }
01048 
01049 
01050 void PerfMonAuditor::before(StandardEventType evt, INamedInterface *alg)
01051 {
01052  switch(evt)
01053  {
01054   case IAuditor::Initialize:
01055    i_beforeInitialize(alg);
01056    break;
01057   case IAuditor::Execute:
01058    i_beforeExecute(alg);
01059    break;
01060   default:
01061    break;
01062  }
01063  return;
01064 }
01065 
01066 void PerfMonAuditor::after(StandardEventType evt, INamedInterface *alg, const StatusCode &)
01067 {
01068  switch(evt)
01069  {
01070   case IAuditor::Initialize:
01071    i_afterInitialize(alg);
01072    break;
01073   case IAuditor::Execute:
01074    i_afterExecute(alg);
01075    break;
01076   default:
01077    break;
01078  }
01079  return;
01080 }
01081 
01082 void PerfMonAuditor::i_beforeInitialize(INamedInterface* alg)
01083 {
01084  if(alg == 0)
01085  {
01086   return;
01087  }
01088  return;
01089 }
01090 
01091 void PerfMonAuditor::i_afterInitialize(INamedInterface* alg)
01092 {
01093  if(alg == 0)
01094  {
01095   return;
01096  }
01097  return;
01098 }
01099 
01100 void PerfMonAuditor::i_beforeExecute(INamedInterface* alg)
01101 {
01102  MsgStream log(msgSvc(), name());
01103  if(alg == 0)
01104  {
01105   return;
01106  }
01107  //log << MSG::INFO << "before:inside! " << alg->name() << endmsg;
01108  if(first_alg)
01109  {
01110   first_alg = false;
01111   first_alg_name = alg->name();
01112   //log << MSG::INFO << "first_alg_name= " << alg->name() << endmsg;
01113  }
01114  if(!event_count_reached)
01115  {
01116   if(!first_alg_name.compare(alg->name()))
01117   {
01118    ph_ev_count++;
01119    //log << MSG::INFO << "EVENT COUNT: " << ph_ev_count << endmsg;
01120    if(ph_ev_count==start_at_event)
01121    {
01122     event_count_reached = true;
01123     //log << MSG::INFO << "!!! EVENT COUNT REACHED: " << ph_ev_count << endmsg;
01124    }
01125   }
01126  }
01127  if(event_count_reached)
01128  {
01129    //log << MSG::INFO << "before:inside! " << alg->name() << endmsg;
01130 
01131   if(!alg_stack.empty())
01132   {
01133    if(sampling == 0) pausepm(); //pausing father algorithm counting
01134    else stop_smpl();
01135   }
01136   ++m_indent;
01137   std::vector <unsigned long int> zeroes(4,0);
01138   alg_stack.push(std::make_pair(alg, zeroes));
01139   if(sampling == 0) startpm();
01140   else start_smpl();
01141  }
01142  return;
01143 }
01144 
01145 void PerfMonAuditor::i_afterExecute(INamedInterface* alg)
01146 {
01147  MsgStream log(msgSvc(), name());
01148  if(alg == 0)
01149  {
01150   return;
01151  }// log << MSG::INFO << "after:inside! " << alg->name() << endmsg;
01152 
01153  if(event_count_reached)
01154  {
01155    //log << MSG::INFO << "after:inside! " << alg->name() << endmsg;
01156 
01157   if(sampling == 0) stoppm();
01158   else stop_smpl();
01159   alg_stack.pop();
01160   --m_indent;
01161   if(!alg_stack.empty())
01162   {
01163    if(sampling == 0) startpm();
01164    else start_smpl(); //resuming father algorithm counting
01165    }
01166  }
01167  return;
01168 }
01169 
01170 DECLARE_AUDITOR_FACTORY(PerfMonAuditor)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Feb 28 2011 18:27:17 for Gaudi Framework, version v22r1 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004