git-svn-id: svn://db.shs.com.ru/pip@513 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2017-06-21 14:00:45 +00:00
parent 6ac45691cc
commit ed1a89508a
7 changed files with 253 additions and 18 deletions

View File

@@ -36,7 +36,7 @@ public:
ullong space_used;
ullong space_free;
};
PIString ifconfigPath, execCommand, hostname, user, OS_name, OS_version, architecture;
PIDateTime execDateTime;
int processorsCount;

View File

@@ -20,6 +20,7 @@
#include "piincludes_p.h"
#include "pisystemmonitor.h"
#include "pisysteminfo.h"
#include "piprocess.h"
#include "pitime_win.h"
#ifdef WINDOWS
# include <psapi.h>
@@ -40,6 +41,7 @@ PRIVATE_DEFINITION_END(PISystemMonitor)
PISystemMonitor::PISystemMonitor(): PIThread() {
self_ = false;
pID_ = cycle = 0;
cpu_count = PISystemInfo::instance()->processorsCount;
#ifndef WINDOWS
@@ -68,8 +70,9 @@ PISystemMonitor::ProcessStats::ProcessStats() {
}
bool PISystemMonitor::startOnProcess(int pID) {
bool PISystemMonitor::startOnProcess(int pID, int interval_ms) {
stop();
self_ = false;
pID_ = pID;
#ifndef WINDOWS
file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIIODevice::ReadOnly);
@@ -87,7 +90,22 @@ bool PISystemMonitor::startOnProcess(int pID) {
}
PRIVATE->tm.reset();
#endif
return start(1000);
return start(interval_ms);
}
bool PISystemMonitor::startOnSelf(int interval_ms) {
bool ret = startOnProcess(PIProcess::currentPID(), interval_ms);
self_ = true;
return ret;
}
PIVector<PISystemMonitor::ThreadStats> PISystemMonitor::threadsStatistic() const {
mutex_.lock();
PIVector<PISystemMonitor::ThreadStats> ret = cur_tm.values();
mutex_.unlock();
return ret;
}
@@ -206,6 +224,21 @@ void PISystemMonitor::run() {
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);
last_tm = cur_tm;
gatherThreadsStats();
//PISystemTime dt = PISystemTime::fromMilliseconds(delay_);
for (PIMap<const void*, ThreadStats>::iterator i = cur_tm.begin(); i != cur_tm.end(); ++i) {
if (!last_tm.contains(i.key())) continue;
ThreadStats & ts_new(i.value());
ThreadStats & ts_old(last_tm[i.key()]);
ts_new.cpu_load_kernel = calcThreadUsage(ts_new.kernel_time, ts_old.kernel_time);
ts_new.cpu_load_user = calcThreadUsage(ts_new.user_time, ts_old.user_time);
}
lock();
cur_ts = cur_tm.values();
unlock();
makeStrings();
}
@@ -217,3 +250,37 @@ void PISystemMonitor::makeStrings() {
stat.virtual_memsize_readable.setReadableSize(stat.virtual_memsize);
stat.data_memsize_readable.setReadableSize(stat.data_memsize);
}
void PISystemMonitor::gatherThreadsStats() {
cur_ts.clear();
cur_tm.clear();
if (!self_) return;
__PIThreadCollection * pitc = __PIThreadCollection::instance();
pitc->lock();
PIVector<PIThread*> tv = pitc->threads();
piForeachC (PIThread * t, tv) {
ThreadStats ts;
ts.name = t->name();
#ifdef WINDOWS
FILETIME times[4];
PISystemTime ct = PISystemTime::current();
if (GetThreadTimes(t->handle(), &(times[0]), &(times[1]), &(times[2]), &(times[3])) == 0) {
piCout << "[PISystemMonitor] threadsInfo():: GetThreadTimes() error:" << errorString();
continue;
}
ts.created = FILETIME2PIDateTime(times[0]);
ts.work_time = ct - ts.created.toSystemTime();
ts.kernel_time = FILETIME2PISystemTime(times[2]);
ts.user_time = FILETIME2PISystemTime(times[3]);
#endif
cur_ts << ts;
cur_tm[t] = ts;
}
pitc->unlock();
}
float PISystemMonitor::calcThreadUsage(PISystemTime & t_new, PISystemTime & t_old) {
if (delay_ <= 0) return -1.;
return piClampf(100. * ((t_new - t_old).toMilliseconds() / delay_), 0.f, 100.f);}

