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
00028 class TimingAuditor: public extends1<Auditor, IIncidentListener> {
00029 public:
00030
00031 virtual void before(StandardEventType evt, INamedInterface* alg);
00032 virtual void after(StandardEventType evt, INamedInterface* alg, const StatusCode &sc);
00033
00034 virtual void before(CustomEventTypeRef evt, const std::string& name);
00035 virtual void after(CustomEventTypeRef evt, const std::string& name, const StatusCode &sc);
00036
00037 private:
00038 void i_beforeInitialize( INamedInterface* alg );
00039 void i_afterInitialize( INamedInterface* alg );
00040 void i_beforeExecute( INamedInterface* alg );
00041 void i_afterExecute( INamedInterface* alg);
00042
00043 public:
00045 virtual void handle ( const Incident& ) ;
00046
00047 public:
00048 virtual StatusCode initialize () ;
00049 virtual StatusCode finalize () ;
00050
00051 public:
00053 TimingAuditor
00054 ( const std::string& name ,
00055 ISvcLocator* pSvc )
00056 : base_class ( name , pSvc )
00057
00058 , m_toolSvc ( 0 )
00059 , m_incSvc ( 0 )
00060
00061 , m_timer ( 0 )
00062
00063 , m_appMgr ( 0 )
00064
00065 , m_map ( )
00066 , m_indent ( 0 )
00067 , m_inEvent ( false )
00068 , m_goodForDOD ( false )
00069 , m_mapUser ( )
00070 {
00071 declareProperty ( "OptimizedForDOD" , m_goodForDOD ) ;
00072 } ;
00074 virtual ~TimingAuditor() {}
00075 private:
00076
00077 TimingAuditor () ;
00078
00079 TimingAuditor ( const TimingAuditor& ) ;
00080
00081 TimingAuditor& operator=( const TimingAuditor& ) ;
00082 private:
00083
00084 IToolSvc* m_toolSvc ;
00085
00086 IIncidentSvc* m_incSvc ;
00087
00088 ISequencerTimerTool* m_timer ;
00089
00090 INamedInterface* m_appMgr ;
00091
00092 typedef GaudiUtils::VectorMap<const INamedInterface*,int> Map ;
00093 Map m_map ;
00094
00095 int m_indent ;
00096
00097 bool m_inEvent ;
00098
00099 bool m_goodForDOD ;
00100
00101 typedef GaudiUtils::HashMap<std::string,int> MapUser ;
00102 MapUser m_mapUser ;
00103
00104 } ;
00105
00107
00108 DECLARE_AUDITOR_FACTORY(TimingAuditor)
00109
00110 StatusCode TimingAuditor::initialize ()
00111 {
00112 StatusCode sc = Auditor::initialize() ;
00113 if ( sc.isFailure() ) { return sc ; }
00114
00115 MsgStream log ( msgSvc() , name() ) ;
00116
00117
00118 if ( 0 == m_toolSvc )
00119 {
00120 sc = Auditor::service ( "ToolSvc" , m_toolSvc ) ;
00121 if ( sc.isFailure() )
00122 {
00123 log << "Could not retrieve 'ToolSvc' " << sc << endmsg ;
00124 return sc ;
00125 }
00126 if ( 0 == m_timer )
00127 {
00128 sc = m_toolSvc->retrieveTool
00129 ( "SequencerTimerTool/TIMER" , m_timer , this , true ) ;
00130 if ( sc.isFailure() )
00131 {
00132 log << MSG::ERROR
00133 << "Could not retrieve ISequencerTimerTool" << endmsg ;
00134 return sc ;
00135 }
00136 }
00137 }
00138
00139 if ( 0 == m_incSvc )
00140 {
00141 sc = Auditor::service ( "IncidentSvc" , m_incSvc ) ;
00142 if ( sc.isFailure() )
00143 {
00144 log << MSG::ERROR
00145 << "Could not retrieve 'IncidentSvc'" << sc << endmsg ;
00146 return sc ;
00147 }
00148 m_incSvc -> addListener ( this , IncidentType::BeginEvent ) ;
00149 m_incSvc -> addListener ( this , IncidentType::EndEvent ) ;
00150 }
00151
00152 if ( 0 == m_appMgr )
00153 {
00154 sc = Auditor::service ( "ApplicationMgr" , m_appMgr ) ;
00155 if ( sc.isFailure() )
00156 {
00157 log << MSG::ERROR
00158 << "Could not retrieve 'ApplicationMgr'" << sc << endmsg ;
00159 return sc ;
00160 }
00161 if ( m_map.end() == m_map.find( m_appMgr ) )
00162 {
00163 int timer = m_timer->addTimer( "EVENT LOOP" ) ;
00164 m_map.insert ( m_appMgr , timer ) ;
00165 }
00166 }
00167
00168 return StatusCode::SUCCESS ;
00169 }
00170
00171 StatusCode TimingAuditor::finalize ()
00172 {
00173 if ( 0 != m_incSvc )
00174 {
00175 m_incSvc -> removeListener ( this , IncidentType::BeginEvent ) ;
00176 m_incSvc -> removeListener ( this , IncidentType::EndEvent ) ;
00177 m_incSvc -> release () ;
00178 m_incSvc = 0 ;
00179 }
00180 if ( 0 != m_toolSvc )
00181 {
00182
00183
00184
00185
00186
00187 m_toolSvc -> release () ;
00188 m_toolSvc = 0 ;
00189 }
00190 if ( 0 != m_appMgr ) { m_appMgr -> release () ; m_appMgr = 0 ; }
00191
00192 m_map.clear() ;
00193
00194 return Auditor::finalize () ;
00195 }
00196
00197 void TimingAuditor::before(StandardEventType evt, INamedInterface *alg)
00198 {
00199 switch (evt) {
00200 case IAuditor::Initialize : i_beforeInitialize( alg ); break;
00201 case IAuditor::Execute : i_beforeExecute( alg ); break;
00202 default: break;
00203 }
00204 }
00205
00206 void TimingAuditor::after(StandardEventType evt, INamedInterface *alg, const StatusCode &)
00207 {
00208 switch (evt) {
00209 case IAuditor::Initialize : i_afterInitialize( alg ); break;
00210 case IAuditor::Execute : i_afterExecute( alg ); break;
00211 default: break;
00212 }
00213 }
00214
00215 void TimingAuditor::i_beforeInitialize( INamedInterface* alg )
00216 {
00217 if ( m_goodForDOD ) { return ; }
00218
00219 if ( 0 == alg ) { return ; }
00220 Map::iterator found = m_map.find( alg ) ;
00221 if ( m_map.end() != found ) { return ; }
00222 ++m_indent ;
00223 std::string nick = alg->name() ;
00224 if ( 0 < m_indent ) { nick = std::string ( m_indent , ' ') + nick ; }
00225 if ( m_inEvent )
00226 {
00227 nick[0] = '*' ;
00228 MsgStream log( msgSvc() , name() ) ;
00229 log << MSG::DEBUG
00230 << "Insert non-structural component '"
00231 << alg->name() << "' of type '"
00232 << System::typeinfoName(typeid(*alg)) << "' at level "
00233 << m_indent << endmsg ;
00234 }
00235 int timer = m_timer->addTimer( nick ) ;
00236 m_map.insert ( alg , timer ) ;
00237 m_timer->start( timer ) ;
00238 }
00239
00240 void TimingAuditor::i_afterInitialize( INamedInterface* alg )
00241 {
00242 if ( m_goodForDOD ) { return ; }
00243 if ( 0 == alg ) { return ; }
00244 --m_indent ;
00245 }
00246
00247 void TimingAuditor::i_beforeExecute( INamedInterface* alg )
00248 {
00249 if ( 0 == alg ) { return ; }
00250 ++m_indent ;
00251 Map::iterator found = m_map.find( alg ) ;
00252 if ( m_map.end() == found )
00253 {
00254 MsgStream log( msgSvc() , name() ) ;
00255 log << MSG::DEBUG
00256 << "Insert non-structural component '"
00257 << alg->name() << "' of type '"
00258 << System::typeinfoName(typeid(*alg)) << "' at level "
00259 << m_indent << endmsg ;
00260 std::string nick = alg->name() ;
00261 if ( 0 < m_indent ) { nick = std::string ( m_indent , ' ') + nick ; }
00262 if ( !m_goodForDOD ) { nick[0]='*' ;}
00263 int timer = m_timer->addTimer( nick ) ;
00264 m_map.insert ( alg , timer ) ;
00265 m_timer->start( timer ) ;
00266 return ;
00267 }
00268 m_timer->start( found->second ) ;
00269 }
00270
00271 void TimingAuditor::i_afterExecute( INamedInterface* alg )
00272 {
00273 if ( 0 == alg ) { return ; }
00274 Map::iterator found = m_map.find( alg ) ;
00275 if ( m_map.end() == found ) { return ; }
00276 m_timer->stop( found->second ) ;
00277 --m_indent ;
00278 }
00279
00280 void TimingAuditor::before(CustomEventTypeRef evt, const std::string& name)
00281 {
00282
00283 if ( name.empty() && evt.empty() ) { return; }
00284
00285
00286 int timer = 0;
00287 std::string nick = name + ":" + evt;
00288 MapUser::iterator found = m_mapUser.find( nick );
00289
00290 if ( m_mapUser.end() == found ) {
00291
00292 timer = m_timer->addTimer( nick ) ;
00293 m_mapUser[nick] = timer;
00294 }
00295 else {
00296 timer = found->second;
00297 }
00298
00299 m_timer->start( timer );
00300 }
00301
00302 void TimingAuditor::after(CustomEventTypeRef evt, const std::string& name, const StatusCode &)
00303 {
00304
00305 if ( name.empty() && evt.empty() ) { return; }
00306
00307
00308 std::string nick = name + ":" + evt;
00309 MapUser::iterator found = m_mapUser.find( nick );
00310
00311
00312 if ( m_mapUser.end() == found ) {
00313 MsgStream log(msgSvc(), this->name());
00314 log << MSG::WARNING << "Trying to stop the measure of the timing for '"
00315 << nick << "' but it was never started. Check the code"
00316 << endmsg;
00317 return;
00318 }
00319 m_timer->stop( found->second );
00320 }
00321
00322 void TimingAuditor::handle ( const Incident& i )
00323 {
00324 if ( IncidentType::BeginEvent == i.type () )
00325 {
00326 m_timer -> start ( m_map[ m_appMgr ] ) ;
00327 ++m_indent ;
00328 m_inEvent = true ;
00329 }
00330 else if ( IncidentType::EndEvent == i.type () )
00331 {
00332 m_timer -> stop ( m_map[ m_appMgr ] ) ;
00333 --m_indent ;
00334 m_inEvent = false ;
00335 }
00336 }
00337
00338
00339