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() ) );
362 m_needRelease =
true;
367 m_needRelease =
false;
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;
424 if ( info == 0 )
return 0;
427 if ( fetch ==
Quota ) {
428 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 432 status = ( status == 0 ) ? 1 : 0;
433 #elif defined( _WIN32 ) // Windows 95,98... 434 #elif defined( __linux ) // Linux 439 getrlimit( RLIMIT_DATA, &lim );
440 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
441 info->PeakPagedPoolUsage = lim.rlim_cur;
442 info->PagedPoolUsage = lim.rlim_cur;
443 info->PagedPoolLimit = lim.rlim_max;
445 getrlimit( RLIMIT_STACK, &lim );
446 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
447 info->PeakNonPagedPoolUsage = lim.rlim_cur;
448 info->NonPagedPoolUsage = lim.rlim_cur;
449 info->NonPagedPoolLimit = lim.rlim_max;
453 info->PeakPagefileUsage = prc.
rss * pg_size;
454 info->PagefileUsage = prc.
rss * pg_size;
455 info->PagefileLimit = 0xFFFFFFFF;
456 #elif defined( __APPLE__ ) 466 if ( info == 0 )
return 0;
471 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 474 #elif defined( _WIN32 ) // Windows 95,98... 477 if ( pid > 0 ) status = 0;
481 status = ( status == 0 ) ? 1 : 0;
492 if ( info == 0 )
return 0;
496 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 499 status = ( status == 0 ) ? 1 : 0;
500 #elif defined( _WIN32 ) // Windows 95,98... 501 #elif defined( __linux ) // Linux 502 const ssize_t bufsize = 1024;
504 pid = processID( pid );
505 sprintf( buf,
"/proc/%ld/statm", pid );
506 long size, resident, share, trs, lrs, drs, dt;
507 int fd = open( buf, O_RDONLY );
508 ssize_t nread =
read( fd, buf, bufsize );
510 if ( nread < bufsize && nread >= 0 ) buf[nread] =
'\0';
511 fd = sscanf( buf,
"%ld %ld %ld %ld %ld %ld %ld", &size, &resident, &share, &trs, &drs, &lrs, &dt );
514 info->PeakVirtualSize = prc.
vsize;
515 info->VirtualSize = prc.
vsize;
516 info->PeakWorkingSetSize = resident * pg_size;
517 info->WorkingSetSize = resident * pg_size;
518 info->QuotaPeakPagedPoolUsage = share * pg_size;
519 info->QuotaPagedPoolUsage = share * pg_size;
520 info->QuotaNonPagedPoolUsage = ( trs + drs ) * pg_size;
521 info->QuotaPeakNonPagedPoolUsage = ( trs + drs ) * pg_size;
523 info->PagefileUsage = prc.
vsize - resident * pg_size;
524 info->PeakPagefileUsage = prc.
vsize - resident * pg_size;
525 #elif defined( __APPLE__ ) 533 if ( info == 0 )
return 0;
536 if ( fetch ==
Quota ) {
537 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 540 status = ( status == 0 ) ? 1 : 0;
541 #elif defined( _WIN32 ) // Windows 95,98... 542 #elif defined( __linux ) // Linux 546 if ( pid > 0 && pid != ::getpid() )
return 0;
549 getrlimit( RLIMIT_DATA, &lim );
550 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
551 info->PagedPoolLimit = lim.rlim_max;
553 getrlimit( RLIMIT_STACK, &lim );
554 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
555 info->NonPagedPoolLimit = lim.rlim_max;
556 info->MinimumWorkingSetSize = 0;
558 getrlimit( RLIMIT_RSS, &lim );
559 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
560 info->MaximumWorkingSetSize = lim.rlim_max;
562 getrlimit( RLIMIT_AS, &lim );
563 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
564 info->PagefileLimit = lim.rlim_max;
566 getrlimit( RLIMIT_CPU, &lim );
567 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
568 info->TimeLimit = lim.rlim_max;
569 #elif defined( __APPLE__ ) 577 if ( info == 0 )
return 0;
581 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 585 status = ( status == 0 ) ? 1 : 0;
586 #elif defined( _WIN32 ) // Windows 95,98... 587 #elif defined( __linux ) // Linux 589 pid = processID( pid );
591 info->ExitStatus = 0;
593 info->BasePriority = 2 * 15 - prc.
priority;
596 info->AffinityMask = prc.
flags;
599 info->UniqueProcessId = pid;
600 info->InheritedFromUniqueProcessId = prc.
ppid;
608 if ( info == 0 )
return 0;
611 if ( fetch ==
Times ) {
612 #if defined( _WIN32 ) && WINVER >= 0x0400 // Windows NT 615 status = ( status == 0 ) ? 1 : 0;
616 #elif defined( _WIN32 ) // Windows 95,98... 617 #elif defined( __linux ) // Linux 618 static long long prc_start = 0;
619 bool myself = pid <= 0 || pid == ::getpid();
620 if ( myself && prc_start == 0 ) {
625 static long long offset =
626 100 *
static_cast<long long>(
time(
nullptr ) ) - static_cast<long long>( times( &tmsb ) );
627 prc_start = ( prc.
starttime + offset ) * TICK_TO_100NSEC;
633 info->UserTime = tmsb.tms_utime * TICK_TO_100NSEC;
634 info->KernelTime = tmsb.tms_stime * TICK_TO_100NSEC;
635 info->CreateTime = prc_start;
640 static long long offset =
641 100 *
static_cast<long long>(
time(
nullptr ) ) - static_cast<long long>( times( &tmsb ) );
645 info->UserTime = t.tms_utime * TICK_TO_100NSEC;
646 info->KernelTime = t.tms_stime * TICK_TO_100NSEC;
647 info->CreateTime = ( prc.
starttime + offset ) * TICK_TO_100NSEC;
653 #elif defined( __APPLE__ ) 656 #else // no /proc file system: assume sys_start for the first call 658 static clock_t sys_start = times( 0 );
659 static long long offset = 100 *
long long(
time( 0 ) ) - sys_start;
660 clock_t now = times( &tmsb );
661 info->CreateTime = offset + now;
662 info->UserTime = tmsb.tms_utime;
663 info->KernelTime = tmsb.tms_stime;
664 info->CreateTime *= TICK_TO_100NSEC;
665 info->UserTime *= TICK_TO_100NSEC;
666 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.