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