The destructor is a quite important function in this class. it makes sure that the static s_instance variable gets reset, and that all TVirtualPerfStats objects really get deleted.
Everywhere in the code this function should be used to access the one and only PerfStats object in memory.
The user is supposed to call this function after the initialization of his/her analysis code finished, but before the event processing starts.
The user is supposed to call this function once his/her analysis code finished with the event processing.
In single process running this function is basically never called. It's only active when running on PROOF, in which case we should not care about the values given to it, but just forward it to TPerfStats. The actual amount of data read for xAOD monitoring is coming in through the FileReadEvent(...) function...
The function just gets the number of events from the other TVirtualPerfStats object if it exists, otherwise it just returns zero.
The constructor needs to do a few things. If there is already another TVirtualPerfStats object defined under gPerfStats, then it stores that pointer in order to be able to forward monitoring information to that object later on. It then overwrites gPerfStats to point to this object.
18 {
19
20
21 PerfStats* PerfStats::s_instance = nullptr;
22 std::mutex PerfStats::s_mutex;
23
28 PerfStats::~PerfStats() {
29
31
32
33
34 s_instance = nullptr;
35 if( m_otherPerfStats ) {
36 delete m_otherPerfStats;
37 }
38 }
39
45 PerfStats& PerfStats::instance() {
46
48
49 if( ! s_instance ) {
50 s_instance = new PerfStats();
51 }
52
53 return *s_instance;
54 }
55
61 void PerfStats::start( bool clear ) {
62
64
65 if( m_running ) return;
66
67
68 if( clear ) IOStats::instance().stats().Clear();
69
70
71 Info(
"start",
"Starting performance monitoring" );
72
73
74 m_startTime = TTimeStamp();
75
76 m_running = true;
77
78 return;
79 }
80
84 void PerfStats::stop() {
85
87
88 if( ! m_running ) return;
89
90
91 const ::Double_t elapsed = TTimeStamp().AsDouble() -
92 m_startTime;
93
94 ReadStats&
stats = IOStats::instance().stats();
95 stats.setProcessTime(
stats.processTime() + elapsed );
96
97
98 m_running = false;
99
100
101 Info(
"stop",
"Performance monitoring stopped after %s",
102 Utils::timeToString( elapsed ).c_str() );
103
104 return;
105 }
106
107 void PerfStats::SimpleEvent( EEventType
type ) {
108
109
110 if( m_otherPerfStats ) {
111 m_otherPerfStats->SimpleEvent(
type );
112 }
113
114 return;
115 }
116
117 void PerfStats::PacketEvent( const char* slave, const char* slavename,
118 const char* filename,
119 ::Long64_t eventsprocessed,
120 ::Double_t latency,
121 ::Double_t proctime, ::Double_t cputime,
122 ::Long64_t bytesRead ) {
123
124
125 if( m_otherPerfStats ) {
126 m_otherPerfStats->PacketEvent( slave, slavename, filename,
127 eventsprocessed, latency, proctime,
128 cputime, bytesRead );
129 }
130
131 return;
132 }
133
134 void PerfStats::FileEvent( const char* slave, const char* slavename,
135 const char* nodename, const char* filename,
136 ::Bool_t isStart ) {
137
138
139 if( m_otherPerfStats ) {
140 m_otherPerfStats->FileEvent( slave, slavename, nodename, filename,
141 isStart );
142 }
143
144 return;
145 }
146
147 void PerfStats::FileOpenEvent( ::TFile*
file,
const char* filename,
148 ::Double_t start ) {
149
150
151 if( m_otherPerfStats ) {
152 m_otherPerfStats->FileOpenEvent(
file, filename, start );
153 }
154
155 return;
156 }
157
167 void PerfStats::FileReadEvent( ::TFile*
file, ::Int_t len,
168 ::Double_t start ) {
169
170
171 const ::Double_t tnow = TTimeStamp();
172 const ::Double_t dtime = tnow -
start;
173
174
175 ReadStats&
stats = IOStats::instance().stats();
176 stats.setReadTime(
stats.readTime() + dtime );
177
178
179 stats.setBytesRead(
stats.bytesRead() + len );
181
182
183 if( m_otherPerfStats ) {
184 m_otherPerfStats->FileReadEvent(
file, len, start );
185 }
186
187 return;
188 }
189
199 void PerfStats::UnzipEvent( ::TObject*
tree, ::Long64_t pos,
200 ::Double_t start, ::Int_t complen,
201 ::Int_t objlen ) {
202
203
204 const ::Double_t tnow = TTimeStamp();
205 const ::Double_t dtime = tnow -
start;
206
207
208 ReadStats&
stats = IOStats::instance().stats();
209 stats.setUnzipTime(
stats.unzipTime() + dtime );
210
211
212 ::TTree*
t =
dynamic_cast< ::TTree*
>(
tree );
213 if( ! t ) {
214 Warning( "UnzipEvent", "Couldn't cast object to TTree" );
215 } else {
216 stats.setCacheSize(
t->GetCacheSize() );
217 }
218
219
220 if( m_otherPerfStats ) {
221 m_otherPerfStats->UnzipEvent(
tree, pos, start, complen, objlen );
222 }
223
224 return;
225 }
226
227 void PerfStats::RateEvent( ::Double_t proctime, ::Double_t deltatime,
228 ::Long64_t eventsprocessed,
229 ::Long64_t bytesRead ) {
230
231
232 if( m_otherPerfStats ) {
233 m_otherPerfStats->RateEvent( proctime, deltatime, eventsprocessed,
234 bytesRead );
235 }
236
237 return;
238 }
239
248 void PerfStats::SetBytesRead( ::Long64_t num ) {
249
250
251 if( m_otherPerfStats ) {
252 m_otherPerfStats->SetBytesRead( num );
253 }
254
255 return;
256 }
257
258 ::Long64_t PerfStats::GetBytesRead() const {
259
260
261 if( m_otherPerfStats ) {
262 return m_otherPerfStats->GetBytesRead();
263 } else {
264 return IOStats::instance().stats().bytesRead();
265 }
266 }
267
274 void PerfStats::SetNumEvents( ::Long64_t num ) {
275
276
277 if( m_otherPerfStats ) {
278 m_otherPerfStats->SetNumEvents( num );
279 }
280
281 return;
282 }
283
290 ::Long64_t PerfStats::GetNumEvents() const {
291
292
293 if( m_otherPerfStats ) {
294 return m_otherPerfStats->GetNumEvents();
295 }
296
297 return 0;
298 }
299
300
301
302
303
304 void PerfStats::PrintBasketInfo( Option_t *option ) const {
305 if( m_otherPerfStats ) m_otherPerfStats->PrintBasketInfo( option );
306 }
307
308 void PerfStats::UpdateBranchIndices( TObjArray *branches ) {
309 if( m_otherPerfStats ) m_otherPerfStats->UpdateBranchIndices( branches );
310 }
311
312 #define FWD_CALL(CALL) \
313 void PerfStats::CALL( TBranch *b, size_t basketNumber ) { \
314 if( m_otherPerfStats ) m_otherPerfStats->CALL( b, basketNumber ); \
315 } \
316 void PerfStats::CALL( size_t bi, size_t basketNumber ) { \
317 if( m_otherPerfStats ) m_otherPerfStats->CALL( bi, basketNumber ); \
318 } struct dummyforsemi
319
324 #undef FWD_CALL
325
332 PerfStats::PerfStats()
333 : m_otherPerfStats( nullptr ), m_running( false ), m_startTime( 0.0 ),
334 m_tree( nullptr ), m_file( nullptr ), m_treeWarningPrinted( false ) {
335
336
337
338
339 if( gPerfStats && ( gPerfStats != this ) ) {
340 m_otherPerfStats = gPerfStats;
342 "Will forward calls to former gPerfStats object" );
343 }
344
345
346 gPerfStats = this;
347 }
348
349#if ROOT_VERSION_CODE >= ROOT_VERSION( 6, 23, 2 )
353 void PerfStats::SetFile( TFile*
file ) {
354
356 }
357#endif
358
359}
std::lock_guard< std::mutex > lock_t