| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TimingAuditor.cpp
Go to the documentation of this file.
1 #include "GaudiKernel/Auditor.h"
2 #include "GaudiKernel/IToolSvc.h"
3 #include "GaudiKernel/IIncidentListener.h"
4 #include "GaudiKernel/IIncidentSvc.h"
5 #include "GaudiKernel/IToolSvc.h"
6 #include "GaudiKernel/VectorMap.h"
7 #include "GaudiKernel/HashMap.h"
8 #include "GaudiKernel/MsgStream.h"
9 // ============================================================================
10 // GaudiAlg
11 // ============================================================================
12 #include "GaudiAlg/ISequencerTimerTool.h"
13 // ============================================================================
14 #ifdef __ICC
15 // disable icc warning #654: overloaded virtual function "B::Y" is only partially overridden in class "C"
16 // TODO: there is only a partial overload of IAuditor::before and IAuditor::after
17 #pragma warning(disable:654)
18 #endif
19
28 class TimingAuditor: public extends1<Auditor, IIncidentListener> {
29 public:
30
31 virtual void before(StandardEventType evt, INamedInterface* alg);
32 virtual void after(StandardEventType evt, INamedInterface* alg, const StatusCode &sc);
33
34 using Auditor::before; // avoid hiding base-class methods
35 virtual void before(CustomEventTypeRef evt, const std::string& name);
36 using Auditor::after; // avoid hiding base-class methods
37 virtual void after(CustomEventTypeRef evt, const std::string& name, const StatusCode &sc);
38
39 private:
40 void i_beforeInitialize( INamedInterface* alg );
41 void i_afterInitialize( INamedInterface* alg );
42 void i_beforeFinalize( INamedInterface* alg );
43 void i_beforeExecute( INamedInterface* alg );
44 void i_afterExecute( INamedInterface* alg);
45
46 public:
48 virtual void handle ( const Incident& ) ;
49
50 public:
51 virtual StatusCode initialize () ;
52 virtual StatusCode finalize () ;
53
54 public:
56 TimingAuditor
57 ( const std::string& name ,
58 ISvcLocator* pSvc )
59 : base_class ( name , pSvc )
60 //
61 , m_toolSvc ( 0 )
62 , m_incSvc ( 0 )
63 //
64 , m_timer ( 0 )
65 //
66 , m_appMgr ( 0 )
67 //
68 , m_map ( )
69 , m_indent ( 0 )
70 , m_inEvent ( false )
71 , m_goodForDOD ( false )
72 , m_mapUser ( )
73 , m_histoSaved ( false )
74 {
75 declareProperty ( "OptimizedForDOD" , m_goodForDOD ) ;
76 } ;
78 virtual ~TimingAuditor() {}
79 private:
80 // the default constructor is disabled
81 TimingAuditor () ;
82 // copy constructor is disabled
83 TimingAuditor ( const TimingAuditor& ) ;
84 // assignement operator is disabled
85 TimingAuditor& operator=( const TimingAuditor& ) ;
86 private:
87 // tool service
88 IToolSvc* m_toolSvc ;
89 // incident service
90 IIncidentSvc* m_incSvc ;
91 // the timer tool
92 ISequencerTimerTool* m_timer ;
93 // ApplicationManager
94 INamedInterface* m_appMgr ;
95 //
96 typedef GaudiUtils::VectorMap<const INamedInterface*,int> Map ;
97 Map m_map ;
98 // indentation level
99 int m_indent ;
100 // "in event"
101 bool m_inEvent ;
102 // "optimized for Data-On-Demand Service"
103 bool m_goodForDOD ;
104 //
105 typedef GaudiUtils::HashMap<std::string,int> MapUser ;
106 MapUser m_mapUser ;
107
108 // Whether the timing has been saved already
109 bool m_histoSaved;
110
111
112 } ;
113 // ============================================================================
115 // ============================================================================
116 DECLARE_COMPONENT(TimingAuditor)
117 // ============================================================================
118 StatusCode TimingAuditor::initialize ()
119 {
120 StatusCode sc = Auditor::initialize() ;
121 if ( sc.isFailure() ) { return sc ; } // RETURN
122
123 MsgStream log ( msgSvc() , name() ) ;
124
125 // get tool service
126 if ( 0 == m_toolSvc )
127 {
128 sc = Auditor::service ( "ToolSvc" , m_toolSvc ) ;
129 if ( sc.isFailure() )
130 {
131 log << "Could not retrieve 'ToolSvc' " << sc << endmsg ;
132 return sc ; // RETURN
133 }
134 if ( 0 == m_timer )
135 {
136 sc = m_toolSvc->retrieveTool
137 ( "SequencerTimerTool/TIMER" , m_timer , this , true ) ;
138 if ( sc.isFailure() )
139 {
140 log << MSG::ERROR
141 << "Could not retrieve ISequencerTimerTool" << endmsg ;
142 return sc ;
143 }
144 }
145 }
146 // get incident service
147 if ( 0 == m_incSvc )
148 {
149 sc = Auditor::service ( "IncidentSvc" , m_incSvc ) ;
150 if ( sc.isFailure() )
151 {
152 log << MSG::ERROR
153 << "Could not retrieve 'IncidentSvc'" << sc << endmsg ;
154 return sc ;
155 }
156 m_incSvc -> addListener ( this , IncidentType::BeginEvent ) ;
157 m_incSvc -> addListener ( this , IncidentType::EndEvent ) ;
158 }
159 // get the application manager
160 if ( 0 == m_appMgr )
161 {
162 sc = Auditor::service ( "ApplicationMgr" , m_appMgr ) ;
163 if ( sc.isFailure() )
164 {
165 log << MSG::ERROR
166 << "Could not retrieve 'ApplicationMgr'" << sc << endmsg ;
167 return sc ;
168 }
169 if ( m_map.end() == m_map.find( m_appMgr ) )
170 {
171 int timer = m_timer->addTimer( "EVENT LOOP" ) ;
172 m_map.insert ( m_appMgr , timer ) ;
173 }
174 }
175 //
176 return StatusCode::SUCCESS ;
177 }
178 // ============================================================================
179 StatusCode TimingAuditor::finalize ()
180 {
181 if ( 0 != m_incSvc )
182 {
183 m_incSvc -> removeListener ( this , IncidentType::BeginEvent ) ;
184 m_incSvc -> removeListener ( this , IncidentType::EndEvent ) ;
185 m_incSvc -> release () ;
186 m_incSvc = 0 ;
187 }
188 if ( 0 != m_toolSvc )
189 {
190 // the 2 following line are commented out: it is
191 // is a temporary hack which prevent a crash due to a problem in
192 // the reference counting
193 // if ( 0 != m_timer )
194 // { m_toolSvc -> releaseTool ( m_timer ) . ignore() ; m_timer = 0 ; }
195 m_toolSvc -> release () ;
196 m_toolSvc = 0 ;
197 }
198 if ( 0 != m_appMgr ) { m_appMgr -> release () ; m_appMgr = 0 ; }
199 // clear the map
200 m_map.clear() ;
201 // finalize the base class
202 return Auditor::finalize () ;
203 }
204 // ============================================================================
205 void TimingAuditor::before(StandardEventType evt, INamedInterface *alg)
206 {
207 switch (evt) {
208 case IAuditor::Initialize : i_beforeInitialize( alg ); break;
209 case IAuditor::Execute : i_beforeExecute( alg ); break;
210 case IAuditor::Finalize : i_beforeFinalize( alg ); break;
211 default: break;
212 }
213 }
214 // ============================================================================
215 void TimingAuditor::after(StandardEventType evt, INamedInterface *alg, const StatusCode &)
216 {
217 switch (evt) {
218 case IAuditor::Initialize : i_afterInitialize( alg ); break;
219 case IAuditor::Execute : i_afterExecute( alg ); break;
220 default: break;
221 }
222 }
223 // ============================================================================
224 void TimingAuditor::i_beforeFinalize( INamedInterface* /*alg*/ )
225 {
226 if (!m_histoSaved)
227 {
228 m_timer->saveHistograms();
229 m_histoSaved = true;
230 }
231 }
232
233 // ============================================================================
234 void TimingAuditor::i_beforeInitialize( INamedInterface* alg )
235 {
236 if ( m_goodForDOD ) { return ; }
237 //
238 if ( 0 == alg ) { return ; }
239 Map::iterator found = m_map.find( alg ) ;
240 if ( m_map.end() != found ) { return ; }
241 ++m_indent ;
242 std::string nick = alg->name() ;
243 if ( 0 < m_indent ) { nick = std::string ( m_indent , ' ') + nick ; }
244 if ( m_inEvent )
245 {
246 nick[0] = '*' ;
247 MsgStream log( msgSvc() , name() ) ;
248 log << MSG::DEBUG
249 << "Insert non-structural component '"
250 << alg->name() << "' of type '"
251 << System::typeinfoName(typeid(*alg)) << "' at level "
252 << m_indent << endmsg ;
253 }
254 int timer = m_timer->addTimer( nick ) ;
255 m_map.insert ( alg , timer ) ;
256 m_timer->start( timer ) ;
257 }
258 // ============================================================================
259 void TimingAuditor::i_afterInitialize( INamedInterface* alg )
260 {
261 if ( m_goodForDOD ) { return ; }
262 if ( 0 == alg ) { return ; }
263 --m_indent ;
264 }
265 // ============================================================================
266 void TimingAuditor::i_beforeExecute( INamedInterface* alg )
267 {
268 if ( 0 == alg ) { return ; }
269 ++m_indent ;
270 Map::iterator found = m_map.find( alg ) ;
271 if ( m_map.end() == found )
272 {
273 MsgStream log( msgSvc() , name() ) ;
274 log << MSG::DEBUG
275 << "Insert non-structural component '"
276 << alg->name() << "' of type '"
277 << System::typeinfoName(typeid(*alg)) << "' at level "
278 << m_indent << endmsg ;
279 std::string nick = alg->name() ;
280 if ( 0 < m_indent ) { nick = std::string ( m_indent , ' ') + nick ; }
281 if ( !m_goodForDOD ) { nick[0]='*' ;}
282 int timer = m_timer->addTimer( nick ) ;
283 m_map.insert ( alg , timer ) ;
284 m_timer->start( timer ) ;
285 return ;
286 }
287 m_timer->start( found->second ) ;
288 }
289 // ============================================================================
290 void TimingAuditor::i_afterExecute( INamedInterface* alg )
291 {
292 if ( 0 == alg ) { return ; }
293 Map::iterator found = m_map.find( alg ) ;
294 if ( m_map.end() == found ) { return ; }
295 m_timer->stop( found->second ) ;
296 --m_indent ;
297 }
298 // ============================================================================
299 void TimingAuditor::before(CustomEventTypeRef evt, const std::string& name)
300 {
301 // Ignore obvious mistakes
302 if ( name.empty() && evt.empty() ) { return; }
303
304 // look for the user timer in the map
305 int timer = 0;
306 std::string nick = name + ":" + evt;
307 MapUser::iterator found = m_mapUser.find( nick );
308
309 if ( m_mapUser.end() == found ) {
310 // add a new timer if not yet available
311 timer = m_timer->addTimer( nick ) ;
312 m_mapUser[nick] = timer;
313 }
314 else {
315 timer = found->second;
316 }
317
318 m_timer->start( timer );
319 }
320 // ============================================================================
321 void TimingAuditor::after(CustomEventTypeRef evt, const std::string& name, const StatusCode &)
322 {
323 // Ignore obvious mistakes
324 if ( name.empty() && evt.empty() ) { return; }
325
326 // look for the user timer in the map
327 std::string nick = name + ":" + evt;
328 MapUser::iterator found = m_mapUser.find( nick );
329
330 // We cannot do much if the timer is not available
331 if ( m_mapUser.end() == found ) {
332 MsgStream log(msgSvc(), this->name());
333 log << MSG::WARNING << "Trying to stop the measure of the timing for '"
334 << nick << "' but it was never started. Check the code"
335 << endmsg;
336 return;
337 }
338 m_timer->stop( found->second );
339 }
340 // ============================================================================
341 void TimingAuditor::handle ( const Incident& i )
342 {
343 if ( IncidentType::BeginEvent == i.type () )
344 {
345 m_timer -> start ( m_map[ m_appMgr ] ) ;
346 ++m_indent ;
347 m_inEvent = true ;
348 }
349 else if ( IncidentType::EndEvent == i.type () )
350 {
351 m_timer -> stop ( m_map[ m_appMgr ] ) ;
352 --m_indent ;
353 m_inEvent = false ;
354 }
355 }
356 // ============================================================================
357 // The END
358 // ============================================================================