00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <math.h>
00014 #include <malloc.h>
00015 #include <unistd.h>
00016 #include "StMemStat.h"
00017 #include "TList.h"
00018 #include "TError.h"
00019 #include <cassert>
00020
00021 Double_t StMemStat::fgUsed=0;
00022 TList *StMemStat::fgList=0;
00023 ClassImp(StMemStat)
00024
00025 #define LOWEST_VAL 0.0000001
00028 //______________________________________________________________________________
00029 StMemStat::StMemStat(const char *name):TNamed(name,"")
00030 {
00031 int n = (char*)&fTally - (char*)&fLast + sizeof(fTally);
00032 memset(&fLast,0,n);
00033 fMin = 1.e+33;
00034 fMax = -1.e+33;
00035 if (!fgList) fgList=new TList;
00036 fgList->Add(this);
00037 }
00038
00039 StMemStat::~StMemStat()
00040 {
00041 fgList->Remove(this);
00042 if (!fgList->First()) {delete fgList; fgList=0;}
00043 }
00044
00045
00046 void StMemStat::Start()
00047 {
00048 fLast = Used();
00049 }
00050
00051
00052 void StMemStat::Stop()
00053 {
00054 fTally++;
00055 Double_t dif = Used() - fLast;
00056
00057
00058 if ( fabs(dif) < LOWEST_VAL ) dif = 0.0;
00059 if ( dif < fMin ) fMin = dif;
00060 if ( dif > fMax ) fMax = dif;
00061
00062 fAver += dif;
00063 fRms += (dif*dif);
00064
00065 }
00066
00067 void StMemStat::Print(const char *) const
00068 {
00069 if (!fTally) return;
00070 Double_t aver = fAver/fTally;
00071 Double_t rms = ::sqrt(fabs(fRms/fTally - aver*aver));
00072
00073
00074 if ( fabs(aver) < LOWEST_VAL ) aver = 0.0;
00075 if ( rms < LOWEST_VAL ) rms = 0.0;
00076
00077 printf("%40.40s(%d)%12.6f%12.6f%12.6f%12.6f\n",
00078 GetName(),fTally,fMin,aver,fMax,rms);
00079 }
00080
00081 void StMemStat::Summary()
00082 {
00083 #define NUMTICKS (40+4*12+5)
00084
00085 Double_t dmin=1.e+33,daver=0,dmax=-1.e+33,drms=0,dtally=0,dmp;
00086 int i;
00087
00088 if(!fgList) return;
00089 fgList->Sort();
00090 printf("%40.40s%12s%12s%12s%12s\n",
00091 "StMemStat::Summary(calls)","Min ","Aver ","Max ","RMS ");
00092
00093 for( i=0 ; i < NUMTICKS ; i++) printf("=");
00094 printf("\n");
00095
00096 TListIter next(fgList);
00097 StMemStat *m;
00098 while((m = (StMemStat*)next())){
00099 if(!m->fTally) continue;
00100 m->Print();
00101 dtally++;
00102 if (m->fMin < dmin) dmin=m->fMin;
00103 if (m->fMax > dmax) dmax=m->fMax;
00104 dmp = m->fAver/m->fTally;
00105 daver += dmp;
00106 drms += fabs(m->fRms/m->fTally-dmp*dmp);
00107
00108 }
00109 if(!dtally) return;
00110
00111 for( i=0 ; i < NUMTICKS ; i++) printf("-");
00112 printf("\n");
00113
00114
00115 drms = ::sqrt(fabs(drms));
00116 printf("%40.40s(%d)%12.6f%12.6f%12.6f%12.6f\n",
00117 "Total",(int)dtally,dmin,daver,dmax,drms);
00118
00119 for( i=0 ; i < NUMTICKS ; i++) printf("=");
00120 printf("\n");
00121
00122 }
00123
00124
00125 Double_t StMemStat::Used()
00126 {
00127 struct mallinfo info;
00128 info = mallinfo();
00129 return double(info.uordblks + info.usmblks)/1000000;
00130 }
00131
00132 Double_t StMemStat::Free()
00133 {
00134 struct mallinfo info;
00135 info = mallinfo();
00136 return double(info.fordblks + info.fsmblks)/1000000;
00137 }
00138
00139
00140 Double_t StMemStat::ProgSize()
00141 {
00142 Double_t res=0;
00143 int pid = ::getpid();
00144 char line[100];
00145 sprintf(line,"/proc/%d/status",pid);
00146
00147 FILE *proc = fopen(line,"r");
00148 if (proc) {
00149 while (fgets(line,100,proc)) {
00150 if (strncmp("VmSize:",line,7)==0) {
00151 fclose(proc);
00152 char *aft=0;
00153 res = (strtod(line+7,&aft));
00154 while ((++aft)[0]==' '){}
00155 int b = 0;
00156 if (strncmp("kB",aft,2)==0) b = 1024;
00157 if (strncmp("mB",aft,2)==0) b = 1024*1024;
00158 if (strncmp("gB",aft,2)==0) b = 1024*1024*1024;
00159 res = (res*b)/(1024*1024);
00160 return res;
00161 }
00162 }
00163 fclose(proc);
00164 }
00165
00166 static char *ps = 0;
00167 if (!ps) {
00168 ps = (char*)malloc(25);
00169 sprintf(ps,"/bin/ps -l -p %d",pid);
00170 }
00171 FILE *pipe = ::popen(ps,"r");
00172 if (!pipe) return 0.;
00173
00174 char psBuf[130];
00175 psBuf[0] = ' ';
00176 while( !feof( pipe ) ) {
00177 psBuf[1]=0;
00178 if(!fgets( psBuf+1, 128, pipe)) continue;
00179
00180 int ifild=0;char *c;
00181
00182 for (c=psBuf; c[0]; c++) {
00183 if (c[0]==' ' && c[1]!=' ') ifild++;
00184 if (ifild == 10) break;
00185 }
00186 res = (Double_t) atoi(c+1);
00187 if (res) break;
00188 }
00189 ::pclose(pipe);
00190 res *=::getpagesize()/(1024.*1024.);
00191
00192 return res;
00193 }
00194
00195
00196 void StMemStat::PrintMem(const char *tit)
00197 {
00198 Double_t used = Used();
00199 Double_t free = Free();
00200 Double_t exec = ProgSize();
00201
00202 if (tit) printf("\nStMemStat::%s",tit);
00203 printf("\t total =%10.6f heap =%10.6f and %10.6f(%+10.6f)\n",exec,used,free,used-fgUsed);
00204 fgUsed = used;
00205 }
00206
00207 void StMemStat::PM()
00208 {
00209 Double_t used = Used();
00210 printf("\nStMemStat: ");
00211 printf("StMemStat::heap =%10.6f(%+10.6f)\n",used,used-fgUsed);
00212 fgUsed = used;
00213 }
00214
00215 void StMemStat::Streamer(TBuffer&)
00216 {assert(0);}
00217
00218
00219