| # Gaudi Framework, version v20r3
Generated: 24 Nov 2008

# TimingAuditor.cpp

Go to the documentation of this file.

    00001 // $Id: TimingAuditor.cpp,v 1.5 2008/04/05 08:04:22 marcocle Exp $
    00002 // ============================================================================
    00003 // CVS tag $Name: v11r2 $, version $Revision: 1.5 $
    00004 // ============================================================================
    00005 #include "GaudiKernel/Auditor.h"
    00006 #include "GaudiKernel/IToolSvc.h"
    00007 #include "GaudiKernel/INamedInterface.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 // GaudiAlg
    00017 // ============================================================================
    00018 #include "GaudiAlg/ISequencerTimerTool.h"
    00019 // ============================================================================
    00029 class TimingAuditor
    00030   : public virtual IIncidentListener
    00031   , public                   Auditor
    00032 {
    00033 public:
    00034
    00035   virtual void before(StandardEventType evt, INamedInterface* alg);
    00036   virtual void after(StandardEventType evt, INamedInterface* alg, const StatusCode &sc);
    00037
    00038   virtual void before(CustomEventTypeRef evt, const std::string& name);
    00039   virtual void after(CustomEventTypeRef evt, const std::string& name, const StatusCode &sc);
    00040
    00041 private:
    00042   void i_beforeInitialize( INamedInterface* alg );
    00043   void i_afterInitialize( INamedInterface* alg );
    00044   void i_beforeExecute( INamedInterface* alg );
    00045   void i_afterExecute( INamedInterface* alg);
    00046
    00047 public:
    00049   virtual void handle ( const Incident& ) ;
    00050
    00051 public:
    00052   virtual StatusCode initialize () ;
    00053   virtual StatusCode finalize   () ;
    00054   virtual StatusCode queryInterface( const InterfaceID& riid,
    00055                                      void** ppvInterface ) ;
    00056 public:
    00058   TimingAuditor
    00059   ( const std::string& name ,
    00060     ISvcLocator*       pSvc )
    00061     : Auditor ( name , pSvc )
    00062     //
    00063     , m_toolSvc    ( 0 )
    00064     , m_incSvc     ( 0 )
    00065     //
    00066     , m_timer      ( 0 )
    00067     //
    00068     , m_appMgr     ( 0 )
    00069     //
    00070     , m_map        (       )
    00071     , m_indent     ( 0     )
    00072     , m_inEvent    ( false )
    00073     , m_goodForDOD ( false )
    00074     , m_mapUser    (       )
    00075   {
    00076     declareProperty ( "OptimizedForDOD" , m_goodForDOD ) ;
    00077   } ;
    00079   virtual ~TimingAuditor() {}
    00080 private:
    00081   // the default constructor is disabled
    00082   TimingAuditor () ;
    00083   // copy constructor is disabled
    00084   TimingAuditor           ( const TimingAuditor& ) ;
    00085   // assignement operator is disabled
    00086   TimingAuditor& operator=( const TimingAuditor& ) ;
    00087 private:
    00088   // tool service
    00089   IToolSvc*            m_toolSvc ;
    00090   // incident service
    00091   IIncidentSvc*        m_incSvc  ;
    00092   // the timer tool
    00093   ISequencerTimerTool* m_timer   ;
    00094   // ApplicationManager
    00095   INamedInterface*     m_appMgr  ;
    00096   //
    00097   typedef GaudiUtils::VectorMap<const INamedInterface*,int>  Map ;
    00098   Map                  m_map     ;
    00099   // indentation level
    00100   int                  m_indent  ;
    00101   // "in event"
    00102   bool                 m_inEvent ;
    00103   // "optimized for Data-On-Demand Service"
    00104   bool                 m_goodForDOD ;
    00105   //
    00106   typedef GaudiUtils::HashMap<std::string,int> MapUser ;
    00107   MapUser              m_mapUser ;
    00108
    00109 } ;
    00110 // ============================================================================
    00112 // ============================================================================
    00113 DECLARE_AUDITOR_FACTORY(TimingAuditor) ;
    00114 // ============================================================================
    00115 StatusCode TimingAuditor::queryInterface
    00116 ( const InterfaceID& riid,
    00117   void** ppv )
    00118 {
    00119   if      ( 0 == ppv ) { return StatusCode::FAILURE ; }  // RETURN
    00120   else if ( IIncidentListener::interfaceID() == riid )
    00121   { *ppv = static_cast<IIncidentListener*> ( this ) ; }
    00122   else
    00123   { return Auditor::queryInterface( riid , ppv ) ; } // RETURN
    00124   addRef() ;
    00125   return StatusCode::SUCCESS ;
    00126 } ;
    00127 // ============================================================================
    00128 StatusCode TimingAuditor::initialize ()
    00129 {
    00130   StatusCode sc = Auditor::initialize() ;
    00131   if ( sc.isFailure() ) { return sc ; }                  // RETURN
    00132
    00133   MsgStream log ( msgSvc() , name() ) ;
    00134
    00135   // get tool service
    00136   if ( 0 == m_toolSvc )
    00137   {
    00138     StatusCode sc = Auditor::service ( "ToolSvc" , m_toolSvc ) ;
    00139     if ( sc.isFailure() )
    00140     {
    00141       log << "Could not retrieve 'ToolSvc' " << sc << endreq ;
    00142       return sc ;                                        // RETURN
    00143     }
    00144     if ( 0 == m_timer )
    00145     {
    00146       sc = m_toolSvc->retrieveTool
    00147         ( "SequencerTimerTool/TIMER" , m_timer , this  , true ) ;
    00148       if ( sc.isFailure() )
    00149       {
    00150         log << MSG::ERROR
    00151             << "Could not retrieve ISequencerTimerTool" << endreq ;
    00152         return sc ;
    00153       }
    00154     }
    00155   }
    00156   // get incident service
    00157   if ( 0 == m_incSvc )
    00158   {
    00159     StatusCode sc = Auditor::service ( "IncidentSvc" , m_incSvc ) ;
    00160     if ( sc.isFailure() )
    00161     {
    00162       log << MSG::ERROR
    00163           << "Could not retrieve 'IncidentSvc'" << sc << endreq ;
    00164       return sc ;
    00165     }
    00166     m_incSvc -> addListener ( this , IncidentType::BeginEvent ) ;
    00167     m_incSvc -> addListener ( this , IncidentType::EndEvent   ) ;
    00168   }
    00169   // get the application manager
    00170   if ( 0 == m_appMgr )
    00171   {
    00172     StatusCode sc = Auditor::service ( "ApplicationMgr" , m_appMgr ) ;
    00173     if ( sc.isFailure() )
    00174     {
    00175       log << MSG::ERROR
    00176           << "Could not retrieve 'ApplicationMgr'" << sc << endreq ;
    00177       return sc ;
    00178     }
    00179     if ( m_map.end() == m_map.find( m_appMgr ) )
    00180     {
    00181       int timer = m_timer->addTimer( "EVENT LOOP" ) ;
    00182       m_map.insert ( m_appMgr , timer ) ;
    00183     }
    00184   }
    00185   //
    00186   return StatusCode::SUCCESS ;
    00187 }
    00188 // ============================================================================
    00189 StatusCode TimingAuditor::finalize   ()
    00190 {
    00191   if ( 0 != m_incSvc )
    00192   {
    00193     m_incSvc -> removeListener ( this , IncidentType::BeginEvent ) ;
    00194     m_incSvc -> removeListener ( this , IncidentType::EndEvent   ) ;
    00195     m_incSvc -> release () ;
    00196     m_incSvc = 0 ;
    00197   }
    00198   if ( 0 != m_toolSvc )
    00199   {
    00200     // the 2 following line are commented out: it is
    00201     // is a temporary hack which prevent a crash due to a problem in
    00202     // the reference counting
    00203     //     if ( 0 != m_timer )
    00204     //     { m_toolSvc -> releaseTool ( m_timer ) . ignore() ; m_timer = 0 ; }
    00205     m_toolSvc -> release () ;
    00206     m_toolSvc = 0 ;
    00207   }
    00208   if ( 0 != m_appMgr ) { m_appMgr -> release () ;  m_appMgr = 0 ; }
    00209   // clear the map
    00210   m_map.clear() ;
    00211   // finalize the base class
    00212   return Auditor::finalize () ;
    00213 }
    00214 // ============================================================================
    00215 void TimingAuditor::before(StandardEventType evt, INamedInterface *alg)
    00216 {
    00217   switch (evt) {
    00218   case IAuditor::Initialize : i_beforeInitialize( alg ); break;
    00219   case IAuditor::Execute    : i_beforeExecute( alg );    break;
    00220   default: break;
    00221   }
    00222 }
    00223 // ============================================================================
    00224 void TimingAuditor::after(StandardEventType evt, INamedInterface *alg, const StatusCode &)
    00225 {
    00226   switch (evt) {
    00227   case IAuditor::Initialize : i_afterInitialize( alg ); break;
    00228   case IAuditor::Execute    : i_afterExecute( alg ); break;
    00229   default: break;
    00230   }
    00231 }
    00232 // ============================================================================
    00233 void TimingAuditor::i_beforeInitialize( INamedInterface* alg )
    00234 {
    00235   if ( m_goodForDOD ) { return ; }
    00236   //
    00237   if ( 0 == alg ) { return ; }
    00238   Map::iterator found = m_map.find( alg ) ;
    00239   if ( m_map.end() != found ) { return ; }
    00240   ++m_indent ;
    00241   std::string nick = alg->name() ;
    00242   if ( 0 < m_indent ) { nick = std::string ( m_indent , ' ') + nick ; }
    00243   if ( m_inEvent )
    00244   {
    00245     nick[0] = '*' ;
    00246     MsgStream log( msgSvc() , name() ) ;
    00247     log << MSG::DEBUG
    00248         << "Insert non-structural component '"
    00249         << alg->name() << "' of type '"
    00250         << System::typeinfoName(typeid(*alg)) << "' at level "
    00251         << m_indent << endreq ;
    00252   }
    00253   int timer = m_timer->addTimer( nick ) ;
    00254   m_map.insert ( alg , timer ) ;
    00255   m_timer->start( timer ) ;
    00256 }
    00257 // ============================================================================
    00258 void TimingAuditor::i_afterInitialize( INamedInterface* alg )
    00259 {
    00260   if ( m_goodForDOD ) { return ; }
    00261   if ( 0 == alg     ) { return ; }
    00262   --m_indent ;
    00263 }
    00264 // ============================================================================
    00265 void TimingAuditor::i_beforeExecute( INamedInterface* alg )
    00266 {
    00267   if ( 0 == alg ) { return ; }
    00268   ++m_indent ;
    00269   Map::iterator found = m_map.find( alg ) ;
    00270   if ( m_map.end() == found )
    00271   {
    00272     MsgStream log( msgSvc() , name() ) ;
    00273     log << MSG::DEBUG
    00274         << "Insert non-structural component '"
    00275         << alg->name() << "' of type '"
    00276         << System::typeinfoName(typeid(*alg)) << "' at level "
    00277         << m_indent << endreq ;
    00278     std::string nick = alg->name() ;
    00279     if ( 0 < m_indent  ) { nick = std::string ( m_indent , ' ') + nick ; }
    00280     if ( !m_goodForDOD ) { nick[0]='*' ;}
    00281     int timer = m_timer->addTimer( nick ) ;
    00282     m_map.insert ( alg , timer ) ;
    00283     m_timer->start( timer ) ;
    00284     return ;
    00285   }
    00286   m_timer->start( found->second ) ;
    00287 }
    00288 // ============================================================================
    00289 void TimingAuditor::i_afterExecute( INamedInterface* alg )
    00290 {
    00291   if ( 0 == alg ) { return ; }
    00292   Map::iterator found = m_map.find( alg ) ;
    00293   if ( m_map.end() == found ) { return ; }
    00294   m_timer->stop( found->second ) ;
    00295   --m_indent ;
    00296 }
    00297 // ============================================================================
    00298 void TimingAuditor::before(CustomEventTypeRef evt, const std::string& name)
    00299 {
    00300   // Ignore obvious mistakes
    00301   if ( name.empty() && evt.empty() ) { return; }
    00302
    00303   // look for the user timer in the map
    00304   int timer = 0;
    00305   std::string nick = name + ":" + evt;
    00306   MapUser::iterator found = m_mapUser.find( nick );
    00307
    00308   if ( m_mapUser.end() == found ) {
    00309     // add a new timer if not yet available
    00310     timer = m_timer->addTimer( nick ) ;
    00311     m_mapUser[nick] = timer;
    00312   }
    00313   else {
    00314     timer = found->second;
    00315   }
    00316
    00317   m_timer->start( timer );
    00318 }
    00319 // ============================================================================
    00320 void TimingAuditor::after(CustomEventTypeRef evt, const std::string& name, const StatusCode &)
    00321 {
    00322   // Ignore obvious mistakes
    00323   if ( name.empty() && evt.empty() ) { return; }
    00324
    00325   // look for the user timer in the map
    00326   std::string nick = name + ":" + evt;
    00327   MapUser::iterator found = m_mapUser.find( nick );
    00328
    00329   // We cannot do much if the timer is not available
    00330   if ( m_mapUser.end() == found ) {
    00331     MsgStream log(msgSvc(), this->name());
    00332     log << MSG::WARNING << "Trying to stop the measure  of the timing for '"
    00333                         << nick << "' but it was never started. Check the code"
    00334                         << endmsg;
    00335     return;
    00336   }
    00337   m_timer->stop( found->second );
    00338 }
    00339 // ============================================================================
    00340 void TimingAuditor::handle ( const Incident& i )
    00341 {
    00342   if      ( IncidentType::BeginEvent == i.type () )
    00343   {
    00344     m_timer -> start ( m_map[ m_appMgr ] ) ;
    00345     ++m_indent ;
    00346     m_inEvent = true ;
    00347   }
    00348   else if ( IncidentType::EndEvent   == i.type () )
    00349   {
    00350     m_timer -> stop  ( m_map[ m_appMgr ] ) ;
    00351     --m_indent ;
    00352     m_inEvent = false ;
    00353   }
    00354 }
    00355 // ============================================================================
    00356 // The END
    00357 // ============================================================================