Gaudi Framework, version v23r2

Home   Generated: Thu Jun 28 2012

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

Generated at Thu Jun 28 2012 23:27:27 for Gaudi Framework, version v23r2 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004