|
Gaudi Framework, version v22r2 |
| Home | Generated: Tue May 10 2011 |
00001 // Class: ProcStats 00002 // Purpose: To keep statistics on memory use 00003 // Warning: Only Linux implementation at the present time... 00004 #ifdef __ICC 00005 // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits 00006 // meant 00007 #pragma warning(disable:2259) 00008 #endif 00009 00010 #include "ProcStats.h" 00011 00012 #ifdef __linux 00013 #include <unistd.h> 00014 #include <iostream> 00015 #include <sstream> 00016 #include <fcntl.h> 00017 #include <sys/types.h> 00018 #include <sys/signal.h> 00019 #include <sys/syscall.h> 00020 #include <sys/procfs.h> 00021 #include <cstdio> 00022 00023 using std::cerr; 00024 using std::cout; 00025 using std::endl; 00026 00027 /* Format of the Linux proc/stat (man 5 proc, kernel 2.6.35): 00028 pid %d The process ID. 00029 00030 comm %s The filename of the executable, in parentheses. This is visible 00031 whether or not the executable is swapped out. 00032 00033 state %c One character from the string "RSDZTW" where R is running, S is 00034 sleeping in an interruptible wait, D is waiting in uninterruptible 00035 disk sleep, Z is zombie, T is traced or stopped (on a signal), and 00036 W is paging. 00037 00038 ppid %d The PID of the parent. 00039 00040 pgrp %d The process group ID of the process. 00041 00042 session %d The session ID of the process. 00043 00044 tty_nr %d The controlling terminal of the process. (The minor device number 00045 is contained in the combination of bits 31 to 20 and 7 to 0; the 00046 major device number is in bits 15 t0 8.) 00047 00048 tpgid %d The ID of the foreground process group of the controlling terminal 00049 of the process. 00050 00051 flags %u (%lu before Linux 2.6.22) 00052 The kernel flags word of the process. For bit meanings, see the 00053 PF_* defines in <linux/sched.h>. Details depend on the kernel 00054 version. 00055 00056 minflt %lu The number of minor faults the process has made which have not 00057 required loading a memory page from disk. 00058 00059 cminflt %lu The number of minor faults that the process's waited-for children 00060 have made. 00061 00062 majflt %lu The number of major faults the process has made which have 00063 required loading a memory page from disk. 00064 00065 cmajflt %lu The number of major faults that the process's waited-for children 00066 have made. 00067 00068 utime %lu Amount of time that this process has been scheduled in user mode, 00069 measured in clock ticks (divide by sysconf(_SC_CLK_TCK). This 00070 includes guest time, guest_time (time spent running a virtual CPU, 00071 see below), so that applications that are not aware of the guest 00072 time field do not lose that time from their calculations. 00073 00074 stime %lu Amount of time that this process has been scheduled in kernel 00075 mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK). 00076 00077 cutime %ld Amount of time that this process's waited-for children have been 00078 scheduled in user mode, measured in clock ticks (divide by 00079 sysconf(_SC_CLK_TCK). (See also times(2).) This includes guest 00080 time, cguest_time (time spent running a virtual CPU, see below). 00081 00082 cstime %ld Amount of time that this process's waited-for children have been 00083 scheduled in kernel mode, measured in clock ticks (divide by 00084 sysconf(_SC_CLK_TCK). 00085 00086 priority %ld 00087 (Explanation for Linux 2.6) For processes running a real-time 00088 scheduling policy (policy below; see sched_setscheduler(2)), this 00089 is the negated scheduling priority, minus one; that is, a number 00090 in the range -2 to -100, corresponding to real-time priorities 1 00091 to 99. For processes running under a non-real-time scheduling 00092 policy, this is the raw nice value (setpriority(2)) as represented 00093 in the kernel. The kernel stores nice values as numbers in the 00094 range 0 (high) to 39 (low), corresponding to the user-visible nice 00095 range of -20 to 19. 00096 00097 Before Linux 2.6, this was a scaled value based on the scheduler 00098 weighting given to this process. 00099 00100 nice %ld The nice value (see setpriority(2)), a value in the range 19 (low 00101 priority) to -20 (high priority). 00102 00103 num_threads %ld 00104 Number of threads in this process (since Linux 2.6). Before ker‐ 00105 nel 2.6, this field was hard coded to 0 as a placeholder for an 00106 earlier removed field. 00107 00108 itrealvalue %ld 00109 The time in jiffies before the next SIGALRM is sent to the process 00110 due to an interval timer. Since kernel 2.6.17, this field is no 00111 longer maintained, and is hard coded as 0. 00112 00113 starttime %llu (was %lu before Linux 2.6) 00114 The time in jiffies the process started after system boot. 00115 00116 vsize %lu Virtual memory size in bytes. 00117 00118 rss %ld Resident Set Size: number of pages the process has in real memory. 00119 This is just the pages which count towards text, data, or stack 00120 space. This does not include pages which have not been demand- 00121 loaded in, or which are swapped out. 00122 00123 rsslim %lu Current soft limit in bytes on the rss of the process; see the 00124 description of RLIMIT_RSS in getpriority(2). 00125 00126 startcode %lu 00127 The address above which program text can run. 00128 00129 endcode %lu The address below which program text can run. 00130 00131 startstack %lu 00132 The address of the start (i.e., bottom) of the stack. 00133 00134 kstkesp %lu The current value of ESP (stack pointer), as found in the kernel 00135 stack page for the process. 00136 00137 kstkeip %lu The current EIP (instruction pointer). 00138 00139 signal %lu The bitmap of pending signals, displayed as a decimal number. 00140 Obsolete, because it does not provide information on real-time 00141 signals; use /proc/[pid]/status instead. 00142 00143 blocked %lu The bitmap of blocked signals, displayed as a decimal number. 00144 Obsolete, because it does not provide information on real-time 00145 signals; use /proc/[pid]/status instead. 00146 00147 sigignore %lu 00148 The bitmap of ignored signals, displayed as a decimal number. 00149 Obsolete, because it does not provide information on real-time 00150 signals; use /proc/[pid]/status instead. 00151 00152 sigcatch %lu 00153 The bitmap of caught signals, displayed as a decimal number. 00154 Obsolete, because it does not provide information on real-time 00155 signals; use /proc/[pid]/status instead. 00156 00157 wchan %lu This is the "channel" in which the process is waiting. It is the 00158 address of a system call, and can be looked up in a namelist if 00159 you need a textual name. (If you have an up-to-date 00160 /etc/psdatabase, then try ps -l to see the WCHAN field in action.) 00161 00162 nswap %lu Number of pages swapped (not maintained). 00163 00164 cnswap %lu Cumulative nswap for child processes (not maintained). 00165 00166 exit_signal %d (since Linux 2.1.22) 00167 Signal to be sent to parent when we die. 00168 00169 processor %d (since Linux 2.2.8) 00170 CPU number last executed on. 00171 00172 rt_priority %u (since Linux 2.5.19; was %lu before Linux 2.6.22) 00173 Real-time scheduling priority, a number in the range 1 to 99 for 00174 processes scheduled under a real-time policy, or 0, for non-real- 00175 time processes (see sched_setscheduler(2)). 00176 00177 policy %u (since Linux 2.5.19; was %lu before Linux 2.6.22) 00178 Scheduling policy (see sched_setscheduler(2)). Decode using the 00179 SCHED_* constants in linux/sched.h. 00180 00181 delayacct_blkio_ticks %llu (since Linux 2.6.18) 00182 Aggregated block I/O delays, measured in clock ticks (centisec‐ 00183 onds). 00184 00185 guest_time %lu (since Linux 2.6.24) 00186 Guest time of the process (time spent running a virtual CPU for a 00187 guest operating system), measured in clock ticks (divide by 00188 sysconf(_SC_CLK_TCK). 00189 00190 cguest_time %ld (since Linux 2.6.24) 00191 Guest time of the process's children, measured in clock ticks 00192 (divide by sysconf(_SC_CLK_TCK). 00193 */ 00194 struct linux_proc { 00195 int pid; 00196 char comm[400]; 00197 char state; 00198 int ppid; 00199 int pgrp; 00200 int session; 00201 int tty; 00202 int tpgid; 00203 unsigned long flags; 00204 unsigned long minflt; 00205 unsigned long cminflt; 00206 unsigned long majflt; 00207 unsigned long cmajflt; 00208 unsigned long utime; 00209 unsigned long stime; 00210 long cutime; 00211 long cstime; 00212 long priority; 00213 long nice; 00214 long num_threads; 00215 long itrealvalue; 00216 unsigned long long starttime; 00217 unsigned long vsize; 00218 long rss; 00219 unsigned long rlim; 00220 unsigned long startcode; 00221 unsigned long endcode; 00222 unsigned long startstack; 00223 unsigned long kstkesp; 00224 unsigned long kstkeip; 00225 unsigned long signal; 00226 unsigned long blocked; 00227 unsigned long sigignore; 00228 unsigned long sigcatch; 00229 unsigned long wchan; 00230 }; 00231 #endif // __linux 00232 00233 ProcStats::cleanup::~cleanup() { 00234 if(ProcStats::inst!=0) { 00235 delete ProcStats::inst; 00236 ProcStats::inst=0; 00237 } 00238 } 00239 00240 ProcStats* ProcStats::instance() { 00241 static cleanup c; 00242 if(inst==0) 00243 inst = new ProcStats; 00244 return inst; 00245 } 00246 00247 ProcStats* ProcStats::inst = 0; 00248 00249 ProcStats::ProcStats():valid(false) 00250 { 00251 #ifdef __linux 00252 pg_size = sysconf(_SC_PAGESIZE); // getpagesize(); 00253 std::ostringstream ost; 00254 00255 ost << "/proc/" << getpid() << "/stat"; 00256 fname = ost.str(); 00257 if((fd=open(fname.c_str(),O_RDONLY))<0) 00258 { 00259 cerr << "Failed to open " << ost.str() << endl; 00260 return; 00261 } 00262 #endif 00263 valid=true; 00264 } 00265 00266 ProcStats::~ProcStats() 00267 { 00268 #ifdef __linux 00269 close(fd); 00270 #endif 00271 } 00272 00273 bool ProcStats::fetch(procInfo& f) 00274 { 00275 if( valid == false ) return false; 00276 00277 #ifdef __linux 00278 double pr_size, pr_rssize; 00279 linux_proc pinfo; 00280 int cnt; 00281 00282 lseek(fd,0,SEEK_SET); 00283 00284 if((cnt=read(fd,buf,sizeof(buf)))<0) 00285 { 00286 cout << "LINUX Read of Proc file failed:" << endl; 00287 return false; 00288 } 00289 00290 if(cnt>0) 00291 { 00292 buf[cnt]='\0'; 00293 00294 sscanf(buf, 00295 //1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 20 1 2 3 4 5 6 7 8 9 30 1 2 3 4 5 00296 "%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", 00297 &pinfo.pid, 00298 pinfo.comm, 00299 &pinfo.state, 00300 &pinfo.ppid, 00301 &pinfo.pgrp, 00302 &pinfo.session, 00303 &pinfo.tty, 00304 &pinfo.tpgid, 00305 &pinfo.flags, 00306 &pinfo.minflt, 00307 &pinfo.cminflt, 00308 &pinfo.majflt, 00309 &pinfo.cmajflt, 00310 &pinfo.utime, 00311 &pinfo.stime, 00312 &pinfo.cutime, 00313 &pinfo.cstime, 00314 &pinfo.priority, 00315 &pinfo.nice, 00316 &pinfo.num_threads, 00317 &pinfo.itrealvalue, 00318 &pinfo.starttime, 00319 &pinfo.vsize, 00320 &pinfo.rss, 00321 &pinfo.rlim, 00322 &pinfo.startcode, 00323 &pinfo.endcode, 00324 &pinfo.startstack, 00325 &pinfo.kstkesp, 00326 &pinfo.kstkeip, 00327 &pinfo.signal, 00328 &pinfo.blocked, 00329 &pinfo.sigignore, 00330 &pinfo.sigcatch, 00331 &pinfo.wchan 00332 ); 00333 00334 // resident set size in pages 00335 pr_size = (double)pinfo.vsize; 00336 pr_rssize = (double)pinfo.rss; 00337 00338 f.vsize = pr_size / (1024*1024); 00339 f.rss = pr_rssize * pg_size / (1024*1024); 00340 } 00341 00342 #else 00343 f.vsize = 0; 00344 f.rss = 0; 00345 #endif 00346 00347 bool rc = (curr==f)?false:true; 00348 00349 curr.rss=f.rss; 00350 curr.vsize=f.vsize; 00351 00352 return rc; 00353 } 00354