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