Gaudi Framework, version v21r8

Home   Generated: 17 Mar 2010

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

Generated at Wed Mar 17 18:06:08 2010 for Gaudi Framework, version v21r8 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004