15 #define GAUDIKERNEL_PROCSTAT_CPP 18 static const long TICK_TO_100NSEC = 100000;
19 #endif // not __APPLE__ 51 # define strcasecmp _stricmp 52 # define strncasecmp _strnicmp 57 # define getpid _getpid 63 typedef long( WINAPI* __NtQueryInformationProcess )(
65 void*
ProcessHandle,
long ProcessInformationClass,
void* ProcessInformation,
66 unsigned long ProcessInformationLength,
unsigned long* ReturnLength );
67 __NtQueryInformationProcess NtQueryInformationProcess;
69 #else // UNIX...: first the EGCS stuff, then the OS dependent includes 72 # include "sys/times.h" 80 # include <sys/signal.h> 81 # include <sys/syscall.h> 82 # include <sys/types.h> 85 # include <sys/procfs.h> 88 # include <sys/resource.h> 89 # include <sys/time.h> 299 static long pg_size = sysconf( _SC_PAGESIZE );
308 ost <<
"/proc/" << pid <<
"/stat";
310 if ( (
fd = open( fname.
c_str(), O_RDONLY ) ) < 0 ) {
315 lseek(
fd, 0, SEEK_SET );
316 if ( ( cnt =
read(
fd, buf,
sizeof( buf ) - 1 ) ) < 0 ) {
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",
345 static inline long processID(
long pid ) {
return ( pid > 0 ) ? pid : ( ::getpid() ); }
346 #endif // not __APPLE__ 355 if ( pid != ::getpid() ) {
357 m_handle = ::OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pid );
360 m_handle = reinterpret_cast<void*>( static_cast<long>( ::getpid() ) );
371 if ( m_needRelease ) {
373 ::CloseHandle( m_handle );
382 static bool first =
true;
385 void* mh = ::LoadLibrary(
"NTDll.dll" );
387 NtApi::NtQueryInformationProcess =
388 ( NtApi::__NtQueryInformationProcess )::GetProcAddress( (HINSTANCE)mh,
"NtQueryInformationProcess" );
397 if ( info == 0 )
return 0;
401 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 404 status = ( status == 0 ) ? 1 : 0;
405 #elif defined( _WIN32 ) // Windows 95,98... 406 #elif defined( __linux ) 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;
425 if ( info == 0 )
return 0;
428 if ( fetch ==
Quota ) {
429 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 433 status = ( status == 0 ) ? 1 : 0;
434 #elif defined( _WIN32 ) // Windows 95,98... 435 #elif defined( __linux ) // Linux 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;
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;
454 info->PeakPagefileUsage = prc.
rss * pg_size;
455 info->PagefileUsage = prc.
rss * pg_size;
456 info->PagefileLimit = 0xFFFFFFFF;
457 #elif defined( __APPLE__ ) 469 if ( info == 0 )
return 0;
474 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 477 #elif defined( _WIN32 ) // Windows 95,98... 481 if ( pid > 0 ) status = 0;
485 status = ( status == 0 ) ? 1 : 0;
496 if ( info == 0 )
return 0;
500 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 503 status = ( status == 0 ) ? 1 : 0;
504 #elif defined( _WIN32 ) // Windows 95,98... 505 #elif defined( __linux ) // Linux 506 const ssize_t bufsize = 1024;
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 );
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 );
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;
525 info->QuotaPeakNonPagedPoolUsage = ( trs + drs ) * pg_size;
527 info->PagefileUsage = prc.
vsize - resident * pg_size;
528 info->PeakPagefileUsage = prc.
vsize - resident * pg_size;
529 #elif defined( __APPLE__ ) 539 if ( info == 0 )
return 0;
542 if ( fetch ==
Quota ) {
543 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 546 status = ( status == 0 ) ? 1 : 0;
547 #elif defined( _WIN32 ) // Windows 95,98... 548 #elif defined( __linux ) // Linux 552 if ( pid > 0 && pid != ::getpid() )
return 0;
555 getrlimit( RLIMIT_DATA, &lim );
556 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
557 info->PagedPoolLimit = lim.rlim_max;
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;
564 getrlimit( RLIMIT_RSS, &lim );
565 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
566 info->MaximumWorkingSetSize = lim.rlim_max;
568 getrlimit( RLIMIT_AS, &lim );
569 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
570 info->PagefileLimit = lim.rlim_max;
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__ ) 585 if ( info == 0 )
return 0;
589 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 593 status = ( status == 0 ) ? 1 : 0;
594 #elif defined( _WIN32 ) // Windows 95,98... 595 #elif defined( __linux ) // Linux 597 pid = processID( pid );
599 info->ExitStatus = 0;
601 info->BasePriority = 2 * 15 - prc.
priority;
604 info->AffinityMask = prc.
flags;
607 info->UniqueProcessId = pid;
608 info->InheritedFromUniqueProcessId = prc.
ppid;
617 if ( info == 0 )
return 0;
620 if ( fetch ==
Times ) {
621 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 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();
629 if ( myself && prc_start == 0 ) {
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;
642 info->UserTime = tmsb.tms_utime * TICK_TO_100NSEC;
643 info->KernelTime = tmsb.tms_stime * TICK_TO_100NSEC;
644 info->CreateTime = prc_start;
649 static long long offset =
650 100 * static_cast<long long>(
time(
nullptr ) ) - static_cast<long long>( times( &tmsb ) );
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;
662 #elif defined( __APPLE__ ) 666 #else // no /proc file system: assume sys_start for the first call 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;
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.