Gaudi Framework, version v23r4

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

Generated at Mon Sep 17 2012 13:49:26 for Gaudi Framework, version v23r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004