View File

@@ -21,7 +21,7 @@
#define PISYSTEMMONITOR_H
#include "pithread.h"
#include "piprocess.h"
#include "pifile.h"
class PIP_EXPORT PISystemMonitor: public PIThread
{
@@ -53,23 +53,58 @@ public:
float cpu_load_system;
float cpu_load_user;
};
struct ThreadStats {
ThreadStats() {cpu_load_kernel = cpu_load_user = -1.f;}
PIString name;
PIDateTime created;
PISystemTime work_time;
PISystemTime kernel_time;
PISystemTime user_time;
float cpu_load_kernel;
float cpu_load_user;
/*PIString device;
PIString filesystem;
PIString label;
ullong space_all;
ullong space_used;
ullong space_free;*/
};
bool startOnProcess(int pID);
bool startOnSelf() {return startOnProcess(PIProcess::currentPID());}
bool startOnProcess(int pID, int interval_ms = 1000);
bool startOnSelf(int interval_ms = 1000);
void stop();
const ProcessStats & statistic() const {return stat;}
PIVector<ThreadStats> threadsStatistic() const;
void setStatistic(const ProcessStats & s) {stat = s; makeStrings();}
private:
void stop();
void run();
void makeStrings();
void gatherThreadsStats();
float calcThreadUsage(PISystemTime & t_new, PISystemTime & t_old);
PIFile file, filem;
ProcessStats stat;
PIVector<ThreadStats> cur_ts;
PIMap<const void*, ThreadStats> last_tm, cur_tm;
bool self_;
int pID_, page_size, cpu_count, cycle;
PRIVATE_DECLARATION
};
inline PICout operator <<(PICout s, const PISystemMonitor::ThreadStats & v) {
s.setControl(0, true);
s << "ThreadInfo(\"" << v.name << "\", created " << v.created
<< ", work " << v.work_time.toMilliseconds() << " ms"
<< ", kernel " << v.kernel_time.toMilliseconds() << " ms"
<< ", user " << v.user_time.toMilliseconds() << " ms"
/*<< ", label \"" << v.label << "\", all " << PIString::readableSize(v.space_all)
<< ", used " << PIString::readableSize(v.space_used)
<< ", free " << PIString::readableSize(v.space_free)*/ << ")\n";
s.restoreControl();
return s;
}
#endif // PISYSTEMMONITOR_H

View File

