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