]>
Commit | Line | Data |
---|---|---|
0e8bc704 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | ||
6efecea1 | 17 | // |
18 | // Origin: marian.ivanov@cern.ch | |
19 | // | |
20 | // Make a log file for the CPU and Memory usage | |
ab557934 | 21 | // |
22 | // Principles: | |
23 | // Snapshots of the system information are writen to the text log files. | |
24 | // Text files were chosen in order to get the ouptu also in case code | |
25 | // is crashing. | |
26 | // Following information is stored in the log file: | |
27 | // TTimeStamp stamp; | |
28 | // CpuInfo_t cpuInfo; | |
29 | // MemInfo_t memInfo; | |
30 | // ProcInfo_t procInfo; | |
31 | // | |
32 | // Root TSystem is used to retrieve this information: | |
33 | // gSystem->GetCpuInfo(&cpuInfo, 10); | |
34 | // gSystem->GetMemInfo(&memInfo); | |
35 | // gSystem->GetProcInfo(&procInfo); | |
36 | // for details see: | |
37 | // http://root.cern.ch/root/html/TUnixSystem.html | |
38 | // http://root.cern.ch/root/html/ProcInfo_t.html | |
39 | // http://root.cern.ch/root/html/MemInfo_t.html | |
40 | // http://root.cern.ch/root/html/CpuInfo_t.html | |
41 | // ------------------------------------------------------------------- | |
42 | // class CpuInfo_t | |
43 | // Float_t fIdle cpu idle percentage | |
44 | // Float_t fLoad15m cpu load average over 15 m | |
45 | // Float_t fLoad1m cpu load average over 1 m | |
46 | // Float_t fLoad5m cpu load average over 5 m | |
47 | // Float_t fSys cpu sys load in percentage | |
48 | // Float_t fTotal cpu user+sys load in percentage | |
49 | // Float_t fUser cpu user load in percentage | |
50 | ||
51 | // ------------------------------------------------------------------- | |
52 | // class ProcInfo_t: | |
53 | // Float_t fCpuSys system time used by this process in seconds | |
54 | // Float_t fCpuUser user time used by this process in seconds | |
55 | // Long_t fMemResident resident memory used by this process in KB | |
56 | // Long_t fMemVirtual virtual memory used by this process in KB | |
57 | // ------------------------------------------------------------------- | |
58 | ||
59 | ||
60 | // The information from the AliSysInfo can be used as measurement | |
61 | // of the code quality. Be aware of the limitation induced by | |
62 | // using only system info described in the AliSysInfo::Test() function | |
63 | // | |
64 | // The example usage of the AliSysInfo is shown in the | |
65 | // AliSysInfo::Test() example. | |
66 | // | |
6efecea1 | 67 | // |
ab557934 | 68 | // |
69 | // | |
70 | // The typical usage in the AliRoot code: | |
6efecea1 | 71 | // Make a set of stamps in the code in the place of interest |
72 | // e.g. | |
73 | // | |
74 | // AliSysInfo::AddStamp("Start"); | |
75 | // | |
76 | // loader->UnloadRecPoints(); | |
77 | // AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr); | |
78 | // | |
79 | ||
80 | // The log file can be transformed to the tree - to make a visualization | |
81 | // See $ALICE_ROOT/macros/PlotSysInfo.C as an example | |
82 | ||
83 | ||
0e8bc704 | 84 | #include <Riostream.h> |
85 | #include "AliLog.h" | |
86 | #include "TStopwatch.h" | |
87 | #include "TSystem.h" | |
88 | #include "TTree.h" | |
89 | ||
90 | #include "TTimeStamp.h" | |
91 | #include "AliSysInfo.h" | |
92 | ||
6efecea1 | 93 | //#include "TMemStatManager.h" //USE IFDEF |
94 | ||
0e8bc704 | 95 | |
96 | ClassImp(AliSysInfo) | |
97 | ||
98 | AliSysInfo* AliSysInfo::fInstance=0; | |
99 | ||
100 | AliSysInfo::AliSysInfo(): | |
101 | TObject(), | |
102 | fSysWatch(0), | |
6efecea1 | 103 | fTimer(0), |
d1d8b044 | 104 | fMemStat(0), |
105 | fCallBackFunc(0), | |
106 | fNCallBack(0) | |
0e8bc704 | 107 | { |
108 | fTimer = new TStopwatch; | |
109 | fSysWatch = new fstream("syswatch.log", ios_base::out|ios_base::trunc); | |
6efecea1 | 110 | |
ab557934 | 111 | //hname/C:sname/C:sec/D:mI.fMemUsed/F:mI.fSwapUsed/F:pI.fMemResident/F:pI.fMemVirtual/F:cI.fUser/F:cI.fSys/F:cI.fCpuUser/F:pI.fCpuSys/F |
0e8bc704 | 112 | |
113 | ||
114 | (*fSysWatch) <<"hname"<<"/C:" // hname - hostname | |
115 | <<"sname"<<"/C:" // stamp name | |
6efecea1 | 116 | <<"id0"<<"/I:" // 0 id |
117 | <<"id1"<<"/I:" // 1 id | |
118 | <<"id2"<<"/I:" // 1 id | |
ab557934 | 119 | <<"first"<<"/D:" // first stamp |
0e8bc704 | 120 | // |
ab557934 | 121 | <<"stampSec"<<"/D:" // time - time stamp in seconds |
122 | <<"mi.fMemUsed"<<"/D:" // system info | |
123 | <<"mi.fSwapUsed"<<"/D:" // | |
124 | <<"cI.fUser"<<"/D:" // | |
125 | <<"cI.fSys"<<"/D:" // | |
0e8bc704 | 126 | // |
ab557934 | 127 | <<"pI.fMemResident"<<"/D:" // process info |
128 | <<"pI.fMemVirtual"<<"/D:" // | |
129 | <<"pI.fCpuUser"<<"/D:" // | |
130 | <<"pI.fCpuSys"<<"/D:" // | |
0e8bc704 | 131 | // |
ab557934 | 132 | <<"stampOldSec"<<"/D:" // time - time stamp in seconds |
133 | <<"miOld.fMemUsed"<<"/D:" // system info - previous | |
134 | <<"miOld.fSwapUsed"<<"/D:" // | |
135 | <<"cIOld.fUser"<<"/D:" // | |
136 | <<"cIOld.fSys"<<"/D:" // | |
0e8bc704 | 137 | // |
ab557934 | 138 | <<"pIOld.fMemResident"<<"/D:" // process info -previous |
139 | <<"pIOld.fMemVirtual"<<"/D:" // | |
140 | <<"pIOld.fCpuUser"<<"/D:" // | |
141 | <<"pIOld.fCpuSys"<<"/D" // | |
0e8bc704 | 142 | << endl; |
143 | ||
144 | } | |
145 | ||
146 | ||
147 | ||
148 | ||
149 | AliSysInfo * AliSysInfo::Instance(){ | |
150 | // | |
151 | // | |
152 | // | |
153 | if (!fInstance){ | |
154 | fInstance = new AliSysInfo; | |
155 | } | |
156 | return fInstance; | |
157 | } | |
158 | ||
159 | ||
6efecea1 | 160 | void AliSysInfo::AddStamp(const char *sname, Int_t id0, Int_t id1, Int_t id2){ |
0e8bc704 | 161 | // |
162 | // | |
163 | // | |
0e8bc704 | 164 | // |
0e8bc704 | 165 | TTimeStamp stamp; |
166 | CpuInfo_t cpuInfo; | |
167 | MemInfo_t memInfo; | |
168 | ProcInfo_t procInfo; | |
169 | gSystem->GetCpuInfo(&cpuInfo, 10); | |
170 | gSystem->GetMemInfo(&memInfo); | |
171 | gSystem->GetProcInfo(&procInfo); | |
ab557934 | 172 | // procInfo.fMemVirtual/=1024; //size in MBy |
173 | //procInfo.fMemResident/=1024; //size in MBy | |
d1d8b044 | 174 | |
0e8bc704 | 175 | const char * hname = gSystem->HostName(); |
176 | ||
177 | static Int_t entry=0; | |
ab557934 | 178 | static Double_t first=stamp.GetSec()+stamp.GetNanoSec()/1000000000.; |
0e8bc704 | 179 | // |
180 | static TTimeStamp stampOld; | |
181 | static CpuInfo_t cpuInfoOld; | |
182 | static MemInfo_t memInfoOld; | |
183 | static ProcInfo_t procInfoOld; | |
184 | ||
185 | ||
ab557934 | 186 | (*(Instance()->fSysWatch)) |
187 | << hname <<"\t" // hname - hostname | |
188 | << sname <<"\t" // stamp name | |
189 | << id0 <<"\t" | |
190 | << id1 <<"\t" | |
191 | << id2 <<"\t" | |
192 | <<setprecision(15)<< first <<"\t" // first stamp | |
0e8bc704 | 193 | // |
ab557934 | 194 | <<setprecision(15)<< stamp.GetSec()+stamp.GetNanoSec()/1000000000.<<"\t" // time - time stamp in seconds |
195 | << memInfo.fMemUsed<<"\t" // system info | |
196 | << memInfo.fSwapUsed<<"\t" // | |
197 | << cpuInfo.fUser <<"\t" // | |
198 | << cpuInfo.fSys <<"\t" // | |
199 | // | |
200 | <<setprecision(15)<< procInfo.fMemResident/1024.<<"\t" // process info | |
201 | <<setprecision(15)<< procInfo.fMemVirtual/1024.<<"\t" // | |
202 | << procInfo.fCpuUser<<"\t" // | |
203 | << procInfo.fCpuSys<<"\t" // | |
204 | // | |
205 | <<setprecision(15)<< stampOld.GetSec()+stampOld.GetNanoSec()/1000000000.<<"\t" // time - time stamp in seconds | |
206 | << memInfoOld.fMemUsed<<"\t" // system info - previous | |
207 | << memInfoOld.fSwapUsed<<"\t" // | |
208 | << cpuInfoOld.fUser <<"\t" // | |
209 | << cpuInfoOld.fSys <<"\t" // | |
210 | // | |
211 | <<setprecision(15)<< procInfoOld.fMemResident/1024.<<"\t" // process info -previous | |
212 | <<setprecision(15)<< procInfoOld.fMemVirtual/1024.<<"\t" // | |
213 | << procInfoOld.fCpuUser<<"\t" // | |
214 | << procInfoOld.fCpuSys<<"\t" // | |
215 | << endl; | |
216 | ||
0e8bc704 | 217 | stampOld = stamp; |
218 | cpuInfoOld = cpuInfo; | |
219 | memInfoOld = memInfo; | |
6efecea1 | 220 | procInfoOld= procInfo; |
221 | ||
222 | // if (fInstance->fMemStat) fInstance->fMemStat->AddStamps(sname); | |
d1d8b044 | 223 | for (Int_t icallback=0; icallback<Instance()->fNCallBack; icallback++){ |
224 | Instance()->fCallBackFunc[icallback](sname); | |
225 | } | |
0e8bc704 | 226 | entry++; |
227 | } | |
228 | ||
229 | ||
230 | TTree * AliSysInfo::MakeTree(const char *lname){ | |
231 | // char * lname = "syswatch.log" | |
232 | TTree * tree = new TTree; | |
233 | tree->ReadFile(lname); | |
234 | tree->SetAlias("deltaT","stampSec-stampOldSec"); | |
6efecea1 | 235 | tree->SetAlias("T","stampSec-first"); |
d1d8b044 | 236 | tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)"); |
237 | tree->SetAlias("VM","pI.fMemVirtual"); | |
0e8bc704 | 238 | return tree; |
239 | } | |
240 | ||
6efecea1 | 241 | |
242 | Bool_t AliSysInfo::Contain(const char * str1, const char * str2){ | |
243 | // | |
244 | // | |
245 | // | |
246 | TString str(str1); | |
247 | return str.Contains(str2); | |
248 | } | |
249 | ||
250 | ||
251 | ||
252 | void AliSysInfo::OpenMemStat(){ | |
253 | // | |
254 | // | |
255 | // | |
256 | //USE IFDEF if MEMSTAT ENABLED | |
257 | // Instance()->fMemStat = TMemStatManager::GetInstance(); | |
258 | // Instance()->fMemStat->SetAutoStamp(10000000, 10000000,1000000); | |
259 | // Instance()->fMemStat->Enable(); | |
260 | } | |
261 | ||
262 | void AliSysInfo::CloseMemStat(){ | |
263 | // | |
264 | // | |
265 | // | |
266 | //USE IFDEF if MEMSTAT ENABLED | |
267 | //if (Instance()->fMemStat == TMemStatManager::GetInstance()) Instance()->fMemStat->Close(); | |
268 | //Instance()->fMemStat=0; | |
269 | } | |
d1d8b044 | 270 | |
271 | ||
272 | ||
273 | void AliSysInfo::AddCallBack(StampCallback_t callback){ | |
274 | // | |
275 | // add cal back function | |
276 | // | |
277 | AliSysInfo *info = Instance(); | |
278 | if (!info->fCallBackFunc) | |
279 | info->fCallBackFunc = new StampCallback_t[100]; | |
280 | info->fCallBackFunc[info->fNCallBack]=callback; | |
281 | info->fNCallBack++; | |
282 | } | |
ab557934 | 283 | |
284 | ||
285 | ||
286 | TTree* AliSysInfo::Test(){ | |
287 | // | |
288 | // Test example for AliSysInfo: | |
289 | // 1. Make huge memory leak | |
290 | // 2. Slow down execution | |
291 | /* | |
292 | To use the test: | |
293 | TTree * tree = AliSysInfo::Test(); | |
294 | // Make alias what we set as input | |
295 | tree->SetAlias("deltaVMIn","(id0*100000+id1*10000+id2*1000)/1000000.") | |
296 | tree->SetAlias("deltaVM","(pI.fMemVirtual-pIOld.fMemVirtual)"); | |
297 | tree->SetAlias("deltaTIn","(id1+id0*10)"); | |
298 | tree->SetAlias("deltaT","stampSec-stampOldSec"); | |
299 | // | |
300 | tree->SetMarkerStyle(23); tree->SetMarkerSize(0.5); | |
301 | // Memory usage | |
302 | tree->Draw("deltaVM:deltaVMIn","Entry$>0"); | |
303 | // or alternative | |
304 | tree->Draw("deltaVM:deltaVMIn","Entry$>0","prof"); | |
305 | // | |
306 | // draw time usage | |
307 | tree->Draw("deltaT:deltaTIn","Entry$>0"); | |
308 | */ | |
309 | // | |
310 | // The delta of VM as obtained from the AliSysInfo starts to be proportional | |
311 | // to the input allocation after 0.12 MBy (and it is system dependent) | |
312 | // Bellow these limit the deltaVM can be used only in mean. | |
313 | // (compare first and profile histogram) | |
314 | for (Int_t id0=0; id0<5; id0++) | |
315 | for (Int_t id1=1; id1<10; id1++) | |
316 | for (Int_t id2=0; id2<20; id2++){ | |
317 | new Char_t[id2*1000+id1*10000+id0*100000]; // emulate memory leak | |
318 | gSystem->Sleep(id1+id0*10); // emulate CPU usage | |
319 | AliSysInfo::AddStamp("Leak",id0,id1,id2); | |
320 | } | |
321 | TTree * tree = AliSysInfo::MakeTree("syswatch.log"); | |
322 | return tree; | |
323 | } |