| # Gaudi Framework, version v21r9 |

Home |  | Generated: 3 May 2010

# ProcStats.cpp

Go to the documentation of this file.

    00001 // $Id: ProcStats.cpp,v 1.4 2006/09/13 14:31:12 hmd Exp $
    00002 // Class: ProcStats
    00003 // Purpose:  To keep statistics on memory use
    00004 // Warning:  Only Linux implementation at the present time...
    00005 #ifdef __ICC
    00006 // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
    00007 //   meant
    00008 #pragma warning(disable:2259)
    00009 #endif
    00010
    00011 #include "ProcStats.h"
    00012
    00013 #ifdef __linux
    00014 #include <unistd.h>
    00015 #include <iostream>
    00016 #include <sstream>
    00017 #include <fcntl.h>
    00018 #include <sys/types.h>
    00019 #include <sys/signal.h>
    00020 #include <sys/syscall.h>
    00021 #include <sys/procfs.h>
    00022 #include <cstdio>
    00023
    00024 using std::cerr;
    00025 using std::cout;
    00026 using std::endl;
    00027
    00028 struct linux_proc {
    00029   int pid; // %d
    00030   char comm[400]; // %s
    00031   char state; // %c
    00032   int ppid; // %d
    00033   int pgrp; // %d
    00034   int session; // %d
    00035   int tty; // %d
    00036   int tpgid; // %d
    00037   unsigned int flags; // %u
    00038   unsigned int minflt; // %u
    00039   unsigned int cminflt; // %u
    00040   unsigned int majflt; // %u
    00041   unsigned int cmajflt; // %u
    00042   int utime; // %d
    00043   int stime; // %d
    00044   int cutime; // %d
    00045   int cstime; // %d
    00046   int counter; // %d
    00047   int priority; // %d
    00048   unsigned int timeout; // %u
    00049   unsigned int itrealvalue; // %u
    00050   int starttime; // %d
    00051   unsigned int vsize; // %u
    00052   unsigned int rss; // %u
    00053   unsigned int rlim; // %u
    00054   unsigned int startcode; // %u
    00055   unsigned int endcode; // %u
    00056   unsigned int startstack; // %u
    00057   unsigned int kstkesp; // %u
    00058   unsigned int kstkeip; // %u
    00059   int signal; // %d
    00060   int blocked; // %d
    00061   int sigignore; // %d
    00062   int sigcatch; // %d
    00063   unsigned int wchan; // %u
    00064 };
    00065 #endif // __linux
    00066
    00067 ProcStats::cleanup::~cleanup() {
    00068   if(ProcStats::inst!=0)  {
    00069     delete ProcStats::inst;
    00070     ProcStats::inst=0;
    00071   }
    00072 }
    00073
    00074 ProcStats* ProcStats::instance() {
    00075   static cleanup c;
    00076   if(inst==0)
    00077     inst = new ProcStats;
    00078   return inst;
    00079 }
    00080
    00081 ProcStats* ProcStats::inst = 0;
    00082
    00083 ProcStats::ProcStats():valid(false)
    00084 {
    00085 #ifdef __linux
    00086   pg_size = sysconf(_SC_PAGESIZE); // getpagesize();
    00087   std::ostringstream ost;
    00088
    00089   ost << "/proc/" << getpid() << "/stat";
    00090   fname = ost.str();
    00091   if((fd=open(fname.c_str(),O_RDONLY))<0)
    00092   {
    00093     cerr << "Failed to open " << ost.str() << endl;
    00094     return;
    00095   }
    00096 #endif
    00097   valid=true;
    00098 }
    00099
    00100 ProcStats::~ProcStats()
    00101 {
    00102 #ifdef __linux
    00103   close(fd);
    00104 #endif
    00105 }
    00106
    00107 bool ProcStats::fetch(procInfo& f)
    00108 {
    00109   if( valid == false ) return false;
    00110
    00111 #ifdef __linux
    00112   double pr_size, pr_rssize;
    00113   linux_proc pinfo;
    00114   int cnt;
    00115
    00116   lseek(fd,0,SEEK_SET);
    00117
    00118   if((cnt=read(fd,buf,sizeof(buf)))<0)
    00119   {
    00120     cout << "LINUX Read of Proc file failed:" << endl;
    00121     return false;
    00122   }
    00123
    00124   if(cnt>0)
    00125   {
    00126     buf[cnt]='\0';
    00127
    00128     sscanf(buf,
    00129       "%d %s %c %d %d %d %d %d %u %u %u %u %u %d %d %d %d %d %d %u %u %d %u %u %u %u %u %u %u %u %d %d %d %d %u",
    00130       &pinfo.pid, // %d
    00131       pinfo.comm, // %s
    00132       &pinfo.state, // %c
    00133       &pinfo.ppid, // %d
    00134       &pinfo.pgrp, // %d
    00135       &pinfo.session, // %d
    00136       &pinfo.tty, // %d
    00137       &pinfo.tpgid, // %d
    00138       &pinfo.flags, // %u
    00139       &pinfo.minflt, // %u
    00140       &pinfo.cminflt, // %u
    00141       &pinfo.majflt, // %u
    00142       &pinfo.cmajflt, // %u
    00143       &pinfo.utime, // %d
    00144       &pinfo.stime, // %d
    00145       &pinfo.cutime, // %d
    00146       &pinfo.cstime, // %d
    00147       &pinfo.counter, // %d
    00148       &pinfo.priority, // %d
    00149       &pinfo.timeout, // %u
    00150       &pinfo.itrealvalue, // %u
    00151       &pinfo.starttime, // %d
    00152       &pinfo.vsize, // %u
    00153       &pinfo.rss, // %u
    00154       &pinfo.rlim, // %u
    00155       &pinfo.startcode, // %u
    00156       &pinfo.endcode, // %u
    00157       &pinfo.startstack, // %u
    00158       &pinfo.kstkesp, // %u
    00159       &pinfo.kstkeip, // %u
    00160       &pinfo.signal, // %d
    00161       &pinfo.blocked, // %d
    00162       &pinfo.sigignore, // %d
    00163       &pinfo.sigcatch, // %d
    00164       &pinfo.wchan // %u
    00165       );
    00166
    00167       // resident set size in pages
    00168     pr_size = (double)pinfo.vsize;
    00169     pr_rssize = (double)pinfo.rss;
    00170
    00171     f.vsize = pr_size   / (1024*1024);
    00172     f.rss   = pr_rssize * pg_size / (1024*1024);
    00173   }
    00174
    00175 #else
    00176   f.vsize = 0;
    00177   f.rss   = 0;
    00178 #endif
    00179
    00180   bool rc = (curr==f)?false:true;
    00181
    00182   curr.rss=f.rss;
    00183   curr.vsize=f.vsize;
    00184
    00185   return rc;
    00186 }
    00187