The Gaudi Framework  v32r2 (46d42edc)
System::ProcessDescriptor Class Reference

Provides access to process information. More...

#include <src/Lib/ProcessDescriptor.h>

Classes

class  ProcessHandle
 

Public Member Functions

 ProcessDescriptor ()
 
virtual ~ProcessDescriptor ()
 
long query (long pid, InfoType info, PROCESS_BASIC_INFORMATION *buffer)
 
long query (long pid, InfoType info, POOLED_USAGE_AND_LIMITS *buffer)
 
long query (long pid, InfoType info, KERNEL_USER_TIMES *buffer)
 
long query (long pid, InfoType info, QUOTA_LIMITS *buffer)
 
long query (long pid, InfoType info, VM_COUNTERS *buffer)
 
long query (long pid, InfoType info, IO_COUNTERS *buffer)
 
long query (long pid, InfoType info, long *buffer)
 

Detailed Description

Provides access to process information.

Author
M.Frank
Sebastien Ponce

Definition at line 108 of file ProcessDescriptor.h.

Constructor & Destructor Documentation

◆ ProcessDescriptor()

System::ProcessDescriptor::ProcessDescriptor ( )

Definition at line 380 of file ProcessDescriptor.cpp.

380  {
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 }

◆ ~ProcessDescriptor()

System::ProcessDescriptor::~ProcessDescriptor ( )
virtual

Definition at line 394 of file ProcessDescriptor.cpp.

394 {}

Member Function Documentation

◆ query() [1/7]

long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
PROCESS_BASIC_INFORMATION buffer 
)

Definition at line 584 of file ProcessDescriptor.cpp.

584  {
585  if ( info == 0 ) return 0;
586  long status = 1;
587 
588  if ( fetch == ProcessBasics ) {
589 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
590  ProcessHandle h( pid );
591  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessBasicInformation, info,
592  sizeof( PROCESS_BASIC_INFORMATION ), 0 );
593  status = ( status == 0 ) ? 1 : 0;
594 #elif defined( _WIN32 ) // Windows 95,98...
595 #elif defined( __linux ) // Linux
596  linux_proc prc;
597  pid = processID( pid );
598  readProcStat( pid, prc );
599  info->ExitStatus = 0;
600  info->PebBaseAddress = (PPEB)prc.startcode;
601  info->BasePriority = 2 * 15 - prc.priority;
602  // std::cout << "Base Priority=" << info->BasePriority << "|"
603  // << prc.priority << std::endl;
604  info->AffinityMask = prc.flags;
605  // std::cout << "Flags =" << info->AffinityMask << "|"
606  // << prc.flags << std::endl;
607  info->UniqueProcessId = pid;
608  info->InheritedFromUniqueProcessId = prc.ppid;
609 #else // All Other
610  if ( pid ) {}
611 #endif // End ALL OS
612  }
613  return status;
614 }
unsigned long flags
void readProcStat(long pid, linux_proc &pinfo)
unsigned long startcode
struct _PEB * PPEB
Basic Process Information NtQueryInformationProcess using ProcessBasicInfo.
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32

◆ query() [2/7]

long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
POOLED_USAGE_AND_LIMITS buffer 
)

Definition at line 424 of file ProcessDescriptor.cpp.

424  {
425  if ( info == 0 ) return 0;
426  long status = 1;
427 
428  if ( fetch == Quota ) {
429 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
430  ProcessHandle h( pid );
431  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessPooledUsageAndLimits, info,
432  sizeof( POOLED_USAGE_AND_LIMITS ), 0 );
433  status = ( status == 0 ) ? 1 : 0;
434 #elif defined( _WIN32 ) // Windows 95,98...
435 #elif defined( __linux ) // Linux
436  // rusage usage;
437  // getrusage(RUSAGE_SELF, &usage);
438  rlimit lim;
439 
440  getrlimit( RLIMIT_DATA, &lim );
441  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
442  info->PeakPagedPoolUsage = lim.rlim_cur;
443  info->PagedPoolUsage = lim.rlim_cur;
444  info->PagedPoolLimit = lim.rlim_max;
445 
446  getrlimit( RLIMIT_STACK, &lim );
447  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
448  info->PeakNonPagedPoolUsage = lim.rlim_cur;
449  info->NonPagedPoolUsage = lim.rlim_cur;
450  info->NonPagedPoolLimit = lim.rlim_max;
451 
452  linux_proc prc;
453  readProcStat( processID( pid ), prc );
454  info->PeakPagefileUsage = prc.rss * pg_size;
455  info->PagefileUsage = prc.rss * pg_size;
456  info->PagefileLimit = 0xFFFFFFFF;
457 #elif defined( __APPLE__ )
458  if ( pid ) {}
459 #else // All Other
460  if ( pid ) {}
461 #endif // End ALL OS
462  }
463 
464  return status;
465 }
void readProcStat(long pid, linux_proc &pinfo)
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32

