15 #define GAUDIKERNEL_PROCSTAT_CPP 18 static const long TICK_TO_100NSEC = 100000;
19 #endif // not __APPLE__ 52 #define strcasecmp _stricmp 53 #define strncasecmp _strnicmp 58 #define getpid _getpid 65 typedef long( WINAPI* __NtQueryInformationProcess )(
67 void*
ProcessHandle,
long ProcessInformationClass,
void* ProcessInformation,
68 unsigned long ProcessInformationLength,
unsigned long* ReturnLength );
69 __NtQueryInformationProcess NtQueryInformationProcess;
71 #else // UNIX...: first the EGCS stuff, then the OS dependent includes 74 #include "sys/times.h" 82 #include <sys/signal.h> 83 #include <sys/syscall.h> 84 #include <sys/types.h> 87 #include <sys/procfs.h> 90 #include <sys/resource.h> 301 static long pg_size = sysconf( _SC_PAGESIZE );
311 ost <<
"/proc/" << pid <<
"/stat";
313 if ( ( fd = open( fname.
c_str(), O_RDONLY ) ) < 0 ) {
318 lseek( fd, 0, SEEK_SET );
319 if ( ( cnt =
read( fd, buf,
sizeof( buf ) - 1 ) ) < 0 ) {
331 "%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 " 332 "%lu %lu %lu %lu %lu %lu %lu",
348 static inline long processID(
long pid ) {
return ( pid > 0 ) ? pid : (::getpid() ); }
349 #endif // not __APPLE__ 359 if ( pid != ::getpid() ) {
361 m_handle = ::OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pid );
364 m_handle =
reinterpret_cast<void*
>(
static_cast<long>(::getpid() ) );
366 m_needRelease =
true;
371 m_needRelease =
false;
376 if ( m_needRelease ) {
378 ::CloseHandle( m_handle );
388 static bool first =
true;
391 void* mh = ::LoadLibrary(
"NTDll.dll" );
393 NtApi::NtQueryInformationProcess =
394 ( NtApi::__NtQueryInformationProcess )::GetProcAddress( (HINSTANCE)mh,
"NtQueryInformationProcess" );
404 if ( info == 0 )
return 0;
408 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 411 status = ( status == 0 ) ? 1 : 0;
412 #elif defined( _WIN32 ) // Windows 95,98... 413 #elif defined( __linux ) 417 getrusage( RUSAGE_SELF, &usage );
418 info->ReadOperationCount = usage.ru_inblock;
419 info->WriteOperationCount = usage.ru_oublock;
420 info->OtherOperationCount = 0;
421 info->ReadTransferCount = usage.ru_inblock;
422 info->WriteTransferCount = usage.ru_oublock;
423 info->OtherTransferCount = 0;
432 if ( info == 0 )
return 0;
435 if ( fetch ==
Quota ) {
436 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 440 status = ( status == 0 ) ? 1 : 0;
441 #elif defined( _WIN32 ) // Windows 95,98... 442 #elif defined( __linux ) // Linux 447 getrlimit( RLIMIT_DATA, &lim );
448 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
449 info->PeakPagedPoolUsage = lim.rlim_cur;
450 info->PagedPoolUsage = lim.rlim_cur;
451 info->PagedPoolLimit = lim.rlim_max;
453 getrlimit( RLIMIT_STACK, &lim );
454 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
455 info->PeakNonPagedPoolUsage = lim.rlim_cur;
456 info->NonPagedPoolUsage = lim.rlim_cur;
457 info->NonPagedPoolLimit = lim.rlim_max;
461 info->PeakPagefileUsage = prc.
rss * pg_size;
462 info->PagefileUsage = prc.
rss * pg_size;
463 info->PagefileLimit = 0xFFFFFFFF;
464 #elif defined( __APPLE__ ) 475 if ( info == 0 )
return 0;
480 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 483 #elif defined( _WIN32 ) // Windows 95,98... 486 if ( pid > 0 ) status = 0;
490 status = ( status == 0 ) ? 1 : 0;
502 if ( info == 0 )
return 0;
506 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 509 status = ( status == 0 ) ? 1 : 0;
510 #elif defined( _WIN32 ) // Windows 95,98... 511 #elif defined( __linux ) // Linux 512 const ssize_t bufsize = 1024;
514 pid = processID( pid );
515 sprintf( buf,
"/proc/%ld/statm", pid );
516 long size, resident, share, trs, lrs, drs, dt;
517 int fd = open( buf, O_RDONLY );
518 ssize_t nread =
read( fd, buf, bufsize );
520 if ( nread < bufsize && nread >= 0 ) buf[nread] =
'\0';
521 fd = sscanf( buf,
"%ld %ld %ld %ld %ld %ld %ld", &size, &resident, &share, &trs, &drs, &lrs, &dt );
524 info->PeakVirtualSize = prc.
vsize;
525 info->VirtualSize = prc.
vsize;
526 info->PeakWorkingSetSize = resident * pg_size;
527 info->WorkingSetSize = resident * pg_size;
528 info->QuotaPeakPagedPoolUsage = share * pg_size;
529 info->QuotaPagedPoolUsage = share * pg_size;
530 info->QuotaNonPagedPoolUsage = ( trs + drs ) * pg_size;
531 info->QuotaPeakNonPagedPoolUsage = ( trs + drs ) * pg_size;
533 info->PagefileUsage = prc.
vsize - resident * pg_size;
534 info->PeakPagefileUsage = prc.
vsize - resident * pg_size;
535 #elif defined( __APPLE__ ) 544 if ( info == 0 )
return 0;
547 if ( fetch ==
Quota ) {
548 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 551 status = ( status == 0 ) ? 1 : 0;
552 #elif defined( _WIN32 ) // Windows 95,98... 553 #elif defined( __linux ) // Linux 557 if ( pid > 0 && pid != ::getpid() )
return 0;
560 getrlimit( RLIMIT_DATA, &lim );
561 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
562 info->PagedPoolLimit = lim.rlim_max;
564 getrlimit( RLIMIT_STACK, &lim );
565 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
566 info->NonPagedPoolLimit = lim.rlim_max;
567 info->MinimumWorkingSetSize = 0;
569 getrlimit( RLIMIT_RSS, &lim );
570 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
571 info->MaximumWorkingSetSize = lim.rlim_max;
573 getrlimit( RLIMIT_AS, &lim );
574 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
575 info->PagefileLimit = lim.rlim_max;
577 getrlimit( RLIMIT_CPU, &lim );
578 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
579 info->TimeLimit = lim.rlim_max;
580 #elif defined( __APPLE__ ) 589 if ( info == 0 )
return 0;
593 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 597 status = ( status == 0 ) ? 1 : 0;
598 #elif defined( _WIN32 ) // Windows 95,98... 599 #elif defined( __linux ) // Linux 601 pid = processID( pid );
603 info->ExitStatus = 0;
605 info->BasePriority = 2 * 15 - prc.
priority;
608 info->AffinityMask = prc.
flags;
611 info->UniqueProcessId = pid;
612 info->InheritedFromUniqueProcessId = prc.
ppid;
621 if ( info == 0 )
return 0;
624 if ( fetch ==
Times ) {
625 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 628 status = ( status == 0 ) ? 1 : 0;
629 #elif defined( _WIN32 ) // Windows 95,98... 630 #elif defined( __linux ) // Linux 632 bool myself = pid <= 0 || pid == ::getpid();
633 if ( myself && prc_start == 0 ) {
639 prc_start = ( prc.
starttime + offset ) * TICK_TO_100NSEC;
645 info->UserTime = tmsb.tms_utime * TICK_TO_100NSEC;
646 info->KernelTime = tmsb.tms_stime * TICK_TO_100NSEC;
647 info->CreateTime = prc_start;
656 info->UserTime = t.tms_utime * TICK_TO_100NSEC;
657 info->KernelTime = t.tms_stime * TICK_TO_100NSEC;
658 info->CreateTime = ( prc.
starttime + offset ) * TICK_TO_100NSEC;
664 #elif defined( __APPLE__ ) 667 #else // no /proc file system: assume sys_start for the first call 669 static clock_t sys_start = times( 0 );
671 clock_t now = times( &tmsb );
672 info->CreateTime = offset + now;
673 info->UserTime = tmsb.tms_utime;
674 info->KernelTime = tmsb.tms_stime;
675 info->CreateTime *= TICK_TO_100NSEC;
676 info->UserTime *= TICK_TO_100NSEC;
677 info->KernelTime *= TICK_TO_100NSEC;
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)
constexpr auto size(const C &c) noexcept(noexcept(c.size())) -> decltype(c.size())
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.