25 #define GAUDIKERNEL_PROCSTAT_CPP 28 static const long TICK_TO_100NSEC = 100000;
29 #endif // not __APPLE__ 61 # define strcasecmp _stricmp 62 # define strncasecmp _strnicmp 67 # define getpid _getpid 73 typedef long( WINAPI* __NtQueryInformationProcess )(
75 void*
ProcessHandle,
long ProcessInformationClass,
void* ProcessInformation,
76 unsigned long ProcessInformationLength,
unsigned long* ReturnLength );
77 __NtQueryInformationProcess NtQueryInformationProcess;
79 #else // UNIX...: first the EGCS stuff, then the OS dependent includes 82 # include "sys/times.h" 90 # include <sys/signal.h> 91 # include <sys/syscall.h> 92 # include <sys/types.h> 95 # include <sys/procfs.h> 98 # include <sys/resource.h> 99 # include <sys/time.h> 309 static long pg_size = sysconf( _SC_PAGESIZE );
318 ost <<
"/proc/" << pid <<
"/stat";
320 if ( (
fd = open( fname.
c_str(), O_RDONLY ) ) < 0 ) {
325 lseek(
fd, 0, SEEK_SET );
326 if ( ( cnt =
read(
fd, buf,
sizeof( buf ) - 1 ) ) < 0 ) {
338 "%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld %lu %lu %lu %lu " 339 "%lu %lu %lu %lu %lu %lu %lu",
355 static inline long processID(
long pid ) {
return ( pid > 0 ) ? pid : ( ::getpid() ); }
356 #endif // not __APPLE__ 365 if ( pid != ::getpid() ) {
367 m_handle = ::OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pid );
370 m_handle = reinterpret_cast<void*>( static_cast<long>( ::getpid() ) );
381 if ( m_needRelease ) {
383 ::CloseHandle( m_handle );
392 static bool first =
true;
395 void* mh = ::LoadLibrary(
"NTDll.dll" );
397 NtApi::NtQueryInformationProcess =
398 ( NtApi::__NtQueryInformationProcess )::GetProcAddress( (HINSTANCE)mh,
"NtQueryInformationProcess" );
407 if ( info == 0 )
return 0;
411 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 414 status = ( status == 0 ) ? 1 : 0;
415 #elif defined( _WIN32 ) // Windows 95,98... 416 #elif defined( __linux ) 420 getrusage( RUSAGE_SELF, &
usage );
421 info->ReadOperationCount =
usage.ru_inblock;
422 info->WriteOperationCount =
usage.ru_oublock;
423 info->OtherOperationCount = 0;
424 info->ReadTransferCount =
usage.ru_inblock;
425 info->WriteTransferCount =
usage.ru_oublock;
426 info->OtherTransferCount = 0;
435 if ( info == 0 )
return 0;
438 if ( fetch ==
Quota ) {
439 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 443 status = ( status == 0 ) ? 1 : 0;
444 #elif defined( _WIN32 ) // Windows 95,98... 445 #elif defined( __linux ) // Linux 450 getrlimit( RLIMIT_DATA, &lim );
451 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
452 info->PeakPagedPoolUsage = lim.rlim_cur;
453 info->PagedPoolUsage = lim.rlim_cur;
454 info->PagedPoolLimit = lim.rlim_max;
456 getrlimit( RLIMIT_STACK, &lim );
457 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
458 info->PeakNonPagedPoolUsage = lim.rlim_cur;
459 info->NonPagedPoolUsage = lim.rlim_cur;
460 info->NonPagedPoolLimit = lim.rlim_max;
464 info->PeakPagefileUsage = prc.
rss * pg_size;
465 info->PagefileUsage = prc.
rss * pg_size;
466 info->PagefileLimit = 0xFFFFFFFF;
467 #elif defined( __APPLE__ ) 479 if ( info == 0 )
return 0;
484 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 487 #elif defined( _WIN32 ) // Windows 95,98... 491 if ( pid > 0 ) status = 0;
495 status = ( status == 0 ) ? 1 : 0;
506 if ( info == 0 )
return 0;
510 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 513 status = ( status == 0 ) ? 1 : 0;
514 #elif defined( _WIN32 ) // Windows 95,98... 515 #elif defined( __linux ) // Linux 516 const ssize_t bufsize = 1024;
518 pid = processID( pid );
519 sprintf( buf,
"/proc/%ld/statm", pid );
520 long size, resident, share, trs, lrs, drs, dt;
521 int fd = open( buf, O_RDONLY );
522 ssize_t nread =
read(
fd, buf, bufsize );
524 if ( nread < bufsize && nread >= 0 ) buf[nread] =
'\0';
525 fd = sscanf( buf,
"%ld %ld %ld %ld %ld %ld %ld", &
size, &resident, &share, &trs, &drs, &lrs, &dt );
528 info->PeakVirtualSize = prc.
vsize;
529 info->VirtualSize = prc.
vsize;
530 info->PeakWorkingSetSize = resident * pg_size;
531 info->WorkingSetSize = resident * pg_size;
532 info->QuotaPeakPagedPoolUsage = share * pg_size;
533 info->QuotaPagedPoolUsage = share * pg_size;
534 info->QuotaNonPagedPoolUsage = ( trs + drs ) * pg_size;
535 info->QuotaPeakNonPagedPoolUsage = ( trs + drs ) * pg_size;
537 info->PagefileUsage = prc.
vsize - resident * pg_size;
538 info->PeakPagefileUsage = prc.
vsize - resident * pg_size;
539 #elif defined( __APPLE__ ) 549 if ( info == 0 )
return 0;
552 if ( fetch ==
Quota ) {
553 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 556 status = ( status == 0 ) ? 1 : 0;
557 #elif defined( _WIN32 ) // Windows 95,98... 558 #elif defined( __linux ) // Linux 562 if ( pid > 0 && pid != ::getpid() )
return 0;
565 getrlimit( RLIMIT_DATA, &lim );
566 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
567 info->PagedPoolLimit = lim.rlim_max;
569 getrlimit( RLIMIT_STACK, &lim );
570 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
571 info->NonPagedPoolLimit = lim.rlim_max;
572 info->MinimumWorkingSetSize = 0;
574 getrlimit( RLIMIT_RSS, &lim );
575 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
576 info->MaximumWorkingSetSize = lim.rlim_max;
578 getrlimit( RLIMIT_AS, &lim );
579 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
580 info->PagefileLimit = lim.rlim_max;
582 getrlimit( RLIMIT_CPU, &lim );
583 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
584 info->TimeLimit = lim.rlim_max;
585 #elif defined( __APPLE__ ) 595 if ( info == 0 )
return 0;
599 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 603 status = ( status == 0 ) ? 1 : 0;
604 #elif defined( _WIN32 ) // Windows 95,98... 605 #elif defined( __linux ) // Linux 607 pid = processID( pid );
609 info->ExitStatus = 0;
611 info->BasePriority = 2 * 15 - prc.
priority;
614 info->AffinityMask = prc.
flags;
617 info->UniqueProcessId = pid;
618 info->InheritedFromUniqueProcessId = prc.
ppid;
627 if ( info == 0 )
return 0;
630 if ( fetch ==
Times ) {
631 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 634 status = ( status == 0 ) ? 1 : 0;
635 #elif defined( _WIN32 ) // Windows 95,98... 636 #elif defined( __linux ) // Linux 637 static long long prc_start = 0;
638 bool myself = pid <= 0 || pid == ::getpid();
639 if ( myself && prc_start == 0 ) {
644 static long long offset =
645 100 * static_cast<long long>(
time(
nullptr ) ) - static_cast<long long>( times( &tmsb ) );
646 prc_start = ( prc.
starttime + offset ) * TICK_TO_100NSEC;
652 info->UserTime = tmsb.tms_utime * TICK_TO_100NSEC;
653 info->KernelTime = tmsb.tms_stime * TICK_TO_100NSEC;
654 info->CreateTime = prc_start;
659 static long long offset =
660 100 * static_cast<long long>(
time(
nullptr ) ) - static_cast<long long>( times( &tmsb ) );
664 info->UserTime = t.tms_utime * TICK_TO_100NSEC;
665 info->KernelTime = t.tms_stime * TICK_TO_100NSEC;
666 info->CreateTime = ( prc.
starttime + offset ) * TICK_TO_100NSEC;
672 #elif defined( __APPLE__ ) 676 #else // no /proc file system: assume sys_start for the first call 678 static clock_t sys_start = times( 0 );
679 static long long offset = 100 *
long long(
time( 0 ) ) - sys_start;
680 clock_t now = times( &tmsb );
681 info->CreateTime = offset + now;
682 info->UserTime = tmsb.tms_utime;
683 info->KernelTime = tmsb.tms_stime;
684 info->CreateTime *= TICK_TO_100NSEC;
685 info->UserTime *= TICK_TO_100NSEC;
686 info->KernelTime *= TICK_TO_100NSEC;
constexpr auto size(const T &, Args &&...) noexcept
Process/Thread System and User Time NtQueryInformationProcess using ProcessTimes NtQueryInformationTh...
Note: OS specific details for environment resolution.
Process I/O Counters NtQueryInformationProcess using ProcessIoCounters.
void usage(std::string argv0)
def read(f, regex='.*', skipevents=0)
GAUDI_API ProcessHandle processHandle()
Handle to running process.
void readProcStat(long pid, linux_proc &pinfo)
unsigned long long starttime
Process Quotas NtQueryInformationProcess using ProcessQuotaLimits NtQueryInformationProcess using Pro...
long query(long pid, InfoType info, PROCESS_BASIC_INFORMATION *buffer)
struct _PEB * PPEB
Basic Process Information NtQueryInformationProcess using ProcessBasicInfo.
Process Virtual Memory Counters NtQueryInformationProcess using ProcessVmCounters.
Process Pooled Quota Usage and Limits NtQueryInformationProcess using ProcessPooledUsageAndLimits.
virtual ~ProcessDescriptor()
InfoType
Enumeration for fetching information.
void * ProcessHandle
Definition of the process handle.