◆ query() [3/7]

long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
KERNEL_USER_TIMES buffer 
)

Definition at line 616 of file ProcessDescriptor.cpp.

616  {
617  if ( info == 0 ) return 0;
618  long status = 1;
619 
620  if ( fetch == Times ) {
621 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
622  ProcessHandle h( pid );
623  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessTimes, info, sizeof( KERNEL_USER_TIMES ), 0 );
624  status = ( status == 0 ) ? 1 : 0;
625 #elif defined( _WIN32 ) // Windows 95,98...
626 #elif defined( __linux ) // Linux
627  static long long prc_start = 0;
628  bool myself = pid <= 0 || pid == ::getpid(); // avoid unnecessary calls to getpid if pid<0
629  if ( myself && prc_start == 0 ) { // called only once to set prc_start
630  linux_proc prc;
631  readProcStat( processID( pid ), prc );
632  // prc.startup is in ticks since system start, need to offset for absolute time
633  tms tmsb;
634  static long long offset =
635  100 * static_cast<long long>( time( nullptr ) ) - static_cast<long long>( times( &tmsb ) );
636  prc_start = ( prc.starttime + offset ) * TICK_TO_100NSEC;
637  }
638 
639  if ( myself ) { // myself
640  tms tmsb;
641  times( &tmsb );
642  info->UserTime = tmsb.tms_utime * TICK_TO_100NSEC;
643  info->KernelTime = tmsb.tms_stime * TICK_TO_100NSEC;
644  info->CreateTime = prc_start;
645  } else { // other process
646  linux_proc prc;
647  readProcStat( processID( pid ), prc );
648  tms tmsb;
649  static long long offset =
650  100 * static_cast<long long>( time( nullptr ) ) - static_cast<long long>( times( &tmsb ) );
651 
652  tms t;
653  times( &t );
654  info->UserTime = t.tms_utime * TICK_TO_100NSEC;
655  info->KernelTime = t.tms_stime * TICK_TO_100NSEC;
656  info->CreateTime = ( prc.starttime + offset ) * TICK_TO_100NSEC;
657  }
658  info->ExitTime = 0;
659 
660  status = 1;
661 
662 #elif defined( __APPLE__ )
663  if ( pid ) {}
664 // FIXME (MCl): Make an alternative function get timing on OSX
665 // times() seems to cause a segmentation fault
666 #else // no /proc file system: assume sys_start for the first call
667  tms tmsb;
668  static clock_t sys_start = times( 0 );
669  static long long offset = 100 * long long( time( 0 ) ) - sys_start;
670  clock_t now = times( &tmsb );
671  info->CreateTime = offset + now;
672  info->UserTime = tmsb.tms_utime;
673  info->KernelTime = tmsb.tms_stime;
674  info->CreateTime *= TICK_TO_100NSEC;
675  info->UserTime *= TICK_TO_100NSEC;
676  info->KernelTime *= TICK_TO_100NSEC;
677  info->ExitTime = 0;
678  status = 1;
679 #endif
680  }
681 
682  return status;
683 }
void readProcStat(long pid, linux_proc &pinfo)
unsigned long long starttime
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32

◆ query() [4/7]

long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
QUOTA_LIMITS buffer 
)

Definition at line 538 of file ProcessDescriptor.cpp.

538  {
539  if ( info == 0 ) return 0;
540  long status = 1;
541 
542  if ( fetch == Quota ) {
543 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
544  ProcessHandle h( pid );
545  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessQuotaLimits, info, sizeof( QUOTA_LIMITS ), 0 );
546  status = ( status == 0 ) ? 1 : 0;
547 #elif defined( _WIN32 ) // Windows 95,98...
548 #elif defined( __linux ) // Linux
549  // On linux all this stuff typically is not set
550  // (ie. rlim_max=RLIM_INFINITY...)
551 
552  if ( pid > 0 && pid != ::getpid() ) return 0; // only possible for myself
553 
554  rlimit lim;
555  getrlimit( RLIMIT_DATA, &lim );
556  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
557  info->PagedPoolLimit = lim.rlim_max;
558 
559  getrlimit( RLIMIT_STACK, &lim );
560  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
561  info->NonPagedPoolLimit = lim.rlim_max;
562  info->MinimumWorkingSetSize = 0;
563 
564  getrlimit( RLIMIT_RSS, &lim );
565  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
566  info->MaximumWorkingSetSize = lim.rlim_max;
567 
568  getrlimit( RLIMIT_AS, &lim );
569  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
570  info->PagefileLimit = lim.rlim_max;
571 
572  getrlimit( RLIMIT_CPU, &lim );
573  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
574  info->TimeLimit = lim.rlim_max;
575 #elif defined( __APPLE__ )
576  if ( pid ) {}
577 #else // All Other
578  if ( pid ) {}
579 #endif // End ALL OS
580  }
581  return status;
582 }
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32

