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