![]() |
|
|
Generated: 8 Jan 2009 |
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 00006 #include "ProcStats.h" 00007 00008 #ifdef __linux 00009 #include <unistd.h> 00010 #include <iostream> 00011 #include <sstream> 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 if(ProcStats::inst!=0) { 00064 delete ProcStats::inst; 00065 ProcStats::inst=0; 00066 } 00067 } 00068 00069 ProcStats* ProcStats::instance() { 00070 static cleanup c; 00071 if(inst==0) 00072 inst = new ProcStats; 00073 return inst; 00074 } 00075 00076 ProcStats* ProcStats::inst = 0; 00077 00078 ProcStats::ProcStats():valid(false) 00079 { 00080 #ifdef __linux 00081 pg_size = sysconf(_SC_PAGESIZE); // getpagesize(); 00082 std::ostringstream ost; 00083 00084 ost << "/proc/" << getpid() << "/stat"; 00085 fname = ost.str(); 00086 if((fd=open(fname.c_str(),O_RDONLY))<0) 00087 { 00088 cerr << "Failed to open " << ost.str() << endl; 00089 return; 00090 } 00091 #endif 00092 valid=true; 00093 } 00094 00095 ProcStats::~ProcStats() 00096 { 00097 #ifdef __linux 00098 close(fd); 00099 #endif 00100 } 00101 00102 bool ProcStats::fetch(procInfo& f) 00103 { 00104 if( valid == false ) return false; 00105 00106 #ifdef __linux 00107 double pr_size, pr_rssize; 00108 linux_proc pinfo; 00109 int cnt; 00110 00111 lseek(fd,0,SEEK_SET); 00112 00113 if((cnt=read(fd,buf,sizeof(buf)))<0) 00114 { 00115 cout << "LINUX Read of Proc file failed:" << endl; 00116 return false; 00117 } 00118 00119 if(cnt>0) 00120 { 00121 buf[cnt]='\0'; 00122 00123 sscanf(buf, 00124 "%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", 00125 &pinfo.pid, // %d 00126 pinfo.comm, // %s 00127 &pinfo.state, // %c 00128 &pinfo.ppid, // %d 00129 &pinfo.pgrp, // %d 00130 &pinfo.session, // %d 00131 &pinfo.tty, // %d 00132 &pinfo.tpgid, // %d 00133 &pinfo.flags, // %u 00134 &pinfo.minflt, // %u 00135 &pinfo.cminflt, // %u 00136 &pinfo.majflt, // %u 00137 &pinfo.cmajflt, // %u 00138 &pinfo.utime, // %d 00139 &pinfo.stime, // %d 00140 &pinfo.cutime, // %d 00141 &pinfo.cstime, // %d 00142 &pinfo.counter, // %d 00143 &pinfo.priority, // %d 00144 &pinfo.timeout, // %u 00145 &pinfo.itrealvalue, // %u 00146 &pinfo.starttime, // %d 00147 &pinfo.vsize, // %u 00148 &pinfo.rss, // %u 00149 &pinfo.rlim, // %u 00150 &pinfo.startcode, // %u 00151 &pinfo.endcode, // %u 00152 &pinfo.startstack, // %u 00153 &pinfo.kstkesp, // %u 00154 &pinfo.kstkeip, // %u 00155 &pinfo.signal, // %d 00156 &pinfo.blocked, // %d 00157 &pinfo.sigignore, // %d 00158 &pinfo.sigcatch, // %d 00159 &pinfo.wchan // %u 00160 ); 00161 00162 // resident set size in pages 00163 pr_size = (double)pinfo.vsize; 00164 pr_rssize = (double)pinfo.rss; 00165 00166 f.vsize = pr_size / (1024*1024); 00167 f.rss = pr_rssize * pg_size / (1024*1024); 00168 } 00169 00170 #else 00171 f.vsize = 0; 00172 f.rss = 0; 00173 #endif 00174 00175 bool rc = (curr==f)?false:true; 00176 00177 curr.rss=f.rss; 00178 curr.vsize=f.vsize; 00179 00180 return rc; 00181 } 00182