00001
00002
00003
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
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
00082 TimingAuditor () ;
00083
00084 TimingAuditor ( const TimingAuditor& ) ;
00085
00086 TimingAuditor& operator=( const TimingAuditor& ) ;
00087 private:
00088
00089 IToolSvc* m_toolSvc ;
00090
00091 IIncidentSvc* m_incSvc ;
00092
00093 ISequencerTimerTool* m_timer ;
00094
00095 INamedInterface* m_appMgr ;
00096
00097 typedef GaudiUtils::VectorMap<const INamedInterface*,int> Map ;
00098 Map m_map ;
00099
00100 int m_indent ;
00101
00102 bool m_inEvent ;
00103
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 ; }
00120 else if ( IIncidentListener::interfaceID() == riid )
00121 { *ppv = static_cast<IIncidentListener*> ( this ) ; }
00122 else
00123 { return Auditor::queryInterface( riid , ppv ) ; }
00124 addRef() ;
00125 return StatusCode::SUCCESS ;
00126 } ;
00127
00128 StatusCode TimingAuditor::initialize ()
00129 {
00130 StatusCode sc = Auditor::initialize() ;
00131 if ( sc.isFailure() ) { return sc ; }
00132
00133 MsgStream log ( msgSvc() , name() ) ;
00134
00135
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 ;
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
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
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
00201
00202
00203
00204
00205 m_toolSvc -> release () ;
00206 m_toolSvc = 0 ;
00207 }
00208 if ( 0 != m_appMgr ) { m_appMgr -> release () ; m_appMgr = 0 ; }
00209
00210 m_map.clear() ;
00211
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
00301 if ( name.empty() && evt.empty() ) { return; }
00302
00303
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
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
00323 if ( name.empty() && evt.empty() ) { return; }
00324
00325
00326 std::string nick = name + ":" + evt;
00327 MapUser::iterator found = m_mapUser.find( nick );
00328
00329
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
00357