15 #define GAUDIKERNEL_PROCSTAT_CPP
17 static const long TICK_TO_100NSEC = 100000;
49 # define strcasecmp _stricmp
50 # define strncasecmp _strnicmp
55 #define getpid _getpid
61 typedef long (WINAPI *__NtQueryInformationProcess)(
64 long ProcessInformationClass,
65 void* ProcessInformation,
66 unsigned long ProcessInformationLength,
67 unsigned long* ReturnLength
69 __NtQueryInformationProcess NtQueryInformationProcess;
71 #else // UNIX...: first the EGCS stuff, then the OS dependent includes
82 #include "sys/times.h"
83 #include <sys/types.h>
84 #include <sys/signal.h>
85 #include <sys/syscall.h>
87 #include <sys/procfs.h>
90 #include <sys/resource.h>
301 static long pg_size = sysconf(_SC_PAGESIZE);
308 std::ostringstream ost;
310 ost <<
"/proc/" << pid <<
"/stat";
311 std::string fname = ost.str();
312 if((fd=open(fname.c_str(),O_RDONLY))<0) {
313 std::cerr <<
"Failed to open " << ost.str() << std::endl;
317 lseek(fd,0,SEEK_SET);
318 if((cnt=read(fd,buf,
sizeof(buf)))<0) {
319 std::cout <<
"LINUX Read of Proc file failed:" << std::endl;
329 "%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 %lu %lu %lu %lu %lu %lu %lu",
373 #define s_myPid (::getpid())
374 static inline long processID(
long pid) {
375 long thePid = (pid>0) ? pid :
s_myPid;
387 static bool first =
true;
390 void* mh = ::LoadLibrary(
"NTDll.dll");
392 NtApi::NtQueryInformationProcess = (NtApi::__NtQueryInformationProcess)
393 ::GetProcAddress((HINSTANCE)mh,
"NtQueryInformationProcess");
404 m_handle = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
FALSE,
419 if ( m_needRelease ) {
421 ::CloseHandle(m_handle);
442 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
443 status = NtApi::NtQueryInformationProcess(h.
handle(),
448 status = (status==0) ? 1 : 0;
449 #elif defined(_WIN32) // Windows 95,98...
450 #elif defined(__linux)
454 getrusage(RUSAGE_SELF, &usage);
455 vb->ReadOperationCount = usage.ru_inblock;
456 vb->WriteOperationCount = usage.ru_oublock;
457 vb->OtherOperationCount = 0;
458 vb->ReadTransferCount = usage.ru_inblock;
459 vb->WriteTransferCount = usage.ru_oublock;
460 vb->OtherTransferCount = 0;
464 if ( info ) *info = *vb;
474 if ( fetch ==
Quota ) {
475 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
476 status = NtApi::NtQueryInformationProcess(h.
handle(),
481 status = (status==0) ? 1 : 0;
482 #elif defined(_WIN32) // Windows 95,98...
483 #elif defined(__linux) // Linux
488 getrlimit(RLIMIT_DATA, &lim);
489 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
490 vb->PeakPagedPoolUsage = lim.rlim_cur;
491 vb->PagedPoolUsage = lim.rlim_cur;
492 vb->PagedPoolLimit = lim.rlim_max;
494 getrlimit(RLIMIT_STACK, &lim);
495 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
496 vb->PeakNonPagedPoolUsage = lim.rlim_cur;
497 vb->NonPagedPoolUsage = lim.rlim_cur;
498 vb->NonPagedPoolLimit = lim.rlim_max;
502 vb->PeakPagefileUsage = prc.
rss * pg_size;
503 vb->PagefileUsage = prc.
rss * pg_size;
504 vb->PagefileLimit = 0xFFFFFFFF;
505 #elif defined(__APPLE__)
509 if ( info ) *info = *vb;
514 long status = 1, *vb = &status;
520 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
521 status = NtApi::NtQueryInformationProcess(h.
handle(),
526 #elif defined(_WIN32) // Windows 95,98...
532 status = (status==0) ? 1 : 0;
539 if ( info ) *info = *vb;
550 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
551 status = NtApi::NtQueryInformationProcess(h.
handle(),
556 status = (status==0) ? 1 : 0;
557 #elif defined(_WIN32) // Windows 95,98...
558 #elif defined(__linux) // Linux
559 const ssize_t bufsize = 1024;
561 sprintf(buf,
"/proc/%ld/statm", processID(pid));
562 long size, resident, share, trs, lrs, drs, dt;
563 int fd = open(buf,O_RDONLY);
564 ssize_t nread = read(fd, buf, bufsize);
566 if ( nread < bufsize && nread >= 0 )
568 fd = sscanf(buf,
"%ld %ld %ld %ld %ld %ld %ld",
569 &size, &resident, &share, &trs, &drs, &lrs, &dt);
572 vb->PeakVirtualSize = prc.
vsize;
573 vb->VirtualSize = prc.
vsize;
574 vb->PeakWorkingSetSize = resident * pg_size;
575 vb->WorkingSetSize = resident * pg_size;
576 vb->QuotaPeakPagedPoolUsage = share * pg_size;
577 vb->QuotaPagedPoolUsage = share * pg_size;
578 vb->QuotaNonPagedPoolUsage = (trs+drs)* pg_size;
579 vb->QuotaPeakNonPagedPoolUsage = (trs+drs)* pg_size;
581 vb->PagefileUsage = prc.
vsize-resident*pg_size;
582 vb->PeakPagefileUsage = prc.
vsize-resident*pg_size;
583 #elif defined(__APPLE__)
587 if ( info ) *info = *vb;
597 if ( fetch ==
Quota ) {
598 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
599 status = NtApi::NtQueryInformationProcess(h.
handle(),
604 status = (status==0) ? 1 : 0;
605 #elif defined(_WIN32) // Windows 95,98...
606 #elif defined(__linux) // Linux
610 getrlimit(RLIMIT_DATA, &lim);
611 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
612 vb->PagedPoolLimit = lim.rlim_max;
614 getrlimit(RLIMIT_STACK, &lim);
615 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
616 vb->NonPagedPoolLimit = lim.rlim_max;
617 vb->MinimumWorkingSetSize = 0;
619 getrlimit(RLIMIT_RSS, &lim);
620 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
621 vb->MaximumWorkingSetSize = lim.rlim_max;
623 getrlimit(RLIMIT_AS, &lim);
624 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
625 vb->PagefileLimit = lim.rlim_max;
627 getrlimit(RLIMIT_CPU, &lim);
628 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
629 vb->TimeLimit = lim.rlim_max;
630 #elif defined(__APPLE__)
634 if ( info ) *info = *vb;
645 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
646 status = NtApi::NtQueryInformationProcess(h.
handle(),
651 status = (status==0) ? 1 : 0;
652 #elif defined(_WIN32) // Windows 95,98...
653 #elif defined(__linux) // Linux
658 vb->BasePriority = 2*15-prc.
priority;
661 vb->AffinityMask = prc.
flags;
664 vb->UniqueProcessId = processID(pid);
665 vb->InheritedFromUniqueProcessId = prc.
ppid;
669 if ( info ) *info = *vb;
679 if ( fetch ==
Times ) {
680 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
681 status = NtApi::NtQueryInformationProcess(h.
handle(),
686 status = (status==0) ? 1 : 0;
687 #elif defined(_WIN32) // Windows 95,98...
688 #elif defined(__linux) // Linux
695 if ( processID(pid) ==
s_myPid && prc_start == 0 ) {
701 if ( processID(pid) ==
s_myPid ) {
703 getrusage( RUSAGE_SELF, &r );
704 tb->UserTime = (
static_cast<long long>(r.ru_utime.tv_sec) * 1000000 +
705 r.ru_utime.tv_usec) * 10;
706 tb->KernelTime = (
static_cast<long long>(r.ru_stime.tv_sec) * 1000000 +
707 r.ru_stime.tv_usec) * 10;
708 tb->CreateTime = prc_start;
716 tb->UserTime = t.tms_utime * TICK_TO_100NSEC;
717 tb->KernelTime = t.tms_stime * TICK_TO_100NSEC;
720 tb->CreateTime *= TICK_TO_100NSEC;
725 #elif defined(__APPLE__)
728 #else // no /proc file system: assume sys_start for the first call
730 static clock_t sys_start = times(0);
732 clock_t now = times(&tmsb);
733 tb->CreateTime = offset + now;
734 tb->UserTime = tmsb.tms_utime;
735 tb->KernelTime = tmsb.tms_stime;
736 tb->CreateTime *= TICK_TO_100NSEC;
737 tb->UserTime *= TICK_TO_100NSEC;
738 tb->KernelTime *= TICK_TO_100NSEC;
743 if ( info ) *info = *tb;
ProcessDescriptor * getProcess()
Retrieve Process structure.
Process/Thread System and User Time NtQueryInformationProcess using ProcessTimes NtQueryInformationTh...
Process I/O Counters NtQueryInformationProcess using ProcessIoCounters.
QUOTA_LIMITS m_QUOTA_LIMITS[2]
void usage(std::string argv0)
GAUDI_API ProcessHandle processHandle()
Handle to running process.
KERNEL_USER_TIMES m_KERNEL_USER_TIMES[2]
void readProcStat(long pid, linux_proc &pinfo)
POOLED_USAGE_AND_LIMITS m_POOLED_USAGE_AND_LIMITS[2]
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.
IO_COUNTERS m_IO_COUNTERS[2]
Provides access to process information.
Process Virtual Memory Counters NtQueryInformationProcess using ProcessVmCounters.
PROCESS_BASIC_INFORMATION m_PROCESS_BASIC_INFORMATION[2]
Process Pooled Quota Usage and Limits NtQueryInformationProcess using ProcessPooledUsageAndLimits.
virtual ~ProcessDescriptor()
VM_COUNTERS m_VM_COUNTERS[2]
InfoType
Enumeration for fetching information.
void * ProcessHandle
Definition of the process handle.