00001
00002
00003
00004
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;
00025 char comm[400];
00026 char state;
00027 int ppid;
00028 int pgrp;
00029 int session;
00030 int tty;
00031 int tpgid;
00032 unsigned int flags;
00033 unsigned int minflt;
00034 unsigned int cminflt;
00035 unsigned int majflt;
00036 unsigned int cmajflt;
00037 int utime;
00038 int stime;
00039 int cutime;
00040 int cstime;
00041 int counter;
00042 int priority;
00043 unsigned int timeout;
00044 unsigned int itrealvalue;
00045 int starttime;
00046 unsigned int vsize;
00047 unsigned int rss;
00048 unsigned int rlim;
00049 unsigned int startcode;
00050 unsigned int endcode;
00051 unsigned int startstack;
00052 unsigned int kstkesp;
00053 unsigned int kstkeip;
00054 int signal;
00055 int blocked;
00056 int sigignore;
00057 int sigcatch;
00058 unsigned int wchan;
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);
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,
00126 pinfo.comm,
00127 &pinfo.state,
00128 &pinfo.ppid,
00129 &pinfo.pgrp,
00130 &pinfo.session,
00131 &pinfo.tty,
00132 &pinfo.tpgid,
00133 &pinfo.flags,
00134 &pinfo.minflt,
00135 &pinfo.cminflt,
00136 &pinfo.majflt,
00137 &pinfo.cmajflt,
00138 &pinfo.utime,
00139 &pinfo.stime,
00140 &pinfo.cutime,
00141 &pinfo.cstime,
00142 &pinfo.counter,
00143 &pinfo.priority,
00144 &pinfo.timeout,
00145 &pinfo.itrealvalue,
00146 &pinfo.starttime,
00147 &pinfo.vsize,
00148 &pinfo.rss,
00149 &pinfo.rlim,
00150 &pinfo.startcode,
00151 &pinfo.endcode,
00152 &pinfo.startstack,
00153 &pinfo.kstkesp,
00154 &pinfo.kstkeip,
00155 &pinfo.signal,
00156 &pinfo.blocked,
00157 &pinfo.sigignore,
00158 &pinfo.sigcatch,
00159 &pinfo.wchan
00160 );
00161
00162
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