git-svn-id: svn://db.shs.com.ru/pip@400 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
219
src_main/system/pisystemmonitor.cpp
Executable file
219
src_main/system/pisystemmonitor.cpp
Executable file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Process resource monitor
|
||||
Copyright (C) 2016 Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pisystemmonitor.h"
|
||||
#include "pisysteminfo.h"
|
||||
#include "pitime_win.h"
|
||||
#ifdef WINDOWS
|
||||
# include <psapi.h>
|
||||
# include <tlhelp32.h>
|
||||
#endif
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PISystemMonitor)
|
||||
#ifndef WINDOWS
|
||||
llong cpu_u_cur, cpu_u_prev, cpu_s_cur, cpu_s_prev;
|
||||
#else
|
||||
HANDLE hProc;
|
||||
PROCESS_MEMORY_COUNTERS mem_cnt;
|
||||
PISystemTime tm_kernel, tm_user;
|
||||
PITimeMeasurer tm;
|
||||
#endif
|
||||
PRIVATE_DEFINITION_END(PISystemMonitor)
|
||||
|
||||
|
||||
PISystemMonitor::PISystemMonitor(): PIThread() {
|
||||
pID_ = cycle = 0;
|
||||
cpu_count = PISystemInfo::instance()->processorsCount;
|
||||
#ifndef WINDOWS
|
||||
# ifdef QNX
|
||||
page_size = 4096;
|
||||
# else
|
||||
page_size = getpagesize();
|
||||
# endif
|
||||
#else
|
||||
PRIVATE->hProc = 0;
|
||||
PRIVATE->mem_cnt.cb = sizeof(PRIVATE->mem_cnt);
|
||||
#endif
|
||||
setName("system_monitor");
|
||||
}
|
||||
|
||||
|
||||
PISystemMonitor::~PISystemMonitor() {
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
PISystemMonitor::ProcessStats::ProcessStats() {
|
||||
ID = parent_ID = group_ID = session_ID = priority = threads = 0;
|
||||
physical_memsize = resident_memsize = share_memsize = virtual_memsize = data_memsize = 0;
|
||||
cpu_load_user = cpu_load_system = 0.f;
|
||||
}
|
||||
|
||||
|
||||
bool PISystemMonitor::startOnProcess(int pID) {
|
||||
stop();
|
||||
pID_ = pID;
|
||||
#ifndef WINDOWS
|
||||
file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIIODevice::ReadOnly);
|
||||
filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIIODevice::ReadOnly);
|
||||
if (!file.isOpened()) {
|
||||
piCoutObj << "Can`t find process with ID = " << pID_ << "!";
|
||||
return false;
|
||||
}
|
||||
cycle = -1;
|
||||
#else
|
||||
PRIVATE->hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pID_);
|
||||
if (PRIVATE->hProc == 0) {
|
||||
piCoutObj << "Can`t open process with ID = " << pID_ << "," << errorString();
|
||||
return false;
|
||||
}
|
||||
PRIVATE->tm.reset();
|
||||
#endif
|
||||
return start(1000);
|
||||
}
|
||||
|
||||
|
||||
void PISystemMonitor::stop() {
|
||||
PIThread::stop();
|
||||
#ifdef WINDOWS
|
||||
if (PRIVATE->hProc != 0) {
|
||||
CloseHandle(PRIVATE->hProc);
|
||||
PRIVATE->hProc = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PISystemMonitor::run() {
|
||||
#ifndef WINDOWS
|
||||
file.seekToBegin();
|
||||
PIString str(file.readAll(true));
|
||||
int si = str.find('(') + 1, fi = 0, cc = 1;
|
||||
for (int i = si; i < str.size_s(); ++i) {
|
||||
if (str[i] == '(') cc++;
|
||||
if (str[i] == ')') cc--;
|
||||
if (cc <= 0) {
|
||||
fi = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
stat.exec_name = str.mid(si, fi - si);
|
||||
str.cutMid(si - 1, fi - si + 3);
|
||||
PIStringList sl = str.split(" ");
|
||||
if (sl.size_s() < 19) return;
|
||||
stat.ID = sl[0].toInt();
|
||||
stat.state = sl[1];
|
||||
stat.parent_ID = sl[2].toInt();
|
||||
stat.group_ID = sl[3].toInt();
|
||||
stat.session_ID = sl[4].toInt();
|
||||
if (cycle < 0) {
|
||||
PRIVATE->cpu_u_prev = PRIVATE->cpu_u_cur = sl[12].toLLong();
|
||||
PRIVATE->cpu_s_prev = PRIVATE->cpu_s_cur = sl[13].toLLong();
|
||||
}
|
||||
cycle++;
|
||||
//if (cycle >= 4) {
|
||||
PRIVATE->cpu_u_prev = PRIVATE->cpu_u_cur;
|
||||
PRIVATE->cpu_s_prev = PRIVATE->cpu_s_cur;
|
||||
PRIVATE->cpu_u_cur = sl[12].toLLong();
|
||||
PRIVATE->cpu_s_cur = sl[13].toLLong();
|
||||
stat.cpu_load_system = PRIVATE->cpu_s_cur - PRIVATE->cpu_s_prev;
|
||||
stat.cpu_load_user = PRIVATE->cpu_u_cur - PRIVATE->cpu_u_prev;
|
||||
stat.cpu_load_system /= cpu_count;
|
||||
stat.cpu_load_user /= cpu_count;
|
||||
cycle = 0;
|
||||
//}
|
||||
stat.priority = sl[16].toInt();
|
||||
stat.threads = sl[18].toInt();
|
||||
|
||||
filem.seekToBegin();
|
||||
str = filem.readAll(true);
|
||||
sl = str.split(" ");
|
||||
if (sl.size_s() < 6) return;
|
||||
stat.virtual_memsize = sl[0].toLong() * page_size;
|
||||
stat.resident_memsize = sl[1].toLong() * page_size;
|
||||
stat.share_memsize = sl[2].toLong() * page_size;
|
||||
stat.data_memsize = sl[5].toLong() * page_size;
|
||||
stat.physical_memsize = stat.resident_memsize - stat.share_memsize;
|
||||
#else
|
||||
stat.ID = pID_;
|
||||
// HMODULE hMod;
|
||||
// DWORD cbNeeded;
|
||||
if (GetProcessMemoryInfo(PRIVATE->hProc, &PRIVATE->mem_cnt, sizeof(PRIVATE->mem_cnt)) != 0) {
|
||||
stat.physical_memsize = PRIVATE->mem_cnt.WorkingSetSize;
|
||||
}
|
||||
stat.priority = GetPriorityClass(PRIVATE->hProc);
|
||||
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pID_);
|
||||
int thcnt = 0;
|
||||
if (snap != 0) {
|
||||
THREADENTRY32 thread;
|
||||
thread.dwSize = sizeof(THREADENTRY32);
|
||||
if (Thread32First(snap, &thread) == TRUE) {
|
||||
if (thread.th32OwnerProcessID == DWORD(pID_))
|
||||
++thcnt;
|
||||
while (Thread32Next(snap, &thread) == TRUE) {
|
||||
if (thread.th32OwnerProcessID == DWORD(pID_))
|
||||
++thcnt;
|
||||
}
|
||||
}
|
||||
stat.threads = thcnt;
|
||||
CloseHandle(snap);
|
||||
}
|
||||
FILETIME ft0, ft1, ft_kernel, ft_user;
|
||||
double el_s = PRIVATE->tm.elapsed_s() * cpu_count / 100.;
|
||||
if (GetProcessTimes(PRIVATE->hProc, &ft0, &ft1, &ft_kernel, &ft_user) != 0) {
|
||||
PISystemTime tm_kernel_c = FILETIME2PISystemTime(ft_kernel);
|
||||
PISystemTime tm_user_c = FILETIME2PISystemTime(ft_user);
|
||||
if (cycle < 0) {
|
||||
PRIVATE->tm_kernel = tm_kernel_c;
|
||||
PRIVATE->tm_user = tm_user_c;
|
||||
}
|
||||
//cycle++;
|
||||
cycle = 0;
|
||||
if (el_s <= 0.) {
|
||||
stat.cpu_load_system = 0.f;
|
||||
stat.cpu_load_user = 0.f;
|
||||
} else {
|
||||
stat.cpu_load_system = (tm_kernel_c - PRIVATE->tm_kernel).toSeconds() / el_s;
|
||||
stat.cpu_load_user = (tm_user_c - PRIVATE->tm_user).toSeconds() / el_s;
|
||||
}
|
||||
PRIVATE->tm_kernel = tm_kernel_c;
|
||||
PRIVATE->tm_user = tm_user_c;
|
||||
} else {
|
||||
stat.cpu_load_system = 0.f;
|
||||
stat.cpu_load_user = 0.f;
|
||||
}
|
||||
PRIVATE->tm.reset();
|
||||
#endif
|
||||
|
||||
stat.cpu_load_system = piClampf(stat.cpu_load_system, 0.f, 100.f);
|
||||
stat.cpu_load_user = piClampf(stat.cpu_load_user, 0.f, 100.f);
|
||||
makeStrings();
|
||||
}
|
||||
|
||||
|
||||
void PISystemMonitor::makeStrings() {
|
||||
stat.physical_memsize_readable.setReadableSize(stat.physical_memsize);
|
||||
stat.resident_memsize_readable.setReadableSize(stat.resident_memsize);
|
||||
stat.share_memsize_readable.setReadableSize(stat.share_memsize);
|
||||
stat.virtual_memsize_readable.setReadableSize(stat.virtual_memsize);
|
||||
stat.data_memsize_readable.setReadableSize(stat.data_memsize);
|
||||
}
|
||||
Reference in New Issue
Block a user