Gaudi Framework, version v23r3

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

Generated at Thu Jun 28 2012 12:29:51 for Gaudi Framework, version v23r3 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004