The Gaudi Framework  v33r0 (d5ea422b)
ProcessDescriptor.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 //====================================================================
12 // ProcStat.cpp
13 //--------------------------------------------------------------------
14 //
15 // Package : System (The LHCb System service)
16 //
17 // Description: Invoke interactively the ProcStat from a
18 // running application
19 //
20 // Author : M.Frank
21 // Created : 13/11/00
22 // Changes :
23 //
24 //====================================================================
25 #define GAUDIKERNEL_PROCSTAT_CPP
26 
27 #ifndef __APPLE__
28 static const long TICK_TO_100NSEC = 100000;
29 #endif // not __APPLE__
30 
31 namespace System {
46  ProcessIoPortHandlers, // Note: this is kernel mode only
58  };
59 }
60 #ifdef _WIN32
61 # define strcasecmp _stricmp
62 # define strncasecmp _strnicmp
63 # define NOMSG
64 # define NOGDI
65 # include "process.h"
66 # include "windows.h"
67 # define getpid _getpid
68 namespace NtApi {
69  //__declspec(dllimport) long __stdcall NtQueryInformationProcess(
70  // typedef __declspec(dllimport) long __stdcall (*__NtQueryInformationProcess)(
71  // extern "C" long __cdecl NtQueryInformationProcess(
72 
73  typedef long( WINAPI* __NtQueryInformationProcess )(
74 
75  void* ProcessHandle, long ProcessInformationClass, void* ProcessInformation,
76  unsigned long ProcessInformationLength, unsigned long* ReturnLength );
77  __NtQueryInformationProcess NtQueryInformationProcess;
78 }; // namespace NtApi
79 #else // UNIX...: first the EGCS stuff, then the OS dependent includes
80 # define WINVER 0
81 # include "libgen.h"
82 # include "sys/times.h"
83 # include "unistd.h"
84 # include <cstdio>
85 # include <errno.h>
86 # include <fcntl.h>
87 # include <iostream>
88 # include <sstream>
89 # include <string>
90 # include <sys/signal.h>
91 # include <sys/syscall.h>
92 # include <sys/types.h>
93 # include <unistd.h>
94 # ifndef __APPLE__
95 # include <sys/procfs.h>
96 # endif
97 # include <cstdio>
98 # include <sys/resource.h>
99 # include <sys/time.h>
100 
101 /* Format of the Linux proc/stat (man 5 proc, kernel 2.6.35):
102  pid %d The process ID.
103 
104  comm %s The filename of the executable, in parentheses. This is visible
105  whether or not the executable is swapped out.
106 
107  state %c One character from the string "RSDZTW" where R is running, S is
108  sleeping in an interruptible wait, D is waiting in uninterruptible
109  disk sleep, Z is zombie, T is traced or stopped (on a signal), and
110  W is paging.
111 
112  ppid %d The PID of the parent.
113 
114  pgrp %d The process group ID of the process.
115 
116  session %d The session ID of the process.
117 
118  tty_nr %d The controlling terminal of the process. (The minor device number
119  is contained in the combination of bits 31 to 20 and 7 to 0; the
120  major device number is in bits 15 t0 8.)
121 
122  tpgid %d The ID of the foreground process group of the controlling terminal
123  of the process.
124 
125  flags %u (%lu before Linux 2.6.22)
126  The kernel flags word of the process. For bit meanings, see the
127  PF_* defines in <linux/sched.h>. Details depend on the kernel
128  version.
129 
130  minflt %lu The number of minor faults the process has made which have not
131  required loading a memory page from disk.
132 
133  cminflt %lu The number of minor faults that the process's waited-for children
134  have made.
135 
136  majflt %lu The number of major faults the process has made which have
137  required loading a memory page from disk.
138 
139  cmajflt %lu The number of major faults that the process's waited-for children
140  have made.
141 
142  utime %lu Amount of time that this process has been scheduled in user mode,
143  measured in clock ticks (divide by sysconf(_SC_CLK_TCK). This
144  includes guest time, guest_time (time spent running a virtual CPU,
145  see below), so that applications that are not aware of the guest
146  time field do not lose that time from their calculations.
147 
148  stime %lu Amount of time that this process has been scheduled in kernel
149  mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK).
150 
151  cutime %ld Amount of time that this process's waited-for children have been
152  scheduled in user mode, measured in clock ticks (divide by
153  sysconf(_SC_CLK_TCK). (See also times(2).) This includes guest
154  time, cguest_time (time spent running a virtual CPU, see below).
155 
156  cstime %ld Amount of time that this process's waited-for children have been
157  scheduled in kernel mode, measured in clock ticks (divide by
158  sysconf(_SC_CLK_TCK).
159 
160  priority %ld
161  (Explanation for Linux 2.6) For processes running a real-time
162  scheduling policy (policy below; see sched_setscheduler(2)), this
163  is the negated scheduling priority, minus one; that is, a number
164  in the range -2 to -100, corresponding to real-time priorities 1
165  to 99. For processes running under a non-real-time scheduling
166  policy, this is the raw nice value (setpriority(2)) as represented
167  in the kernel. The kernel stores nice values as numbers in the
168  range 0 (high) to 39 (low), corresponding to the user-visible nice
169  range of -20 to 19.
170 
171  Before Linux 2.6, this was a scaled value based on the scheduler
172  weighting given to this process.
173 
174  nice %ld The nice value (see setpriority(2)), a value in the range 19 (low
175  priority) to -20 (high priority).
176 
177  num_threads %ld
178  Number of threads in this process (since Linux 2.6). Before ker‐
179  nel 2.6, this field was hard coded to 0 as a placeholder for an
180  earlier removed field.
181 
182  itrealvalue %ld
183  The time in jiffies before the next SIGALRM is sent to the process
184  due to an interval timer. Since kernel 2.6.17, this field is no
185  longer maintained, and is hard coded as 0.
186 
187  starttime %llu (was %lu before Linux 2.6)
188  The time in jiffies the process started after system boot.
189 
190  vsize %lu Virtual memory size in bytes.
191 
192  rss %ld Resident Set Size: number of pages the process has in real memory.
193  This is just the pages which count towards text, data, or stack
194  space. This does not include pages which have not been demand-
195  loaded in, or which are swapped out.
196 
197  rsslim %lu Current soft limit in bytes on the rss of the process; see the
198  description of RLIMIT_RSS in getpriority(2).
199 
200  startcode %lu
201  The address above which program text can run.
202 
203  endcode %lu The address below which program text can run.
204 
205  startstack %lu
206  The address of the start (i.e., bottom) of the stack.
207 
208  kstkesp %lu The current value of ESP (stack pointer), as found in the kernel
209  stack page for the process.
210 
211  kstkeip %lu The current EIP (instruction pointer).
212 
213  signal %lu The bitmap of pending signals, displayed as a decimal number.
214  Obsolete, because it does not provide information on real-time
215  signals; use /proc/[pid]/status instead.
216 
217  blocked %lu The bitmap of blocked signals, displayed as a decimal number.
218  Obsolete, because it does not provide information on real-time
219  signals; use /proc/[pid]/status instead.
220 
221  sigignore %lu
222  The bitmap of ignored signals, displayed as a decimal number.
223  Obsolete, because it does not provide information on real-time
224  signals; use /proc/[pid]/status instead.
225 
226  sigcatch %lu
227  The bitmap of caught signals, displayed as a decimal number.
228  Obsolete, because it does not provide information on real-time
229  signals; use /proc/[pid]/status instead.
230 
231  wchan %lu This is the "channel" in which the process is waiting. It is the
232  address of a system call, and can be looked up in a namelist if
233  you need a textual name. (If you have an up-to-date
234  /etc/psdatabase, then try ps -l to see the WCHAN field in action.)
235 
236  nswap %lu Number of pages swapped (not maintained).
237 
238  cnswap %lu Cumulative nswap for child processes (not maintained).
239 
240  exit_signal %d (since Linux 2.1.22)
241  Signal to be sent to parent when we die.
242 
243  processor %d (since Linux 2.2.8)
244  CPU number last executed on.
245 
246  rt_priority %u (since Linux 2.5.19; was %lu before Linux 2.6.22)
247  Real-time scheduling priority, a number in the range 1 to 99 for
248  processes scheduled under a real-time policy, or 0, for non-real-
249  time processes (see sched_setscheduler(2)).
250 
251  policy %u (since Linux 2.5.19; was %lu before Linux 2.6.22)
252  Scheduling policy (see sched_setscheduler(2)). Decode using the
253  SCHED_* constants in linux/sched.h.
254 
255  delayacct_blkio_ticks %llu (since Linux 2.6.18)
256  Aggregated block I/O delays, measured in clock ticks (centisec‐
257  onds).
258 
259  guest_time %lu (since Linux 2.6.24)
260  Guest time of the process (time spent running a virtual CPU for a
261  guest operating system), measured in clock ticks (divide by
262  sysconf(_SC_CLK_TCK).
263 
264  cguest_time %ld (since Linux 2.6.24)
265  Guest time of the process's children, measured in clock ticks
266  (divide by sysconf(_SC_CLK_TCK).
267 */
268 struct linux_proc {
269  int pid;
270  char comm[400];
271  char state;
272  int ppid;
273  int pgrp;
274  int session;
275  int tty;
276  int tpgid;
277  unsigned long flags;
278  unsigned long minflt;
279  unsigned long cminflt;
280  unsigned long majflt;
281  unsigned long cmajflt;
282  unsigned long utime;
283  unsigned long stime;
284  long cutime;
285  long cstime;
286  long priority;
287  long nice;
290  unsigned long long starttime;
291  unsigned long vsize;
292  long rss;
293  unsigned long rlim;
294  unsigned long startcode;
295  unsigned long endcode;
296  unsigned long startstack;
297  unsigned long kstkesp;
298  unsigned long kstkeip;
299  unsigned long signal;
300  unsigned long blocked;
301  unsigned long sigignore;
302  unsigned long sigcatch;
303  unsigned long wchan;
304 };
305 
306 # ifdef __APPLE__
307 // static long pg_size = 0;
308 # else
309 static long pg_size = sysconf( _SC_PAGESIZE ); // getpagesize();
310 # endif
311 void readProcStat( long pid, linux_proc& pinfo ) {
312 
313  int cnt, fd;
314  char buf[512];
315 
316  std::ostringstream ost;
317 
318  ost << "/proc/" << pid << "/stat";
319  std::string fname = ost.str();
320  if ( ( fd = open( fname.c_str(), O_RDONLY ) ) < 0 ) {
321  std::cerr << "Failed to open " << ost.str() << std::endl;
322  return;
323  }
324 
325  lseek( fd, 0, SEEK_SET );
326  if ( ( cnt = read( fd, buf, sizeof( buf ) - 1 ) ) < 0 ) {
327  std::cout << "LINUX Read of Proc file failed:" << std::endl;
328  close( fd );
329  return;
330  }
331 
332  // Format
333  if ( cnt > 0 ) {
334  buf[cnt] = '\0';
335  sscanf( buf,
336  // 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
337  // 30 1 2 3 4 5
338  "%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 "
339  "%lu %lu %lu %lu %lu %lu %lu",
340  &pinfo.pid, pinfo.comm, &pinfo.state, &pinfo.ppid, &pinfo.pgrp, &pinfo.session, &pinfo.tty, &pinfo.tpgid,
341  &pinfo.flags, &pinfo.minflt, &pinfo.cminflt, &pinfo.majflt, &pinfo.cmajflt, &pinfo.utime, &pinfo.stime,
342  &pinfo.cutime, &pinfo.cstime, &pinfo.priority, &pinfo.nice, &pinfo.num_threads, &pinfo.itrealvalue,
343  &pinfo.starttime, &pinfo.vsize, &pinfo.rss, &pinfo.rlim, &pinfo.startcode, &pinfo.endcode,
344  &pinfo.startstack, &pinfo.kstkesp, &pinfo.kstkeip, &pinfo.signal, &pinfo.blocked, &pinfo.sigignore,
345  &pinfo.sigcatch, &pinfo.wchan );
346  }
347  close( fd );
348 }
349 #endif
350 
351  // static long s_myPid = ::getpid();
352  // In order to properly support e.g. fork() calls, we cannot keep a copy of the pid!
353 
354 #ifndef __APPLE__
355 static inline long processID( long pid ) { return ( pid > 0 ) ? pid : ( ::getpid() ); }
356 #endif // not __APPLE__
357 
358 // Framework include files
359 #include "GaudiKernel/ModuleInfo.h"
360 #include "GaudiKernel/System.h"
361 #include "ProcessDescriptor.h"
362 
364  if ( pid > 0 ) {
365  if ( pid != ::getpid() ) {
366 #ifdef _WIN32
367  m_handle = ::OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
368 #else
369  // Note: the return type of getpid is pid_t, which is int on 64bit machines too
370  m_handle = reinterpret_cast<void*>( static_cast<long>( ::getpid() ) );
371 #endif
372  m_needRelease = true;
373  return;
374  }
375  }
377  m_needRelease = false;
378 }
379 
381  if ( m_needRelease ) {
382 #ifdef _WIN32
383  ::CloseHandle( m_handle );
384 #else
385  m_handle = nullptr;
386 #endif
387  }
388 }
389 
391 #ifdef _WIN32
392  static bool first = true;
393  if ( first ) {
394  first = false;
395  void* mh = ::LoadLibrary( "NTDll.dll" );
396  if ( mh ) {
397  NtApi::NtQueryInformationProcess =
398  ( NtApi::__NtQueryInformationProcess )::GetProcAddress( (HINSTANCE)mh, "NtQueryInformationProcess" );
399  }
400  }
401 #endif
402 }
403 
405 
406 long System::ProcessDescriptor::query( long pid, InfoType fetch, IO_COUNTERS* info ) {
407  if ( info == 0 ) return 0;
408  long status = 1;
409 
410  if ( fetch == IO ) {
411 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
412  ProcessHandle h( pid );
413  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessIoCounters, info, sizeof( IO_COUNTERS ), 0 );
414  status = ( status == 0 ) ? 1 : 0;
415 #elif defined( _WIN32 ) // Windows 95,98...
416 #elif defined( __linux )
417  linux_proc prc;
418  readProcStat( processID( pid ), prc );
419  rusage usage;
420  getrusage( RUSAGE_SELF, &usage );
421  info->ReadOperationCount = usage.ru_inblock;
422  info->WriteOperationCount = usage.ru_oublock;
423  info->OtherOperationCount = 0;
424  info->ReadTransferCount = usage.ru_inblock;
425  info->WriteTransferCount = usage.ru_oublock;
426  info->OtherTransferCount = 0;
427 #else // All Other
428  if ( pid ) {}
429 #endif // End ALL OS
430  }
431  return status;
432 }
433 
435  if ( info == 0 ) return 0;
436  long status = 1;
437 
438  if ( fetch == Quota ) {
439 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
440  ProcessHandle h( pid );
441  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessPooledUsageAndLimits, info,
442  sizeof( POOLED_USAGE_AND_LIMITS ), 0 );
443  status = ( status == 0 ) ? 1 : 0;
444 #elif defined( _WIN32 ) // Windows 95,98...
445 #elif defined( __linux ) // Linux
446  // rusage usage;
447  // getrusage(RUSAGE_SELF, &usage);
448  rlimit lim;
449 
450  getrlimit( RLIMIT_DATA, &lim );
451  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
452  info->PeakPagedPoolUsage = lim.rlim_cur;
453  info->PagedPoolUsage = lim.rlim_cur;
454  info->PagedPoolLimit = lim.rlim_max;
455 
456  getrlimit( RLIMIT_STACK, &lim );
457  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
458  info->PeakNonPagedPoolUsage = lim.rlim_cur;
459  info->NonPagedPoolUsage = lim.rlim_cur;
460  info->NonPagedPoolLimit = lim.rlim_max;
461 
462  linux_proc prc;
463  readProcStat( processID( pid ), prc );
464  info->PeakPagefileUsage = prc.rss * pg_size;
465  info->PagefileUsage = prc.rss * pg_size;
466  info->PagefileLimit = 0xFFFFFFFF;
467 #elif defined( __APPLE__ )
468  if ( pid ) {}
469 #else // All Other
470  if ( pid ) {}
471 #endif // End ALL OS
472  }
473 
474  return status;
475 }
476 
477 long System::ProcessDescriptor::query( long pid, InfoType fetch, long* info ) {
478 
479  if ( info == 0 ) return 0;
480  long status = 1;
481 
482  switch ( fetch ) {
483  case PriorityBoost:
484 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
485  ProcessHandle h( pid );
486  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessPriorityBoost, info, sizeof( long ), 0 );
487 #elif defined( _WIN32 ) // Windows 95,98...
488  if ( pid ) {}
489 #else
490  // Not applicable
491  if ( pid > 0 ) status = 0; // to avoid compiler warning
492  status = 0;
493  *info = 0;
494 #endif // End ALL OS
495  status = ( status == 0 ) ? 1 : 0;
496  break;
497  default:
498  status = -1;
499  info = &status;
500  break;
501  }
502  return status;
503 }
504 
505 long System::ProcessDescriptor::query( long pid, InfoType fetch, VM_COUNTERS* info ) {
506  if ( info == 0 ) return 0;
507  long status = 1;
508 
509  if ( fetch == Memory ) {
510 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
511  ProcessHandle h( pid );
512  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessVmCounters, info, sizeof( VM_COUNTERS ), 0 );
513  status = ( status == 0 ) ? 1 : 0;
514 #elif defined( _WIN32 ) // Windows 95,98...
515 #elif defined( __linux ) // Linux
516  const ssize_t bufsize = 1024;
517  char buf[bufsize];
518  pid = processID( pid );
519  sprintf( buf, "/proc/%ld/statm", pid );
520  long size, resident, share, trs, lrs, drs, dt;
521  int fd = open( buf, O_RDONLY );
522  ssize_t nread = read( fd, buf, bufsize );
523  close( fd );
524  if ( nread < bufsize && nread >= 0 ) buf[nread] = '\0';
525  fd = sscanf( buf, "%ld %ld %ld %ld %ld %ld %ld", &size, &resident, &share, &trs, &drs, &lrs, &dt );
526  linux_proc prc;
527  readProcStat( pid, prc );
528  info->PeakVirtualSize = prc.vsize;
529  info->VirtualSize = prc.vsize;
530  info->PeakWorkingSetSize = resident * pg_size;
531  info->WorkingSetSize = resident * pg_size;
532  info->QuotaPeakPagedPoolUsage = share * pg_size;
533  info->QuotaPagedPoolUsage = share * pg_size;
534  info->QuotaNonPagedPoolUsage = ( trs + drs ) * pg_size; // drs = data/stack size
535  info->QuotaPeakNonPagedPoolUsage = ( trs + drs ) * pg_size; // trs = VmExe size
536  info->PageFaultCount = prc.majflt + prc.minflt;
537  info->PagefileUsage = prc.vsize - resident * pg_size;
538  info->PeakPagefileUsage = prc.vsize - resident * pg_size;
539 #elif defined( __APPLE__ )
540  if ( pid ) {}
541 #else // All Other
542  if ( pid ) {}
543 #endif // End ALL OS
544  }
545  return status;
546 }
547 
549  if ( info == 0 ) return 0;
550  long status = 1;
551 
552  if ( fetch == Quota ) {
553 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
554  ProcessHandle h( pid );
555  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessQuotaLimits, info, sizeof( QUOTA_LIMITS ), 0 );
556  status = ( status == 0 ) ? 1 : 0;
557 #elif defined( _WIN32 ) // Windows 95,98...
558 #elif defined( __linux ) // Linux
559  // On linux all this stuff typically is not set
560  // (ie. rlim_max=RLIM_INFINITY...)
561 
562  if ( pid > 0 && pid != ::getpid() ) return 0; // only possible for myself
563 
564  rlimit lim;
565  getrlimit( RLIMIT_DATA, &lim );
566  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
567  info->PagedPoolLimit = lim.rlim_max;
568 
569  getrlimit( RLIMIT_STACK, &lim );
570  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
571  info->NonPagedPoolLimit = lim.rlim_max;
572  info->MinimumWorkingSetSize = 0;
573 
574  getrlimit( RLIMIT_RSS, &lim );
575  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
576  info->MaximumWorkingSetSize = lim.rlim_max;
577 
578  getrlimit( RLIMIT_AS, &lim );
579  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
580  info->PagefileLimit = lim.rlim_max;
581 
582  getrlimit( RLIMIT_CPU, &lim );
583  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
584  info->TimeLimit = lim.rlim_max;
585 #elif defined( __APPLE__ )
586  if ( pid ) {}
587 #else // All Other
588  if ( pid ) {}
589 #endif // End ALL OS
590  }
591  return status;
592 }
593 
595  if ( info == 0 ) return 0;
596  long status = 1;
597 
598  if ( fetch == ProcessBasics ) {
599 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
600  ProcessHandle h( pid );
601  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessBasicInformation, info,
602  sizeof( PROCESS_BASIC_INFORMATION ), 0 );
603  status = ( status == 0 ) ? 1 : 0;
604 #elif defined( _WIN32 ) // Windows 95,98...
605 #elif defined( __linux ) // Linux
606  linux_proc prc;
607  pid = processID( pid );
608  readProcStat( pid, prc );
609  info->ExitStatus = 0;
610  info->PebBaseAddress = (PPEB)prc.startcode;
611  info->BasePriority = 2 * 15 - prc.priority;
612  // std::cout << "Base Priority=" << info->BasePriority << "|"
613  // << prc.priority << std::endl;
614  info->AffinityMask = prc.flags;
615  // std::cout << "Flags =" << info->AffinityMask << "|"
616  // << prc.flags << std::endl;
617  info->UniqueProcessId = pid;
618  info->InheritedFromUniqueProcessId = prc.ppid;
619 #else // All Other
620  if ( pid ) {}
621 #endif // End ALL OS
622  }
623  return status;
624 }
625 
627  if ( info == 0 ) return 0;
628  long status = 1;
629 
630  if ( fetch == Times ) {
631 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
632  ProcessHandle h( pid );
633  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessTimes, info, sizeof( KERNEL_USER_TIMES ), 0 );
634  status = ( status == 0 ) ? 1 : 0;
635 #elif defined( _WIN32 ) // Windows 95,98...
636 #elif defined( __linux ) // Linux
637  static long long prc_start = 0;
638  bool myself = pid <= 0 || pid == ::getpid(); // avoid unnecessary calls to getpid if pid<0
639  if ( myself && prc_start == 0 ) { // called only once to set prc_start
640  linux_proc prc;
641  readProcStat( processID( pid ), prc );
642  // prc.startup is in ticks since system start, need to offset for absolute time
643  tms tmsb;
644  static long long offset =
645  100 * static_cast<long long>( time( nullptr ) ) - static_cast<long long>( times( &tmsb ) );
646  prc_start = ( prc.starttime + offset ) * TICK_TO_100NSEC;
647  }
648 
649  if ( myself ) { // myself
650  tms tmsb;
651  times( &tmsb );
652  info->UserTime = tmsb.tms_utime * TICK_TO_100NSEC;
653  info->KernelTime = tmsb.tms_stime * TICK_TO_100NSEC;
654  info->CreateTime = prc_start;
655  } else { // other process
656  linux_proc prc;
657  readProcStat( processID( pid ), prc );
658  tms tmsb;
659  static long long offset =
660  100 * static_cast<long long>( time( nullptr ) ) - static_cast<long long>( times( &tmsb ) );
661 
662  tms t;
663  times( &t );
664  info->UserTime = t.tms_utime * TICK_TO_100NSEC;
665  info->KernelTime = t.tms_stime * TICK_TO_100NSEC;
666  info->CreateTime = ( prc.starttime + offset ) * TICK_TO_100NSEC;
667  }
668  info->ExitTime = 0;
669 
670  status = 1;
671 
672 #elif defined( __APPLE__ )
673  if ( pid ) {}
674 // FIXME (MCl): Make an alternative function get timing on OSX
675 // times() seems to cause a segmentation fault
676 #else // no /proc file system: assume sys_start for the first call
677  tms tmsb;
678  static clock_t sys_start = times( 0 );
679  static long long offset = 100 * long long( time( 0 ) ) - sys_start;
680  clock_t now = times( &tmsb );
681  info->CreateTime = offset + now;
682  info->UserTime = tmsb.tms_utime;
683  info->KernelTime = tmsb.tms_stime;
684  info->CreateTime *= TICK_TO_100NSEC;
685  info->UserTime *= TICK_TO_100NSEC;
686  info->KernelTime *= TICK_TO_100NSEC;
687  info->ExitTime = 0;
688  status = 1;
689 #endif
690  }
691 
692  return status;
693 }
unsigned long minflt
unsigned long kstkesp
constexpr auto size(const T &, Args &&...) noexcept
Process/Thread System and User Time NtQueryInformationProcess using ProcessTimes NtQueryInformationTh...
unsigned long signal
unsigned long wchan
unsigned long sigcatch
unsigned long flags
Note: OS specific details for environment resolution.
Definition: Debugger.h:29
T endl(T... args)
Process I/O Counters NtQueryInformationProcess using ProcessIoCounters.
void usage(std::string argv0)
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:33
GAUDI_API ProcessHandle processHandle()
Handle to running process.
Definition: ModuleInfo.cpp:135
void readProcStat(long pid, linux_proc &pinfo)
STL class.
unsigned long vsize
T str(T... args)
unsigned long startstack
unsigned long cminflt
unsigned long majflt
unsigned long long starttime
unsigned long cmajflt
unsigned long kstkeip
Process Quotas NtQueryInformationProcess using ProcessQuotaLimits NtQueryInformationProcess using Pro...
long query(long pid, InfoType info, PROCESS_BASIC_INFORMATION *buffer)
unsigned long startcode
struct _PEB * PPEB
Basic Process Information NtQueryInformationProcess using ProcessBasicInfo.
T c_str(T... args)
unsigned long utime
Process Virtual Memory Counters NtQueryInformationProcess using ProcessVmCounters.
Process Pooled Quota Usage and Limits NtQueryInformationProcess using ProcessPooledUsageAndLimits.
unsigned long blocked
unsigned long endcode
unsigned long stime
unsigned long sigignore
InfoType
Enumeration for fetching information.
Definition: SystemBase.h:28
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:42
unsigned long rlim