Coverity 16571
[u/mrichter/AliRoot.git] / STEER / AliMemoryWatcher.cxx
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 /* $Id$ */
16
17 //_________________________________________________________________________
18 //Basic Memory Leak utility.    
19 //     You can use this tiny class to *see* if your program is leaking.
20 //     Usage:
21 //     AliMemoryWatcher memwatcher;
22 //     some program loop on events here {
23 //       if ( nevents % x == 0 ) 
24 //       {
25 //       // take a sample every x events
26 //         memwatcher.Watch(nevents);
27 //       }
28 //     }
29 //     TFile f("out.root","RECREATE");
30 //     memwatcher.Write();
31 //     f.Close();
32 //     In the output root file you'll get 3 graphs representing
33 //     the evolAliPHOSon, as a function of the number of events, of :
34 //     - VSIZE is the virtual size (in KBytes) of your program, that is sort of
35 //     the total memory used
36 //     - RSSIZE is the resident size (in KBytes), that is, the part of your 
37 //     program which is really in physical memory.
38 //     - TIME is an estimate of time per event (really it's the time elasped
39 //     between two calls to watch method)
40 //     WARNING: this is far from a bulletproof memory report (it's basically 
41 //     using UNIX command ps -h -p [PID] -o vsize,rssize to do its job).
42 //     It has only been tested on Linux so far.    
43 //     But by fitting the VSIZE by a pol1 under ROOT, you'll see right away
44 //     by how much your program is leaking.          
45 //*-- Author: Laurent Aphecetche(SUBATECH)
46
47 // --- std system ---
48 #include <cassert> 
49 #ifdef NEVER
50 #include <stdlib.h>
51 #endif
52 // --- AliRoot header files ---
53 #include "AliLog.h"
54 #include "AliMemoryWatcher.h"
55 // --- ROOT system ---
56 #include "TSystem.h"
57 #include "TGraph.h"
58 #include "TH2.h"
59 #include "TStopwatch.h"
60 #include "TError.h"
61
62 ClassImp(AliMemoryWatcher)
63
64 //_____________________________________________________________________________
65 AliMemoryWatcher::AliMemoryWatcher(UInt_t maxsize) :
66   TObject(),
67   fMAXSIZE(maxsize),
68   fSize(0),
69   fX(new Int_t[fMAXSIZE]),
70   fVSIZE(new Int_t[fMAXSIZE]),
71   fRSSIZE(new Int_t[fMAXSIZE]),
72   fTIME(new Double_t[fMAXSIZE]),
73   fTimer(0),
74   fDisabled(kFALSE)
75 {
76   //
77   //ctor
78   //
79 }
80
81 //_____________________________________________________________________________
82 AliMemoryWatcher::AliMemoryWatcher(const AliMemoryWatcher& mw):
83   TObject(mw),
84   fMAXSIZE(mw.fMAXSIZE),
85   fSize(0),
86   fX(new Int_t[fMAXSIZE]),
87   fVSIZE(new Int_t[fMAXSIZE]),
88   fRSSIZE(new Int_t[fMAXSIZE]),
89   fTIME(new Double_t[fMAXSIZE]),
90   fTimer(0),
91   fDisabled(kFALSE)
92 {
93   //copy ctor
94 }
95
96 //_____________________________________________________________________________
97 AliMemoryWatcher::~AliMemoryWatcher()
98 {
99   // dtor
100   delete[] fVSIZE;
101   delete[] fRSSIZE;
102   delete[] fX;
103   delete[] fTIME;
104   delete fTimer;
105 }
106 //_____________________________________________________________________________
107 void AliMemoryWatcher::Watch(Int_t x)
108 {
109   static ProcInfo_t meminfo;
110 #ifdef NEVER
111   static Char_t cmd[1024]="";
112 #endif
113   // Sets the point where CPU parameters have to be monitored
114   if ( !fDisabled && fSize < fMAXSIZE ) {
115     if ( fSize==0 ) {
116       fTimer = new TStopwatch;
117       fTimer->Start(true);
118       fTimer->Stop();
119 #ifdef NEVER
120       if(!cmd[0])  
121         sprintf(cmd,"ps -h -p %d -o vsz,rss | grep -v VSZ",gSystem->GetPid());
122 #endif
123     }
124     gSystem->GetProcInfo(&meminfo);
125     fX[fSize]      = x ;
126     fVSIZE[fSize]  = meminfo.fMemVirtual /  1024;
127     fRSSIZE[fSize] = meminfo.fMemResident / 1024;
128     fTIME[fSize]   = fTimer->CpuTime();
129     fSize++;
130 #ifdef NEVER
131     Int_t vsize, rssize;
132     FILE* pipe = 0;
133     pipe = popen(cmd,"r");
134     if ( pipe ) {
135       
136       fscanf(pipe,"%d %d",&vsize,&rssize);
137       
138       fX[fSize] = x ;
139       fVSIZE[fSize] = vsize ;
140       fRSSIZE[fSize] = rssize ;
141       fTIME[fSize] = fTimer->CpuTime();
142       fSize++;
143     }
144     Int_t iclose=pclose(pipe);
145     assert(iclose!=-1);
146 #endif
147     fTimer->Start(true);
148   } else {
149     fDisabled=true;
150     AliError("I'm full !" ) ;
151   }
152 }
153 //_____________________________________________________________________________
154 TGraph*
155 AliMemoryWatcher::GraphVSIZE(void)
156 {
157   // Fills the graph with the virtual memory sized used
158   TGraph* g = 0;
159   if ( Size() )
160     {
161       g = new TGraph(Size());
162       Int_t i ; 
163       for (i=0; i < g->GetN(); i++ ) {
164         g->SetPoint(i,X(i),VSIZE(i));
165       }
166     }
167   return g;
168 }
169 //_____________________________________________________________________________
170 TGraph*
171 AliMemoryWatcher::GraphRSSIZE(void)
172 {
173   // Fills the graph with the real memory sized used
174   TGraph* g = 0;
175   if ( Size() ) 
176     {
177       g = new TGraph(Size());
178       Int_t i ; 
179       for (i=0; i < g->GetN(); i++ ) {
180         g->SetPoint(i,X(i),RSSIZE(i));
181       }
182     }
183   return g;
184 }
185 //_____________________________________________________________________________
186 TGraph*
187 AliMemoryWatcher::GraphTIME(void)
188 {
189   // Fills the raph with the used CPU time
190   TGraph* g = 0;
191   if ( Size() ) 
192     {
193       g = new TGraph(Size());
194       Int_t i ; 
195       for (i=0; i < g->GetN(); i++ ) {
196         g->SetPoint(i,X(i),TIME(i));
197       }
198     }
199   return g;
200 }
201 //_____________________________________________________________________________
202 TH2*
203 AliMemoryWatcher::Frame(void) const
204 {
205   //creates the frame histo in which the graphs will be plotted 
206   Double_t xmin=1E30;
207   Double_t xmax=0;
208   Double_t ymin=1;
209   Double_t ymax=0;
210   UInt_t i ; 
211   for (i=0; i < Size() ; i++ ) {
212     if ( X(i) < xmin ) xmin = X(i);
213     if ( X(i) > xmax ) xmax = X(i);
214     Double_t y = VSIZE(i)+RSSIZE(i);
215     if ( y > ymax ) ymax = y;
216     if ( VSIZE(i) < ymin ) ymin = VSIZE(i);
217     if ( RSSIZE(i) < ymin ) ymin = RSSIZE(i);
218   }
219   TH2F* h = new TH2F("frame","",10,xmin,xmax,10,ymin*0.8,ymax*1.2);
220   return h;
221 }
222 //_____________________________________________________________________________
223 Int_t
224 AliMemoryWatcher::WriteToFile()
225 {
226   // Stores the graphs in a file 
227   if ( GraphVSIZE() ) GraphVSIZE()->Write("VSIZE",TObject::kOverwrite);
228   if ( GraphRSSIZE() ) GraphRSSIZE() ->Write("RSSIZE",TObject::kOverwrite);
229   if ( GraphTIME() ) GraphTIME()->Write("TIME",TObject::kOverwrite);
230   return 0;
231 }