| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

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: GAUDI_v20r4-pre $, 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 // ============================================================================
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 19:58:14 2011 for GaudiAlg by doxygen 1.4.7