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