◆ query() [5/7]

long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
VM_COUNTERS buffer 
)

Definition at line 495 of file ProcessDescriptor.cpp.

495  {
496  if ( info == 0 ) return 0;
497  long status = 1;
498 
499  if ( fetch == Memory ) {
500 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
501  ProcessHandle h( pid );
502  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessVmCounters, info, sizeof( VM_COUNTERS ), 0 );
503  status = ( status == 0 ) ? 1 : 0;
504 #elif defined( _WIN32 ) // Windows 95,98...
505 #elif defined( __linux ) // Linux
506  const ssize_t bufsize = 1024;
507  char buf[bufsize];
508  pid = processID( pid );
509  sprintf( buf, "/proc/%ld/statm", pid );
510  long size, resident, share, trs, lrs, drs, dt;
511  int fd = open( buf, O_RDONLY );
512  ssize_t nread = read( fd, buf, bufsize );
513  close( fd );
514  if ( nread < bufsize && nread >= 0 ) buf[nread] = '\0';
515  fd = sscanf( buf, "%ld %ld %ld %ld %ld %ld %ld", &size, &resident, &share, &trs, &drs, &lrs, &dt );
516  linux_proc prc;
517  readProcStat( pid, prc );
518  info->PeakVirtualSize = prc.vsize;
519  info->VirtualSize = prc.vsize;
520  info->PeakWorkingSetSize = resident * pg_size;
521  info->WorkingSetSize = resident * pg_size;
522  info->QuotaPeakPagedPoolUsage = share * pg_size;
523  info->QuotaPagedPoolUsage = share * pg_size;
524  info->QuotaNonPagedPoolUsage = ( trs + drs ) * pg_size; // drs = data/stack size
525  info->QuotaPeakNonPagedPoolUsage = ( trs + drs ) * pg_size; // trs = VmExe size
526  info->PageFaultCount = prc.majflt + prc.minflt;
527  info->PagefileUsage = prc.vsize - resident * pg_size;
528  info->PeakPagefileUsage = prc.vsize - resident * pg_size;
529 #elif defined( __APPLE__ )
530  if ( pid ) {}
531 #else // All Other
532  if ( pid ) {}
533 #endif // End ALL OS
534  }
535  return status;
536 }
unsigned long minflt
constexpr auto size(const T &, Args &&...) noexcept
T sscanf(T... args)
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:23
void readProcStat(long pid, linux_proc &pinfo)
unsigned long vsize
unsigned long majflt
T sprintf(T... args)
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32

◆ query() [6/7]

long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
IO_COUNTERS buffer 
)

Definition at line 396 of file ProcessDescriptor.cpp.

396  {
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  if ( pid ) {}
419 #endif // End ALL OS
420  }
421  return status;
422 }
void usage(std::string argv0)
void readProcStat(long pid, linux_proc &pinfo)
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32

◆ query() [7/7]

long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
long *  buffer 
)

Definition at line 467 of file ProcessDescriptor.cpp.

467  {
468 
469  if ( info == 0 ) return 0;
470  long status = 1;
471 
472  switch ( fetch ) {
473  case PriorityBoost:
474 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT
475  ProcessHandle h( pid );
476  status = NtApi::NtQueryInformationProcess( h.handle(), ProcessPriorityBoost, info, sizeof( long ), 0 );
477 #elif defined( _WIN32 ) // Windows 95,98...
478  if ( pid ) {}
479 #else
480  // Not applicable
481  if ( pid > 0 ) status = 0; // to avoid compiler warning
482  status = 0;
483  *info = 0;
484 #endif // End ALL OS
485  status = ( status == 0 ) ? 1 : 0;
486  break;
487  default:
488  status = -1;
489  info = &status;
490  break;
491  }
492  return status;
493 }
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32

The documentation for this class was generated from the following files: