00001
00002
00003
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
00016
00017 #include "GaudiAlg/ISequencerTimerTool.h"
00018
00019 #ifdef __ICC
00020
00021
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;
00040 virtual void before(CustomEventTypeRef evt, const std::string& name);
00041 using Auditor::after;
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
00086 TimingAuditor () ;
00087
00088 TimingAuditor ( const TimingAuditor& ) ;
00089
00090 TimingAuditor& operator=( const TimingAuditor& ) ;
00091 private:
00092
00093 IToolSvc* m_toolSvc ;
00094
00095 IIncidentSvc* m_incSvc ;
00096
00097 ISequencerTimerTool* m_timer ;
00098
00099 INamedInterface* m_appMgr ;
00100
00101 typedef GaudiUtils::VectorMap<const INamedInterface*,int> Map ;
00102 Map m_map ;
00103
00104 int m_indent ;
00105
00106 bool m_inEvent ;
00107
00108 bool m_goodForDOD ;
00109
00110 typedef GaudiUtils::HashMap<std::string,int> MapUser ;
00111 MapUser m_mapUser ;
00112
00113
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 ; }
00127
00128 MsgStream log ( msgSvc() , name() ) ;
00129
00130
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 ;
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
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
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
00196
00197
00198
00199
00200 m_toolSvc -> release () ;
00201 m_toolSvc = 0 ;
00202 }
00203 if ( 0 != m_appMgr ) { m_appMgr -> release () ; m_appMgr = 0 ; }
00204
00205 m_map.clear() ;
00206
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* )
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
00307 if ( name.empty() && evt.empty() ) { return; }
00308
00309
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
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
00329 if ( name.empty() && evt.empty() ) { return; }
00330
00331
00332 std::string nick = name + ":" + evt;
00333 MapUser::iterator found = m_mapUser.find( nick );
00334
00335
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
00363