]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliMemoryWatcher.cxx
Separated TOF libraries (base,rec,sim)
[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 #ifdef __APPLE__
48 #include <stdlib.h>
49 #else
50 #include <malloc.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 {
67   //ctor
68   fMAXSIZE=maxsize;
69   fUseMallinfo = true;
70   fPID = gSystem->GetPid();
71   sprintf(fCmd,"ps -h -p %d -o vsize,rssize",fPID);
72   fX = new Int_t[fMAXSIZE];
73   fVSIZE = new Int_t[fMAXSIZE];
74   fRSSIZE = new Int_t[fMAXSIZE];
75   fTIME = new Double_t[fMAXSIZE];
76   fSize=0;
77   fDisabled=false;
78   fTimer=0;
79 }
80 //_____________________________________________________________________________
81 AliMemoryWatcher::AliMemoryWatcher(const AliMemoryWatcher& mw):
82   TObject(mw)
83 {
84   //copy ctor
85   fMAXSIZE = mw.fMAXSIZE ;
86   fUseMallinfo = mw.fUseMallinfo;
87   fPID = mw.fPID ; 
88   strcpy(fCmd, mw.fCmd) ; 
89   fX = new Int_t[fMAXSIZE];
90   fVSIZE = new Int_t[fMAXSIZE];
91   fRSSIZE = new Int_t[fMAXSIZE];
92   fTIME = new Double_t[fMAXSIZE];
93   fSize=0;
94   fDisabled=false;
95   fTimer=0;   
96 }
97 //_____________________________________________________________________________
98 AliMemoryWatcher::~AliMemoryWatcher()
99 {
100   // dtor
101   delete[] fVSIZE;
102   delete[] fRSSIZE;
103   delete[] fX;
104   delete[] fTIME;
105   delete fTimer;
106 }
107 //_____________________________________________________________________________
108 void AliMemoryWatcher::Watch(Int_t x)
109 {
110   // Sets the point where CPU parameters have to be monitored
111   if ( !fDisabled && fSize < fMAXSIZE ) {
112     if ( fSize==0 ) {
113       assert(fTimer==0);
114       fTimer = new TStopwatch;
115       fTimer->Start(true);
116       fTimer->Stop();
117     }
118     if ( fUseMallinfo ) {
119 #ifdef __linux
120       static struct mallinfo meminfo;
121       meminfo = mallinfo();
122       fX[fSize] = x ;
123       fVSIZE[fSize] = (meminfo.hblkhd + meminfo.uordblks) / 1024;
124       fRSSIZE[fSize] =  meminfo.uordblks / 1024;
125       fTIME[fSize] = fTimer->CpuTime();
126       fSize++;
127 #else
128       AliFatal("Please SetUseMallinfo to kFALSE on this system");
129 #endif
130     } else {
131       static Int_t vsize, rssize;
132       static FILE* pipe = 0;
133       pipe = popen(fCmd,"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       assert(pclose(pipe)!=-1);
145     }
146     fTimer->Start(true);
147   }
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::Write(const char *, Int_t, Int_t)
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 }