@@ -33,6 +33,8 @@
__THREAD_FUNC_RET__ thread_function(void * t) {PIThread::__thread_func__(t); return 0;}
__THREAD_FUNC_RET__ thread_function_once(void * t) {PIThread::__thread_func_once__(t); return 0;}
#define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
#define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t)
/*! \class PIThread
* \brief Thread class
@@ -84,6 +86,64 @@ end();
*/
__PIThreadCollection *__PIThreadCollection::instance() {
/*static CDCore * ret = new CDCore();
return ret;*/
return __PIThreadCollection_Initializer__::__instance__;
}
void __PIThreadCollection::registerThread(PIThread * t) {
lock();
if (!threads_.contains(t))
threads_ << t;
unlock();
}
void __PIThreadCollection::unregisterThread(PIThread * t) {
lock();
threads_.removeAll(t);
unlock();
}
PIVector<PIThread * > __PIThreadCollection::threads() const {
return threads_;
}
int __PIThreadCollection_Initializer__::count_(0);
__PIThreadCollection * __PIThreadCollection_Initializer__::__instance__(0);
__PIThreadCollection_Initializer__::__PIThreadCollection_Initializer__() {
count_++;
//piCout << "try create Core" << count_;
if (count_ > 1) return;
//piCout << "create Core";
__instance__ = new __PIThreadCollection();
}
__PIThreadCollection_Initializer__::~__PIThreadCollection_Initializer__() {
count_--;
//piCout << "try delete Core" << count_;
if (count_ > 0) return;
//piCout << "delete Core";
if (__instance__ != 0) {
delete __instance__;
__instance__ = 0;
}
}
PRIVATE_DEFINITION_START(PIThread)
#ifndef WINDOWS
pthread_t thread;
@@ -211,6 +271,7 @@ bool PIThread::startOnce() {
void PIThread::terminate() {
if (PRIVATE->thread == 0) return;
REGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
terminating = running_ = false;
tid_ = -1;
@@ -285,6 +346,11 @@ void PIThread::setPriority(PIThread::Priority prior) {
}
void * PIThread::handle() const {
return PRIVATE->thread;
}
bool PIThread::waitForFinish(int timeout_msecs) {
if (!running_) return true;
if (timeout_msecs < 0) {
@@ -327,6 +393,7 @@ void PIThread::__thread_func__(void * t) {
ct.tid_ = GetCurrentThreadId();
#endif
PIINTROSPECTION_REGISTER_THREAD(ct.tid(), ct.priority(), ct.name());
REGISTER_THREAD(&ct);
ct.running_ = true;
if (ct.lockRun) ct.mutex_.lock();
ct.begin();
@@ -368,6 +435,7 @@ void PIThread::__thread_func__(void * t) {
ct.tid_ = -1;
//cout << "thread " << t << " exiting ... " << endl;
//piCout << "pthread_exit" << (ct.__privateinitializer__.p)->thread;
UNREGISTER_THREAD(&ct);
PIINTROSPECTION_UNREGISTER_THREAD(ct.tid());
#ifndef WINDOWS
pthread_detach((ct.__privateinitializer__.p)->thread);
@@ -396,6 +464,7 @@ void PIThread::__thread_func_once__(void * t) {
ct.tid_ = GetCurrentThreadId();
#endif
PIINTROSPECTION_REGISTER_THREAD(ct.tid(), ct.priority(), ct.name());
REGISTER_THREAD(&ct);
ct.running_ = true;
ct.begin();
ct.started();
@@ -409,6 +478,7 @@ void PIThread::__thread_func_once__(void * t) {
ct.tid_ = -1;
//cout << "thread " << t << " exiting ... " << endl;
//piCout << "pthread_exit" << (ct.__privateinitializer__.p)->thread;
UNREGISTER_THREAD(&ct);
PIINTROSPECTION_UNREGISTER_THREAD(ct.tid());
#ifndef WINDOWS
pthread_detach((ct.__privateinitializer__.p)->thread);

View File

@@ -29,6 +29,33 @@
#include "pimutex.h"
#include "piobject.h"
class PIThread;
class __PIThreadCollection {
public:
static __PIThreadCollection * instance();
void registerThread(PIThread * t);
void unregisterThread(PIThread * t);
PIVector<PIThread * > threads() const;
void lock() {mutex.lock();}
void unlock() {mutex.unlock();}
private:
PIVector<PIThread * > threads_;
mutable PIMutex mutex;
};
class __PIThreadCollection_Initializer__ {
public:
__PIThreadCollection_Initializer__();
~__PIThreadCollection_Initializer__();
static int count_;
static __PIThreadCollection * __instance__;
};
static __PIThreadCollection_Initializer__ __PIThreadCollection_initializer__;
typedef void (*ThreadFunc)(void * );
class PIP_EXPORT PIThread: public PIObject
@@ -98,6 +125,8 @@ public:
//! \brief Returns thread ID
llong tid() const {return tid_;}
void * handle() const;
static void __thread_func__(void*);
static void __thread_func_once__(void*);
@@ -189,11 +218,12 @@ protected:
int delay_, policy_;
llong tid_;
void * data_;
PIMutex mutex_;
mutable PIMutex mutex_;
PITimeMeasurer tmf_, tms_, tmr_;
PIThread::Priority priority_;
ThreadFunc ret_func;
PRIVATE_DECLARATION
};
#endif // PITHREAD_H