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