Gaudi Framework, version v23r2

Home   Generated: Thu Jun 28 2012

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:  $, version $Revision: 1.5 $
00004 // ============================================================================
00005 #include "GaudiKernel/Auditor.h"
00006 #include "GaudiKernel/IToolSvc.h"
00007 #include "GaudiKernel/IIncidentListener.h"
00008 #include "GaudiKernel/IIncidentSvc.h"
00009 #include "GaudiKernel/IToolSvc.h"
00010 #include "GaudiKernel/VectorMap.h"
00011 #include "GaudiKernel/HashMap.h"
00012 #include "GaudiKernel/AudFactory.h"
00013 #include "GaudiKernel/MsgStream.h"
00014 // ============================================================================
00015 // GaudiAlg
00016 // ============================================================================
00017 #include "GaudiAlg/ISequencerTimerTool.h"
00018 // ============================================================================
00019 #ifdef __ICC
00020 // disable icc warning #654: overloaded virtual function "B::Y" is only partially overridden in class "C"
00021 //   TODO: there is only a partial overload of IAuditor::before and IAuditor::after
00022 #pragma warning(disable:654)
00023 #endif
00024 
00033 class TimingAuditor: public extends1<Auditor, IIncidentListener> {
00034 public:
00035 
00036   virtual void before(StandardEventType evt, INamedInterface* alg);
00037   virtual void after(StandardEventType evt, INamedInterface* alg, const StatusCode &sc);
00038 
00039   virtual void before(CustomEventTypeRef evt, const std::string& name);
00040   virtual void after(CustomEventTypeRef evt, const std::string& name, const StatusCode &sc);
00041 
00042 private:
00043   void i_beforeInitialize( INamedInterface* alg );
00044   void i_afterInitialize( INamedInterface* alg );
00045   void i_beforeExecute( INamedInterface* alg );
00046   void i_afterExecute( INamedInterface* alg);
00047 
00048 public:
00050   virtual void handle ( const Incident& ) ;
00051 
00052 public:
00053   virtual StatusCode initialize () ;
00054   virtual StatusCode finalize   () ;
00055 
00056 public:
00058   TimingAuditor
00059   ( const std::string& name ,
00060     ISvcLocator*       pSvc )
00061     : base_class ( 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::initialize ()
00116 {
00117   StatusCode sc = Auditor::initialize() ;
00118   if ( sc.isFailure() ) { return sc ; }                  // RETURN
00119 
00120   MsgStream log ( msgSvc() , name() ) ;
00121 
00122   // get tool service
00123   if ( 0 == m_toolSvc )
00124   {
00125     sc = Auditor::service ( "ToolSvc" , m_toolSvc ) ;
00126     if ( sc.isFailure() )
00127     {
00128       log << "Could not retrieve 'ToolSvc' " << sc << endmsg ;
00129       return sc ;                                        // RETURN
00130     }
00131     if ( 0 == m_timer )
00132     {
00133       sc = m_toolSvc->retrieveTool
00134         ( "SequencerTimerTool/TIMER" , m_timer , this  , true ) ;
00135       if ( sc.isFailure() )
00136       {
00137         log << MSG::ERROR
00138             << "Could not retrieve ISequencerTimerTool" << endmsg ;
00139         return sc ;
00140       }
00141     }
00142   }
00143   // get incident service
00144   if ( 0 == m_incSvc )
00145   {
00146     sc = Auditor::service ( "IncidentSvc" , m_incSvc ) ;
00147     if ( sc.isFailure() )
00148     {
00149       log << MSG::ERROR
00150           << "Could not retrieve 'IncidentSvc'" << sc << endmsg ;
00151       return sc ;
00152     }
00153     m_incSvc -> addListener ( this , IncidentType::BeginEvent ) ;
00154     m_incSvc -> addListener ( this , IncidentType::EndEvent   ) ;
00155   }
00156   // get the application manager
00157   if ( 0 == m_appMgr )
00158   {
00159     sc = Auditor::service ( "ApplicationMgr" , m_appMgr ) ;
00160     if ( sc.isFailure() )
00161     {
00162       log << MSG::ERROR
00163           << "Could not retrieve 'ApplicationMgr'" << sc << endmsg ;
00164       return sc ;
00165     }
00166     if ( m_map.end() == m_map.find( m_appMgr ) )
00167     {
00168       int timer = m_timer->addTimer( "EVENT LOOP" ) ;
00169       m_map.insert ( m_appMgr , timer ) ;
00170     }
00171   }
00172   //
00173   return StatusCode::SUCCESS ;
00174 }
00175 // ============================================================================
00176 StatusCode TimingAuditor::finalize   ()
00177 {
00178   if ( 0 != m_incSvc )
00179   {
00180     m_incSvc -> removeListener ( this , IncidentType::BeginEvent ) ;
00181     m_incSvc -> removeListener ( this , IncidentType::EndEvent   ) ;
00182     m_incSvc -> release () ;
00183     m_incSvc = 0 ;
00184   }
00185   if ( 0 != m_toolSvc )
00186   {
00187     // the 2 following line are commented out: it is
00188     // is a temporary hack which prevent a crash due to a problem in
00189     // the reference counting
00190     //     if ( 0 != m_timer )
00191     //     { m_toolSvc -> releaseTool ( m_timer ) . ignore() ; m_timer = 0 ; }
00192     m_toolSvc -> release () ;
00193     m_toolSvc = 0 ;
00194   }
00195   if ( 0 != m_appMgr ) { m_appMgr -> release () ;  m_appMgr = 0 ; }
00196   // clear the map
00197   m_map.clear() ;
00198   // finalize the base class
00199   return Auditor::finalize () ;
00200 }
00201 // ============================================================================
00202 void TimingAuditor::before(StandardEventType evt, INamedInterface *alg)
00203 {
00204   switch (evt) {
00205   case IAuditor::Initialize : i_beforeInitialize( alg ); break;
00206   case IAuditor::Execute    : i_beforeExecute( alg );    break;
00207   default: break;
00208   }
00209 }
00210 // ============================================================================
00211 void TimingAuditor::after(StandardEventType evt, INamedInterface *alg, const StatusCode &)
00212 {
00213   switch (evt) {
00214   case IAuditor::Initialize : i_afterInitialize( alg ); break;
00215   case IAuditor::Execute    : i_afterExecute( alg ); break;
00216   default: break;
00217   }
00218 }
00219 // ============================================================================
00220 void TimingAuditor::i_beforeInitialize( INamedInterface* alg )
00221 {
00222   if ( m_goodForDOD ) { return ; }
00223   //
00224   if ( 0 == alg ) { return ; }
00225   Map::iterator found = m_map.find( alg ) ;
00226   if ( m_map.end() != found ) { return ; }
00227   ++m_indent ;
00228   std::string nick = alg->name() ;
00229   if ( 0 < m_indent ) { nick = std::string ( m_indent , ' ') + nick ; }
00230   if ( m_inEvent )
00231   {
00232     nick[0] = '*' ;
00233     MsgStream log( msgSvc() , name() ) ;
00234     log << MSG::DEBUG
00235         << "Insert non-structural component '"
00236         << alg->name() << "' of type '"
00237         << System::typeinfoName(typeid(*alg)) << "' at level "
00238         << m_indent << endmsg ;
00239   }
00240   int timer = m_timer->addTimer( nick ) ;
00241   m_map.insert ( alg , timer ) ;
00242   m_timer->start( timer ) ;
00243 }
00244 // ============================================================================
00245 void TimingAuditor::i_afterInitialize( INamedInterface* alg )
00246 {
00247   if ( m_goodForDOD ) { return ; }
00248   if ( 0 == alg     ) { return ; }
00249   --m_indent ;
00250 }
00251 // ============================================================================
00252 void TimingAuditor::i_beforeExecute( INamedInterface* alg )
00253 {
00254   if ( 0 == alg ) { return ; }
00255   ++m_indent ;
00256   Map::iterator found = m_map.find( alg ) ;
00257   if ( m_map.end() == found )
00258   {
00259     MsgStream log( msgSvc() , name() ) ;
00260     log << MSG::DEBUG
00261         << "Insert non-structural component '"
00262         << alg->name() << "' of type '"
00263         << System::typeinfoName(typeid(*alg)) << "' at level "
00264         << m_indent << endmsg ;
00265     std::string nick = alg->name() ;
00266     if ( 0 < m_indent  ) { nick = std::string ( m_indent , ' ') + nick ; }
00267     if ( !m_goodForDOD ) { nick[0]='*' ;}
00268     int timer = m_timer->addTimer( nick ) ;
00269     m_map.insert ( alg , timer ) ;
00270     m_timer->start( timer ) ;
00271     return ;
00272   }
00273   m_timer->start( found->second ) ;
00274 }
00275 // ============================================================================
00276 void TimingAuditor::i_afterExecute( INamedInterface* alg )
00277 {
00278   if ( 0 == alg ) { return ; }
00279   Map::iterator found = m_map.find( alg ) ;
00280   if ( m_map.end() == found ) { return ; }
00281   m_timer->stop( found->second ) ;
00282   --m_indent ;
00283 }
00284 // ============================================================================
00285 void TimingAuditor::before(CustomEventTypeRef evt, const std::string& name)
00286 {
00287   // Ignore obvious mistakes
00288   if ( name.empty() && evt.empty() ) { return; }
00289 
00290   // look for the user timer in the map
00291   int timer = 0;
00292   std::string nick = name + ":" + evt;
00293   MapUser::iterator found = m_mapUser.find( nick );
00294 
00295   if ( m_mapUser.end() == found ) {
00296     // add a new timer if not yet available
00297     timer = m_timer->addTimer( nick ) ;
00298     m_mapUser[nick] = timer;
00299   }
00300   else {
00301     timer = found->second;
00302   }
00303 
00304   m_timer->start( timer );
00305 }
00306 // ============================================================================
00307 void TimingAuditor::after(CustomEventTypeRef evt, const std::string& name, const StatusCode &)
00308 {
00309   // Ignore obvious mistakes
00310   if ( name.empty() && evt.empty() ) { return; }
00311 
00312   // look for the user timer in the map
00313   std::string nick = name + ":" + evt;
00314   MapUser::iterator found = m_mapUser.find( nick );
00315 
00316   // We cannot do much if the timer is not available
00317   if ( m_mapUser.end() == found ) {
00318     MsgStream log(msgSvc(), this->name());
00319     log << MSG::WARNING << "Trying to stop the measure  of the timing for '"
00320                         << nick << "' but it was never started. Check the code"
00321                         << endmsg;
00322     return;
00323   }
00324   m_timer->stop( found->second );
00325 }
00326 // ============================================================================
00327 void TimingAuditor::handle ( const Incident& i )
00328 {
00329   if      ( IncidentType::BeginEvent == i.type () )
00330   {
00331     m_timer -> start ( m_map[ m_appMgr ] ) ;
00332     ++m_indent ;
00333     m_inEvent = true ;
00334   }
00335   else if ( IncidentType::EndEvent   == i.type () )
00336   {
00337     m_timer -> stop  ( m_map[ m_appMgr ] ) ;
00338     --m_indent ;
00339     m_inEvent = false ;
00340   }
00341 }
00342 // ============================================================================
00343 // The END
00344 // ============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

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