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