Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

ProcStats.cpp

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

Generated at Wed Nov 21 12:20:02 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000