All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ProcStats.cpp
Go to the documentation of this file.
1 // Class: ProcStats
2 // Purpose: To keep statistics on memory use
3 // Warning: Only Linux implementation at the present time...
4 #ifdef __ICC
5 // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
6 // meant
7 #pragma warning(disable:2259)
8 #endif
9 
10 #include "ProcStats.h"
11 
12 #ifdef __linux
13 #include <iostream>
14 #include <sstream>
15 #include <sys/signal.h>
16 #include <sys/syscall.h>
17 #include <sys/procfs.h>
18 #include <cstdio>
19 
20 using std::cerr;
21 using std::cout;
22 using std::endl;
23 
24 /* Format of the Linux proc/stat (man 5 proc, kernel 2.6.35):
25  pid %d The process ID.
26 
27  comm %s The filename of the executable, in parentheses. This is visible
28  whether or not the executable is swapped out.
29 
30  state %c One character from the string "RSDZTW" where R is running, S is
31  sleeping in an interruptible wait, D is waiting in uninterruptible
32  disk sleep, Z is zombie, T is traced or stopped (on a signal), and
33  W is paging.
34 
35  ppid %d The PID of the parent.
36 
37  pgrp %d The process group ID of the process.
38 
39  session %d The session ID of the process.
40 
41  tty_nr %d The controlling terminal of the process. (The minor device number
42  is contained in the combination of bits 31 to 20 and 7 to 0; the
43  major device number is in bits 15 t0 8.)
44 
45  tpgid %d The ID of the foreground process group of the controlling terminal
46  of the process.
47 
48  flags %u (%lu before Linux 2.6.22)
49  The kernel flags word of the process. For bit meanings, see the
50  PF_* defines in <linux/sched.h>. Details depend on the kernel
51  version.
52 
53  minflt %lu The number of minor faults the process has made which have not
54  required loading a memory page from disk.
55 
56  cminflt %lu The number of minor faults that the process's waited-for children
57  have made.
58 
59  majflt %lu The number of major faults the process has made which have
60  required loading a memory page from disk.
61 
62  cmajflt %lu The number of major faults that the process's waited-for children
63  have made.
64 
65  utime %lu Amount of time that this process has been scheduled in user mode,
66  measured in clock ticks (divide by sysconf(_SC_CLK_TCK). This
67  includes guest time, guest_time (time spent running a virtual CPU,
68  see below), so that applications that are not aware of the guest
69  time field do not lose that time from their calculations.
70 
71  stime %lu Amount of time that this process has been scheduled in kernel
72  mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK).
73 
74  cutime %ld Amount of time that this process's waited-for children have been
75  scheduled in user mode, measured in clock ticks (divide by
76  sysconf(_SC_CLK_TCK). (See also times(2).) This includes guest
77  time, cguest_time (time spent running a virtual CPU, see below).
78 
79  cstime %ld Amount of time that this process's waited-for children have been
80  scheduled in kernel mode, measured in clock ticks (divide by
81  sysconf(_SC_CLK_TCK).
82 
83  priority %ld
84  (Explanation for Linux 2.6) For processes running a real-time
85  scheduling policy (policy below; see sched_setscheduler(2)), this
86  is the negated scheduling priority, minus one; that is, a number
87  in the range -2 to -100, corresponding to real-time priorities 1
88  to 99. For processes running under a non-real-time scheduling
89  policy, this is the raw nice value (setpriority(2)) as represented
90  in the kernel. The kernel stores nice values as numbers in the
91  range 0 (high) to 39 (low), corresponding to the user-visible nice
92  range of -20 to 19.
93 
94  Before Linux 2.6, this was a scaled value based on the scheduler
95  weighting given to this process.
96 
97  nice %ld The nice value (see setpriority(2)), a value in the range 19 (low
98  priority) to -20 (high priority).
99 
100  num_threads %ld
101  Number of threads in this process (since Linux 2.6). Before ker‐
102  nel 2.6, this field was hard coded to 0 as a placeholder for an
103  earlier removed field.
104 
105  itrealvalue %ld
106  The time in jiffies before the next SIGALRM is sent to the process
107  due to an interval timer. Since kernel 2.6.17, this field is no
108  longer maintained, and is hard coded as 0.
109 
110  starttime %llu (was %lu before Linux 2.6)
111  The time in jiffies the process started after system boot.
112 
113  vsize %lu Virtual memory size in bytes.
114 
115  rss %ld Resident Set Size: number of pages the process has in real memory.
116  This is just the pages which count towards text, data, or stack
117  space. This does not include pages which have not been demand-
118  loaded in, or which are swapped out.
119 
120  rsslim %lu Current soft limit in bytes on the rss of the process; see the
121  description of RLIMIT_RSS in getpriority(2).
122 
123  startcode %lu
124  The address above which program text can run.
125 
126  endcode %lu The address below which program text can run.
127 
128  startstack %lu
129  The address of the start (i.e., bottom) of the stack.
130 
131  kstkesp %lu The current value of ESP (stack pointer), as found in the kernel
132  stack page for the process.
133 
134  kstkeip %lu The current EIP (instruction pointer).
135 
136  signal %lu The bitmap of pending signals, displayed as a decimal number.
137  Obsolete, because it does not provide information on real-time
138  signals; use /proc/[pid]/status instead.
139 
140  blocked %lu The bitmap of blocked signals, displayed as a decimal number.
141  Obsolete, because it does not provide information on real-time
142  signals; use /proc/[pid]/status instead.
143 
144  sigignore %lu
145  The bitmap of ignored signals, displayed as a decimal number.
146  Obsolete, because it does not provide information on real-time
147  signals; use /proc/[pid]/status instead.
148 
149  sigcatch %lu
150  The bitmap of caught signals, displayed as a decimal number.
151  Obsolete, because it does not provide information on real-time
152  signals; use /proc/[pid]/status instead.
153 
154  wchan %lu This is the "channel" in which the process is waiting. It is the
155  address of a system call, and can be looked up in a namelist if
156  you need a textual name. (If you have an up-to-date
157  /etc/psdatabase, then try ps -l to see the WCHAN field in action.)
158 
159  nswap %lu Number of pages swapped (not maintained).
160 
161  cnswap %lu Cumulative nswap for child processes (not maintained).
162 
163  exit_signal %d (since Linux 2.1.22)
164  Signal to be sent to parent when we die.
165 
166  processor %d (since Linux 2.2.8)
167  CPU number last executed on.
168 
169  rt_priority %u (since Linux 2.5.19; was %lu before Linux 2.6.22)
170  Real-time scheduling priority, a number in the range 1 to 99 for
171  processes scheduled under a real-time policy, or 0, for non-real-
172  time processes (see sched_setscheduler(2)).
173 
174  policy %u (since Linux 2.5.19; was %lu before Linux 2.6.22)
175  Scheduling policy (see sched_setscheduler(2)). Decode using the
176  SCHED_* constants in linux/sched.h.
177 
178  delayacct_blkio_ticks %llu (since Linux 2.6.18)
179  Aggregated block I/O delays, measured in clock ticks (centisec‐
180  onds).
181 
182  guest_time %lu (since Linux 2.6.24)
183  Guest time of the process (time spent running a virtual CPU for a
184  guest operating system), measured in clock ticks (divide by
185  sysconf(_SC_CLK_TCK).
186 
187  cguest_time %ld (since Linux 2.6.24)
188  Guest time of the process's children, measured in clock ticks
189  (divide by sysconf(_SC_CLK_TCK).
190 */
191 struct linux_proc {
192  int pid;
193  char comm[400];
194  char state;
195  int ppid;
196  int pgrp;
197  int session;
198  int tty;
199  int tpgid;
200  unsigned long flags;
201  unsigned long minflt;
202  unsigned long cminflt;
203  unsigned long majflt;
204  unsigned long cmajflt;
205  unsigned long utime;
206  unsigned long stime;
207  long cutime;
208  long cstime;
209  long priority;
210  long nice;
211  long num_threads;
212  long itrealvalue;
213  unsigned long long starttime;
214  unsigned long vsize;
215  long rss;
216  unsigned long rlim;
217  unsigned long startcode;
218  unsigned long endcode;
219  unsigned long startstack;
220  unsigned long kstkesp;
221  unsigned long kstkeip;
222  unsigned long signal;
223  unsigned long blocked;
224  unsigned long sigignore;
225  unsigned long sigcatch;
226  unsigned long wchan;
227 };
228 #endif // __linux
229 
231  if(ProcStats::inst!=0) {
232  delete ProcStats::inst;
233  ProcStats::inst=0;
234  }
235 }
236 
238  static cleanup c;
239  if(!inst) inst = new ProcStats;
240  return inst;
241 }
242 
244 
246 {
247 #ifdef __linux
248  pg_size = sysconf(_SC_PAGESIZE); // getpagesize();
249 
250  fname = "/proc/" + std::to_string(getpid()) + "/stat";
251 
252  fd.open( fname.c_str(), O_RDONLY );
253  if(!fd)
254  {
255  cerr << "Failed to open " << fname << endl;
256  return;
257  }
258 #endif
259  valid=true;
260 }
261 
262 
264 {
265  if( valid == false ) return false;
266 
267 #ifdef __linux
268  double pr_size, pr_rssize;
269  linux_proc pinfo;
270  int cnt;
271 
272  fd.lseek(0,SEEK_SET);
273 
274  if((cnt=fd.read(buf,sizeof(buf)))<0)
275  {
276  cout << "LINUX Read of Proc file failed:" << endl;
277  return false;
278  }
279 
280  if(cnt>0)
281  {
282  buf[cnt]='\0';
283 
284  sscanf(buf,
285  //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
286  "%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",
287  &pinfo.pid,
288  pinfo.comm,
289  &pinfo.state,
290  &pinfo.ppid,
291  &pinfo.pgrp,
292  &pinfo.session,
293  &pinfo.tty,
294  &pinfo.tpgid,
295  &pinfo.flags,
296  &pinfo.minflt,
297  &pinfo.cminflt,
298  &pinfo.majflt,
299  &pinfo.cmajflt,
300  &pinfo.utime,
301  &pinfo.stime,
302  &pinfo.cutime,
303  &pinfo.cstime,
304  &pinfo.priority,
305  &pinfo.nice,
306  &pinfo.num_threads,
307  &pinfo.itrealvalue,
308  &pinfo.starttime,
309  &pinfo.vsize,
310  &pinfo.rss,
311  &pinfo.rlim,
312  &pinfo.startcode,
313  &pinfo.endcode,
314  &pinfo.startstack,
315  &pinfo.kstkesp,
316  &pinfo.kstkeip,
317  &pinfo.signal,
318  &pinfo.blocked,
319  &pinfo.sigignore,
320  &pinfo.sigcatch,
321  &pinfo.wchan
322  );
323 
324  // resident set size in pages
325  pr_size = (double)pinfo.vsize;
326  pr_rssize = (double)pinfo.rss;
327 
328  f.vsize = pr_size / (1024*1024);
329  f.rss = pr_rssize * pg_size / (1024*1024);
330  }
331 
332 #else
333  f.vsize = 0;
334  f.rss = 0;
335 #endif
336 
337  bool rc = (curr==f)?false:true;
338 
339  curr.rss=f.rss;
340  curr.vsize=f.vsize;
341 
342  return rc;
343 }
344 
unsigned long minflt
unsigned long kstkesp
tuple c
Definition: gaudirun.py:391
static ProcStats * inst
Definition: ProcStats.h:94
string to_string(const T &value)
Definition: mergesort.cpp:40
unsigned long signal
unsigned long wchan
unsigned long sigcatch
static ProcStats * instance()
Definition: ProcStats.cpp:237
unsigned long flags
unique_fd & open(Args &&...args)
Definition: ProcStats.h:71
double pg_size
Definition: ProcStats.h:88
procInfo curr
Definition: ProcStats.h:89
std::string fname
Definition: ProcStats.h:90
double rss
Definition: ProcStats.h:38
unique_fd fd
Definition: ProcStats.h:87
unsigned long vsize
unsigned long startstack
tuple rc
Definition: IOTest.py:92
unsigned long cminflt
unsigned long majflt
unsigned long long starttime
unsigned long cmajflt
unsigned long kstkeip
unsigned long startcode
bool valid
Definition: ProcStats.h:92
unsigned long utime
char buf[500]
Definition: ProcStats.h:91
unsigned long blocked
double vsize
Definition: ProcStats.h:37
bool fetch(procInfo &fill_me)
Definition: ProcStats.cpp:263
unsigned long endcode
unsigned long stime
unsigned long sigignore
unsigned long rlim