00001
00002
00003
00004
00005 #include "ProcStats.h"
00006
00007 #ifdef linux
00008 #include <unistd.h>
00009 #include <iostream>
00010
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;
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 {
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);
00085
00086
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,
00133 pinfo.comm,
00134 &pinfo.state,
00135 &pinfo.ppid,
00136 &pinfo.pgrp,
00137 &pinfo.session,
00138 &pinfo.tty,
00139 &pinfo.tpgid,
00140 &pinfo.flags,
00141 &pinfo.minflt,
00142 &pinfo.cminflt,
00143 &pinfo.majflt,
00144 &pinfo.cmajflt,
00145 &pinfo.utime,
00146 &pinfo.stime,
00147 &pinfo.cutime,
00148 &pinfo.cstime,
00149 &pinfo.counter,
00150 &pinfo.priority,
00151 &pinfo.timeout,
00152 &pinfo.itrealvalue,
00153 &pinfo.starttime,
00154 &pinfo.vsize,
00155 &pinfo.rss,
00156 &pinfo.rlim,
00157 &pinfo.startcode,
00158 &pinfo.endcode,
00159 &pinfo.startstack,
00160 &pinfo.kstkesp,
00161 &pinfo.kstkeip,
00162 &pinfo.signal,
00163 &pinfo.blocked,
00164 &pinfo.sigignore,
00165 &pinfo.sigcatch,
00166 &pinfo.wchan
00167 );
00168
00169
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