| # Gaudi Framework, version v21r6 |

Home |  | Generated: 11 Nov 2009

# 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     StatusCode 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     StatusCode 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     StatusCode 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 // ============================================================================