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