| # Gaudi Framework, version v23r0 |

Home |  | Generated: Mon Jan 30 2012

# ProcessDescriptor.cpp

Go to the documentation of this file.

    00001 //====================================================================
    00002 //  ProcStat.cpp
    00003 //--------------------------------------------------------------------
    00004 //
    00005 //  Package    : System (The LHCb System service)
    00006 //
    00007 //  Description: Invoke interactively the ProcStat from a
    00008 //               running application
    00009 //
    00010 //  Author     : M.Frank
    00011 //  Created    : 13/11/00
    00012 //  Changes    :
    00013 //
    00014 //====================================================================
    00015 #define GAUDIKERNEL_PROCSTAT_CPP
    00016
    00017 static const long TICK_TO_100NSEC = 100000;
    00018
    00019 namespace System    {
    00020   enum ProcessInfoCommand {
    00021       ProcessBasicInformation,
    00022       ProcessQuotaLimits,
    00023       ProcessIoCounters,
    00024       ProcessVmCounters,
    00025       ProcessTimes,
    00026       ProcessBasePriority,
    00027       ProcessRaisePriority,
    00028       ProcessDebugPort,
    00029       ProcessExceptionPort,
    00030       ProcessAccessToken,
    00031       ProcessLdtInformation,
    00032       ProcessLdtSize,
    00033       ProcessDefaultHardErrorMode,
    00034       ProcessIoPortHandlers,          // Note: this is kernel mode only
    00035       ProcessPooledUsageAndLimits,
    00036       ProcessWorkingSetWatch,
    00037       ProcessUserModeIOPL,
    00038       ProcessEnableAlignmentFaultFixup,
    00039       ProcessPriorityClass,
    00040       ProcessWx86Information,
    00041       ProcessHandleCount,
    00042       ProcessAffinityMask,
    00043       ProcessPriorityBoost,
    00044       MaxProcessInfoClass,  //
    00045       ProcessEllapsedTime
    00046   };
    00047 }
    00048 #ifdef _WIN32
    00049   #  define strcasecmp _stricmp
    00050   #  define strncasecmp _strnicmp
    00051   #define NOMSG
    00052   #define NOGDI
    00053   #include "process.h"
    00054   #include "windows.h"
    00055   #define getpid _getpid
    00056 namespace NtApi {
    00057 //__declspec(dllimport) long __stdcall NtQueryInformationProcess(
    00058 //  typedef __declspec(dllimport) long __stdcall (*__NtQueryInformationProcess)(
    00059 //  extern "C" long __cdecl NtQueryInformationProcess(
    00060
    00061     typedef long (WINAPI *__NtQueryInformationProcess)(
    00062
    00063     void* ProcessHandle,
    00064     long ProcessInformationClass,
    00065     void* ProcessInformation,
    00066     unsigned long ProcessInformationLength,
    00067     unsigned long* ReturnLength
    00068     );
    00069   __NtQueryInformationProcess NtQueryInformationProcess;
    00070 };
    00071 #else  // UNIX...: first the EGCS stuff, then the OS dependent includes
    00072 #define WINVER 0
    00073 #include <errno.h>
    00074 #include <string>
    00075 #include "unistd.h"
    00076 #include "libgen.h"
    00077 #include <cstdio>
    00078 #include <unistd.h>
    00079 #include <sstream>
    00080 #include <iostream>
    00081 #include <fcntl.h>
    00082 #include "sys/times.h"
    00083 #include <sys/types.h>
    00084 #include <sys/signal.h>
    00085 #include <sys/syscall.h>
    00086 #ifndef __APPLE__
    00087 #include <sys/procfs.h>
    00088 #endif
    00089 #include <sys/time.h>
    00090 #include <sys/resource.h>
    00091 #include <cstdio>
    00092
    00093 /* Format of the Linux proc/stat (man 5 proc, kernel 2.6.35):
    00094  pid %d      The process ID.
    00095
    00096  comm %s     The  filename  of the executable, in parentheses.  This is visible
    00097              whether or not the executable is swapped out.
    00098
    00099  state %c    One character from the string "RSDZTW" where R is  running,  S  is
    00100              sleeping in an interruptible wait, D is waiting in uninterruptible
    00101              disk sleep, Z is zombie, T is traced or stopped (on a signal), and
    00102              W is paging.
    00103
    00104  ppid %d     The PID of the parent.
    00105
    00106  pgrp %d     The process group ID of the process.
    00107
    00108  session %d  The session ID of the process.
    00109
    00110  tty_nr %d   The controlling terminal of the process.  (The minor device number
    00111              is contained in the combination of bits 31 to 20 and 7 to  0;  the
    00112              major device number is in bits 15 t0 8.)
    00113
    00114  tpgid %d    The ID of the foreground process group of the controlling terminal
    00115              of the process.
    00116
    00117  flags %u (%lu before Linux 2.6.22)
    00118              The kernel flags word of the process.  For bit meanings,  see  the
    00119              PF_*  defines  in  <linux/sched.h>.   Details depend on the kernel
    00120              version.
    00121
    00122  minflt %lu  The number of minor faults the process has  made  which  have  not
    00123              required loading a memory page from disk.
    00124
    00125  cminflt %lu The  number of minor faults that the process's waited-for children
    00126              have made.
    00127
    00128  majflt %lu  The number of  major  faults  the  process  has  made  which  have
    00129              required loading a memory page from disk.
    00130
    00131  cmajflt %lu The  number of major faults that the process's waited-for children
    00132              have made.
    00133
    00134  utime %lu   Amount of time that this process has been scheduled in user  mode,
    00135              measured  in  clock  ticks  (divide by sysconf(_SC_CLK_TCK).  This
    00136              includes guest time, guest_time (time spent running a virtual CPU,
    00137              see  below),  so that applications that are not aware of the guest
    00138              time field do not lose that time from their calculations.
    00139
    00140  stime %lu   Amount of time that this process  has  been  scheduled  in  kernel
    00141              mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK).
    00142
    00143  cutime %ld  Amount  of  time that this process's waited-for children have been
    00144              scheduled in  user  mode,  measured  in  clock  ticks  (divide  by
    00145              sysconf(_SC_CLK_TCK).   (See  also times(2).)  This includes guest
    00146              time, cguest_time (time spent running a virtual CPU, see below).
    00147
    00148  cstime %ld  Amount of time that this process's waited-for children  have  been
    00149              scheduled  in  kernel  mode,  measured  in  clock ticks (divide by
    00150              sysconf(_SC_CLK_TCK).
    00151
    00152  priority %ld
    00153              (Explanation for Linux 2.6)  For  processes  running  a  real-time
    00154              scheduling  policy (policy below; see sched_setscheduler(2)), this
    00155              is the negated scheduling priority, minus one; that is,  a  number
    00156              in  the  range -2 to -100, corresponding to real-time priorities 1
    00157              to 99.  For processes running  under  a  non-real-time  scheduling
    00158              policy, this is the raw nice value (setpriority(2)) as represented
    00159              in the kernel.  The kernel stores nice values as  numbers  in  the
    00160              range 0 (high) to 39 (low), corresponding to the user-visible nice
    00161              range of -20 to 19.
    00162
    00163              Before Linux 2.6, this was a scaled value based on  the  scheduler
    00164              weighting given to this process.
    00165
    00166  nice %ld    The  nice value (see setpriority(2)), a value in the range 19 (low
    00167              priority) to -20 (high priority).
    00168
    00169  num_threads %ld
    00170              Number of threads in this process (since Linux 2.6).  Before  ker‐
    00171              nel  2.6,  this  field was hard coded to 0 as a placeholder for an
    00172              earlier removed field.
    00173
    00174  itrealvalue %ld
    00175              The time in jiffies before the next SIGALRM is sent to the process
    00176              due  to  an interval timer.  Since kernel 2.6.17, this field is no
    00177              longer maintained, and is hard coded as 0.
    00178
    00179  starttime %llu (was %lu before Linux 2.6)
    00180              The time in jiffies the process started after system boot.
    00181
    00182  vsize %lu   Virtual memory size in bytes.
    00183
    00184  rss %ld     Resident Set Size: number of pages the process has in real memory.
    00185              This  is  just  the pages which count towards text, data, or stack
    00186              space.  This does not include pages which have  not  been  demand-
    00187              loaded in, or which are swapped out.
    00188
    00189  rsslim %lu  Current  soft  limit  in  bytes on the rss of the process; see the
    00190              description of RLIMIT_RSS in getpriority(2).
    00191
    00192  startcode %lu
    00193              The address above which program text can run.
    00194
    00195  endcode %lu The address below which program text can run.
    00196
    00197  startstack %lu
    00198              The address of the start (i.e., bottom) of the stack.
    00199
    00200  kstkesp %lu The current value of ESP (stack pointer), as found in  the  kernel
    00201              stack page for the process.
    00202
    00203  kstkeip %lu The current EIP (instruction pointer).
    00204
    00205  signal %lu  The  bitmap  of  pending  signals,  displayed as a decimal number.
    00206              Obsolete, because it does not  provide  information  on  real-time
    00207              signals; use /proc/[pid]/status instead.
    00208
    00209  blocked %lu The  bitmap  of  blocked  signals,  displayed as a decimal number.
    00210              Obsolete, because it does not  provide  information  on  real-time
    00211              signals; use /proc/[pid]/status instead.
    00212
    00213  sigignore %lu
    00214              The  bitmap  of  ignored  signals,  displayed as a decimal number.
    00215              Obsolete, because it does not  provide  information  on  real-time
    00216              signals; use /proc/[pid]/status instead.
    00217
    00218  sigcatch %lu
    00219              The  bitmap  of  caught  signals,  displayed  as a decimal number.
    00220              Obsolete, because it does not  provide  information  on  real-time
    00221              signals; use /proc/[pid]/status instead.
    00222
    00223  wchan %lu   This  is the "channel" in which the process is waiting.  It is the
    00224              address of a system call, and can be looked up in  a  namelist  if
    00225              you   need   a   textual   name.    (If  you  have  an  up-to-date
    00226              /etc/psdatabase, then try ps -l to see the WCHAN field in action.)
    00227
    00228  nswap %lu   Number of pages swapped (not maintained).
    00229
    00230  cnswap %lu  Cumulative nswap for child processes (not maintained).
    00231
    00232  exit_signal %d (since Linux 2.1.22)
    00233              Signal to be sent to parent when we die.
    00234
    00235  processor %d (since Linux 2.2.8)
    00236              CPU number last executed on.
    00237
    00238  rt_priority %u (since Linux 2.5.19; was %lu before Linux 2.6.22)
    00239              Real-time scheduling priority, a number in the range 1 to  99  for
    00240              processes  scheduled under a real-time policy, or 0, for non-real-
    00241              time processes (see sched_setscheduler(2)).
    00242
    00243  policy %u (since Linux 2.5.19; was %lu before Linux 2.6.22)
    00244              Scheduling policy (see sched_setscheduler(2)).  Decode  using  the
    00245              SCHED_* constants in linux/sched.h.
    00246
    00247  delayacct_blkio_ticks %llu (since Linux 2.6.18)
    00248              Aggregated  block  I/O  delays, measured in clock ticks (centisec‐
    00249              onds).
    00250
    00251  guest_time %lu (since Linux 2.6.24)
    00252              Guest time of the process (time spent running a virtual CPU for  a
    00253              guest  operating  system),  measured  in  clock  ticks  (divide by
    00254              sysconf(_SC_CLK_TCK).
    00255
    00256  cguest_time %ld (since Linux 2.6.24)
    00257              Guest time of the process's  children,  measured  in  clock  ticks
    00258              (divide by sysconf(_SC_CLK_TCK).
    00259 */
    00260 struct linux_proc {
    00261   int pid;
    00262   char comm[400];
    00263   char state;
    00264   int ppid;
    00265   int pgrp;
    00266   int session;
    00267   int tty;
    00268   int tpgid;
    00269   unsigned long flags;
    00270   unsigned long minflt;
    00271   unsigned long cminflt;
    00272   unsigned long majflt;
    00273   unsigned long cmajflt;
    00274   unsigned long utime;
    00275   unsigned long stime;
    00276   long cutime;
    00277   long cstime;
    00278   long priority;
    00279   long nice;
    00280   long num_threads;
    00281   long itrealvalue;
    00282   unsigned long long starttime;
    00283   unsigned long vsize;
    00284   long rss;
    00285   unsigned long rlim;
    00286   unsigned long startcode;
    00287   unsigned long endcode;
    00288   unsigned long startstack;
    00289   unsigned long kstkesp;
    00290   unsigned long kstkeip;
    00291   unsigned long signal;
    00292   unsigned long blocked;
    00293   unsigned long sigignore;
    00294   unsigned long sigcatch;
    00295   unsigned long wchan;
    00296 };
    00297
    00298 #ifdef __APPLE__
    00299 // static long  pg_size = 0;
    00300 #else
    00301 static long  pg_size = sysconf(_SC_PAGESIZE); // getpagesize();
    00302 #endif
    00303 void readProcStat(long pid, linux_proc& pinfo) {
    00304
    00305   int cnt, fd;
    00306   char buf[512];
    00307
    00308   std::ostringstream ost;
    00309
    00310   ost << "/proc/" << pid << "/stat";
    00311   std::string fname = ost.str();
    00312   if((fd=open(fname.c_str(),O_RDONLY))<0)  {
    00313     std::cerr << "Failed to open " << ost.str() << std::endl;
    00314     return;
    00315   }
    00316
    00317   lseek(fd,0,SEEK_SET);
    00318   if((cnt=read(fd,buf,sizeof(buf)))<0) {
    00319     std::cout << "LINUX Read of Proc file failed:" << std::endl;
    00320     close(fd);
    00321     return;
    00322   }
    00323
    00324   // Format
    00325   if(cnt>0) {
    00326     buf[cnt]='\0';
    00327     sscanf(buf,
    00328            //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
    00329            "%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",
    00330            &pinfo.pid,
    00331            pinfo.comm,
    00332            &pinfo.state,
    00333            &pinfo.ppid,
    00334            &pinfo.pgrp,
    00335            &pinfo.session,
    00336            &pinfo.tty,
    00337            &pinfo.tpgid,
    00338            &pinfo.flags,
    00339            &pinfo.minflt,
    00340            &pinfo.cminflt,
    00341            &pinfo.majflt,
    00342            &pinfo.cmajflt,
    00343            &pinfo.utime,
    00344            &pinfo.stime,
    00345            &pinfo.cutime,
    00346            &pinfo.cstime,
    00347            &pinfo.priority,
    00348            &pinfo.nice,
    00349            &pinfo.num_threads,
    00350            &pinfo.itrealvalue,
    00351            &pinfo.starttime,
    00352            &pinfo.vsize,
    00353            &pinfo.rss,
    00354            &pinfo.rlim,
    00355            &pinfo.startcode,
    00356            &pinfo.endcode,
    00357            &pinfo.startstack,
    00358            &pinfo.kstkesp,
    00359            &pinfo.kstkeip,
    00360            &pinfo.signal,
    00361            &pinfo.blocked,
    00362            &pinfo.sigignore,
    00363            &pinfo.sigcatch,
    00364            &pinfo.wchan
    00365            );
    00366   }
    00367   close(fd);
    00368 }
    00369 #endif
    00370
    00371 //static long s_myPid  = ::getpid();
    00372 // In order to properly support e.g. fork() calls, we cannot keep a copy of the pid!
    00373 #define s_myPid (::getpid())
    00374 static inline long processID(long pid) {
    00375   long thePid = (pid>0) ? pid : s_myPid;
    00376   return thePid;
    00377 }
    00378
    00379 // Framework include files
    00380 #include "ProcessDescriptor.h"
    00381 #include "GaudiKernel/ModuleInfo.h"
    00382 #include "GaudiKernel/System.h"
    00383
    00384 System::ProcessDescriptor* System::getProcess()   {
    00385   static ProcessDescriptor p;
    00386 #ifdef _WIN32
    00387   static bool first = true;
    00388   if ( first )    {
    00389     first = false;
    00390     void* mh = ::LoadLibrary("NTDll.dll");
    00391     if ( mh )  {
    00392       NtApi::NtQueryInformationProcess = (NtApi::__NtQueryInformationProcess)
    00393         ::GetProcAddress((HINSTANCE)mh, "NtQueryInformationProcess");
    00394     }
    00395   }
    00396 #endif
    00397   return &p;
    00398 }
    00399
    00400 System::ProcessDescriptor::ProcessHandle::ProcessHandle(long pid)   {
    00401   if ( pid > 0 )    {
    00402     if ( pid != s_myPid )    {
    00403 #ifdef _WIN32
    00404       m_handle = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,
    00405                                pid);
    00406 #else
    00407       // Note: the return type of getpid is pid_t, which is int on 64bit machines too
    00408       m_handle = reinterpret_cast<void*>(static_cast<long>(s_myPid));
    00409 #endif
    00410       m_needRelease = true;
    00411       return;
    00412     }
    00413   }
    00414   m_handle = processHandle();
    00415   m_needRelease = false;
    00416 }
    00417
    00418 System::ProcessDescriptor::ProcessHandle::~ProcessHandle()   {
    00419   if ( m_needRelease )    {
    00420 #ifdef _WIN32
    00421     ::CloseHandle(m_handle);
    00422 #else
    00423       m_handle = 0;
    00424 #endif
    00425   }
    00426 }
    00427
    00428 System::ProcessDescriptor::ProcessDescriptor()
    00429 {
    00430 }
    00431
    00432 System::ProcessDescriptor::~ProcessDescriptor()   {
    00433 }
    00434
    00435 long System::ProcessDescriptor::query(long pid,
    00436                                       InfoType fetch,
    00437                                       IO_COUNTERS* info) {
    00438   long status = 1;
    00439   ProcessHandle h(pid);
    00440   IO_COUNTERS* vb = &m_IO_COUNTERS[h.item()];
    00441   if ( fetch == IO )   {
    00442 #if defined(_WIN32) && WINVER>=0x0400     // Windows NT
    00443     status = NtApi::NtQueryInformationProcess(h.handle(),
    00444                                               ProcessIoCounters,
    00445                                               vb,
    00446                                               sizeof(IO_COUNTERS),
    00447                                               0);
    00448     status = (status==0) ? 1 : 0;
    00449 #elif defined(_WIN32)                     // Windows 95,98...
    00450 #elif defined(linux)
    00451     linux_proc prc;
    00452     readProcStat(processID(pid), prc);
    00453     rusage usage;
    00454     getrusage(RUSAGE_SELF, &usage);
    00455     vb->ReadOperationCount    = usage.ru_inblock;
    00456     vb->WriteOperationCount   = usage.ru_oublock;
    00457     vb->OtherOperationCount   = 0;
    00458     vb->ReadTransferCount     = usage.ru_inblock;
    00459     vb->WriteTransferCount    = usage.ru_oublock;
    00460     vb->OtherTransferCount    = 0;
    00461 #else                                     // All Other
    00462 #endif                                    // End ALL OS
    00463   }
    00464   if ( info ) *info = *vb;
    00465   return status;
    00466 }
    00467
    00468 long System::ProcessDescriptor::query(long pid,
    00469                                       InfoType fetch,
    00470                                       POOLED_USAGE_AND_LIMITS* info)    {
    00471   long status = 1;
    00472   ProcessHandle h(pid);
    00473   POOLED_USAGE_AND_LIMITS* vb = &m_POOLED_USAGE_AND_LIMITS[h.item()];
    00474   if ( fetch == Quota )   {
    00475 #if defined(_WIN32) && WINVER>=0x0400     // Windows NT
    00476     status = NtApi::NtQueryInformationProcess(h.handle(),
    00477                                               ProcessPooledUsageAndLimits,
    00478                                               vb,
    00479                                               sizeof(POOLED_USAGE_AND_LIMITS),
    00480                                               0);
    00481     status = (status==0) ? 1 : 0;
    00482 #elif defined(_WIN32)                     // Windows 95,98...
    00483 #elif defined(linux)                      // Linux
    00484     //rusage usage;
    00485     //getrusage(RUSAGE_SELF, &usage);
    00486     rlimit lim;
    00487
    00488     getrlimit(RLIMIT_DATA, &lim);
    00489     if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
    00490     vb->PeakPagedPoolUsage = lim.rlim_cur;
    00491     vb->PagedPoolUsage     = lim.rlim_cur;
    00492     vb->PagedPoolLimit     = lim.rlim_max;
    00493
    00494     getrlimit(RLIMIT_STACK, &lim);
    00495     if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
    00496     vb->PeakNonPagedPoolUsage = lim.rlim_cur;
    00497     vb->NonPagedPoolUsage     = lim.rlim_cur;
    00498     vb->NonPagedPoolLimit     = lim.rlim_max;
    00499
    00500     linux_proc prc;
    00501     readProcStat(processID(pid), prc);
    00502     vb->PeakPagefileUsage     = prc.rss * pg_size;
    00503     vb->PagefileUsage         = prc.rss * pg_size;
    00504     vb->PagefileLimit         = 0xFFFFFFFF;
    00505 #elif defined(__APPLE__)
    00506 #else                                     // All Other
    00507 #endif                                    // End ALL OS
    00508   }
    00509   if ( info ) *info = *vb;
    00510   return status;
    00511 }
    00512
    00513 long System::ProcessDescriptor::query(long pid, InfoType fetch, long* info)    {
    00514   long status = 1, *vb = &status;
    00515   ProcessHandle h(pid);
    00516   vb = &m_PRIORITYBOOST[h.item()];
    00517   *vb = 0;
    00518   switch ( fetch )    {
    00519   case PriorityBoost:
    00520 #if defined(_WIN32) && WINVER>=0x0400     // Windows NT
    00521     status = NtApi::NtQueryInformationProcess(h.handle(),
    00522                                               ProcessPriorityBoost,
    00523                                               vb,
    00524                                               sizeof(long),
    00525                                               0);
    00526 #elif defined(_WIN32)                     // Windows 95,98...
    00527 #else
    00528     // Not applicable
    00529     status = 0;
    00530     *vb = 0;
    00531 #endif                                    // End ALL OS
    00532     status = (status==0) ? 1 : 0;
    00533     break;
    00534   default:
    00535     status = -1;
    00536     vb = &status;
    00537     break;
    00538   }
    00539   if ( info ) *info = *vb;
    00540   return status;
    00541 }
    00542
    00543 long System::ProcessDescriptor::query(long pid,
    00544                                       InfoType fetch,
    00545                                       VM_COUNTERS* info)    {
    00546   long status = 1;
    00547   ProcessHandle h(pid);
    00548   VM_COUNTERS* vb = &m_VM_COUNTERS[h.item()];
    00549   if ( fetch == Memory )   {
    00550 #if defined(_WIN32) && WINVER>=0x0400     // Windows NT
    00551     status = NtApi::NtQueryInformationProcess(h.handle(),
    00552                                               ProcessVmCounters,
    00553                                               vb,
    00554                                               sizeof(VM_COUNTERS),
    00555                                               0);
    00556     status = (status==0) ? 1 : 0;
    00557 #elif defined(_WIN32)                     // Windows 95,98...
    00558 #elif defined(linux)                      // Linux
    00559     const ssize_t bufsize = 1024;
    00560     char buf[bufsize];
    00561     sprintf(buf,"/proc/%ld/statm", processID(pid));
    00562     long size, resident, share, trs, lrs, drs, dt;
    00563     int fd = open(buf,O_RDONLY);
    00564     ssize_t nread = read(fd, buf, bufsize);
    00565     close(fd);
    00566     if ( nread < bufsize && nread >= 0 )
    00567       buf[nread]='\0';
    00568     fd = sscanf(buf, "%ld %ld %ld %ld %ld %ld %ld",
    00569                      &size, &resident, &share, &trs, &drs, &lrs, &dt);
    00570     linux_proc prc;
    00571     readProcStat( processID(pid), prc);
    00572     vb->PeakVirtualSize            = prc.vsize;
    00573     vb->VirtualSize                = prc.vsize;
    00574     vb->PeakWorkingSetSize         = resident * pg_size;
    00575     vb->WorkingSetSize             = resident * pg_size;
    00576     vb->QuotaPeakPagedPoolUsage    = share    * pg_size;
    00577     vb->QuotaPagedPoolUsage        = share    * pg_size;
    00578     vb->QuotaNonPagedPoolUsage     = (trs+drs)* pg_size;// drs = data/stack size
    00579     vb->QuotaPeakNonPagedPoolUsage = (trs+drs)* pg_size;// trs = VmExe size
    00580     vb->PageFaultCount             = prc.majflt + prc.minflt;
    00581     vb->PagefileUsage              = prc.vsize-resident*pg_size;
    00582     vb->PeakPagefileUsage          = prc.vsize-resident*pg_size;
    00583 #elif defined(__APPLE__)
    00584 #else                                     // All Other
    00585 #endif                                    // End ALL OS
    00586   }
    00587   if ( info ) *info = *vb;
    00588   return status;
    00589 }
    00590
    00591 long System::ProcessDescriptor::query(long pid,
    00592                                       InfoType fetch,
    00593                                       QUOTA_LIMITS* info)    {
    00594   long status = 1;
    00595   ProcessHandle h(pid);
    00596   QUOTA_LIMITS* vb = &m_QUOTA_LIMITS[h.item()];
    00597   if ( fetch == Quota )   {
    00598 #if defined(_WIN32) && WINVER>=0x0400     // Windows NT
    00599     status = NtApi::NtQueryInformationProcess(h.handle(),
    00600                                               ProcessQuotaLimits,
    00601                                               vb,
    00602                                               sizeof(QUOTA_LIMITS),
    00603                                               0);
    00604     status = (status==0) ? 1 : 0;
    00605 #elif defined(_WIN32)                     // Windows 95,98...
    00606 #elif defined(linux)                      // Linux
    00607     // On linux all this stuff typically is not set
    00608     // (ie. rlim_max=RLIM_INFINITY...)
    00609     rlimit lim;
    00610     getrlimit(RLIMIT_DATA, &lim);
    00611     if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
    00612     vb->PagedPoolLimit        = lim.rlim_max;
    00613
    00614     getrlimit(RLIMIT_STACK, &lim);
    00615     if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
    00616     vb->NonPagedPoolLimit     = lim.rlim_max;
    00617     vb->MinimumWorkingSetSize = 0;
    00618
    00619     getrlimit(RLIMIT_RSS, &lim);
    00620     if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
    00621     vb->MaximumWorkingSetSize = lim.rlim_max;
    00622
    00623     getrlimit(RLIMIT_AS, &lim);
    00624     if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
    00625     vb->PagefileLimit         = lim.rlim_max;
    00626
    00627     getrlimit(RLIMIT_CPU, &lim);
    00628     if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
    00629     vb->TimeLimit             = lim.rlim_max;
    00630 #elif defined(__APPLE__)
    00631 #else                                     // All Other
    00632 #endif                                    // End ALL OS
    00633   }
    00634   if ( info ) *info = *vb;
    00635   return status;
    00636 }
    00637
    00638 long System::ProcessDescriptor::query(long pid,
    00639                                       InfoType fetch,
    00640                                       PROCESS_BASIC_INFORMATION* info)    {
    00641   long status = 1;
    00642   ProcessHandle h(pid);
    00643   PROCESS_BASIC_INFORMATION* vb = &m_PROCESS_BASIC_INFORMATION[h.item()];
    00644   if ( fetch == ProcessBasics )   {
    00645 #if defined(_WIN32) && WINVER>=0x0400     // Windows NT
    00646     status = NtApi::NtQueryInformationProcess(h.handle(),
    00647                                               ProcessBasicInformation,
    00648                                               vb,
    00649                                               sizeof(PROCESS_BASIC_INFORMATION),
    00650                                               0);
    00651     status = (status==0) ? 1 : 0;
    00652 #elif defined(_WIN32)                     // Windows 95,98...
    00653 #elif defined(linux)                      // Linux
    00654     linux_proc prc;
    00655     readProcStat( processID(pid), prc);
    00656     vb->ExitStatus                   = 0;
    00657     vb->PebBaseAddress               = (PPEB)prc.startcode;
    00658     vb->BasePriority                 = 2*15-prc.priority;
    00659     // std::cout << "Base Priority=" << vb->BasePriority << "|"
    00660     // << prc.priority << std::endl;
    00661     vb->AffinityMask                 = prc.flags;
    00662     // std::cout << "Flags        =" << vb->AffinityMask << "|"
    00663     // << prc.flags << std::endl;
    00664     vb->UniqueProcessId              = processID(pid);
    00665     vb->InheritedFromUniqueProcessId = prc.ppid;
    00666 #else                                     // All Other
    00667 #endif                                    // End ALL OS
    00668   }
    00669   if ( info ) *info = *vb;
    00670   return status;
    00671 }
    00672
    00673 long System::ProcessDescriptor::query(long pid,
    00674                                       InfoType fetch,
    00675                                       KERNEL_USER_TIMES* info)   {
    00676   long status = 1;
    00677   ProcessHandle h(pid);
    00678   KERNEL_USER_TIMES* tb = &m_KERNEL_USER_TIMES[h.item()];;
    00679   if ( fetch == Times )   {
    00680 #if defined(_WIN32) && WINVER>=0x0400     // Windows NT
    00681     status = NtApi::NtQueryInformationProcess(h.handle(),
    00682                                               ProcessTimes,
    00683                                               tb,
    00684                                               sizeof(KERNEL_USER_TIMES),
    00685                                               0);
    00686     status = (status==0) ? 1 : 0;
    00687 #elif defined(_WIN32)                     // Windows 95,98...
    00688 #elif defined(linux)                      // Linux
    00689     // prc.startup is in ticks since system start :
    00690     // need to offset for absolute time
    00691     tms tmsb;
    00692     static longlong prc_start = 0;
    00693     //    static longlong offset = 100*longlong(time(0)) - longlong(times(0));
    00694     static longlong offset = 100*longlong(time(0)) - longlong(times(&tmsb));
    00695     if ( processID(pid) == s_myPid && prc_start == 0 ) {
    00696       linux_proc prc;
    00697       readProcStat( processID(pid), prc);
    00698       prc_start = prc.starttime+offset;
    00699     }
    00700
    00701     if ( processID(pid) == s_myPid ) {
    00702       struct rusage r;
    00703       getrusage( RUSAGE_SELF, &r );
    00704       tb->UserTime   = (static_cast<long long>(r.ru_utime.tv_sec) * 1000000 +
    00705                         r.ru_utime.tv_usec) * 10;
    00706       tb->KernelTime = (static_cast<long long>(r.ru_stime.tv_sec) * 1000000 +
    00707                         r.ru_stime.tv_usec) * 10;
    00708       tb->CreateTime = prc_start;
    00709     }
    00710     else {
    00711       linux_proc prc;
    00712       readProcStat( processID(pid), prc );
    00713
    00714       tms t;
    00715       times(&t);
    00716       tb->UserTime   = t.tms_utime * TICK_TO_100NSEC;
    00717       tb->KernelTime = t.tms_stime * TICK_TO_100NSEC;
    00718       tb->CreateTime = (prc.starttime+offset);
    00719     }
    00720     tb->CreateTime *= TICK_TO_100NSEC;
    00721     tb->ExitTime    = 0;
    00722
    00723     status = 1;
    00724
    00725 #elif defined(__APPLE__)
    00726     // FIXME (MCl): Make an alternative function get timing on OSX
    00727     // times() seems to cause a segmentation fault
    00728 #else  // no /proc file system: assume sys_start for the first call
    00729     tms tmsb;
    00730     static clock_t sys_start = times(0);
    00731     static longlong offset = 100*longlong(time(0)) - sys_start;
    00732     clock_t now = times(&tmsb);
    00733     tb->CreateTime    = offset + now;
    00734     tb->UserTime      = tmsb.tms_utime;
    00735     tb->KernelTime    = tmsb.tms_stime;
    00736     tb->CreateTime   *= TICK_TO_100NSEC;
    00737     tb->UserTime     *= TICK_TO_100NSEC;
    00738     tb->KernelTime   *= TICK_TO_100NSEC;
    00739     tb->ExitTime      = 0;
    00740     status = 1;
    00741 #endif
    00742   }
    00743   if ( info ) *info = *tb;
    00744   return status;
    00745 }

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines