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_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
00084 TimingAuditor () ;
00085
00086 TimingAuditor ( const TimingAuditor& ) ;
00087
00088 TimingAuditor& operator=( const TimingAuditor& ) ;
00089 private:
00090
00091 IToolSvc* m_toolSvc ;
00092
00093 IIncidentSvc* m_incSvc ;
00094
00095 ISequencerTimerTool* m_timer ;
00096
00097 INamedInterface* m_appMgr ;
00098
00099 typedef GaudiUtils::VectorMap<const INamedInterface*,int> Map ;
00100 Map m_map ;
00101
00102 int m_indent ;
00103
00104 bool m_inEvent ;
00105
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 ; }
00121
00122 MsgStream log ( msgSvc() , name() ) ;
00123
00124
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 ;
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
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
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
00190
00191
00192
00193
00194 m_toolSvc -> release () ;
00195 m_toolSvc = 0 ;
00196 }
00197 if ( 0 != m_appMgr ) { m_appMgr -> release () ; m_appMgr = 0 ; }
00198
00199 m_map.clear() ;
00200
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
00290 if ( name.empty() && evt.empty() ) { return; }
00291
00292
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
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
00312 if ( name.empty() && evt.empty() ) { return; }
00313
00314
00315 std::string nick = name + ":" + evt;
00316 MapUser::iterator found = m_mapUser.find( nick );
00317
00318
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
00346