00001
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "CPUUsage.hpp"
00030 #include "../libH/Debug.hpp"
00031 #include "../libH/Exception.hpp"
00032 #include "../libH/UtilTime.hpp"
00033 #include <fstream>
00034 #include <iostream>
00035 #include <boost/filesystem/operations.hpp>
00036 #include <boost/filesystem/exception.hpp>
00037 #include <boost/thread/thread.hpp>
00038
00039 using namespace std;
00040 using namespace boost;
00041 using namespace boost::filesystem;
00042 using namespace H;
00043 using namespace Gizmod;
00044
00046
00048
00053 #define PROC_STAT_PATH "/proc/stat"
00054
00059 #define DEFAULT_UPDATE_DELAY 0.1f
00060
00062
00064
00066
00068
00072 CPUUsage::CPUUsage() : mThreadProc(this) {
00073 mSecsBetweenUpdates = DEFAULT_UPDATE_DELAY;
00074 mWatching = false;
00075 mThreading = false;
00076 getNumCPUs();
00077 }
00078
00082 CPUUsageInfo::CPUUsageInfo() {
00083 memset(Field, 0, sizeof(double) * CPUUSAGE_MAX);
00084 memset(Stat, 0, sizeof(double) * CPUUSAGE_MAX);
00085 Usage = 0.0;
00086 Average = 0.0;
00087 }
00088
00092 CPUUsage::~CPUUsage() {
00093 shutdown();
00094 }
00095
00099 CPUUsageInfo::~CPUUsageInfo() {
00100 }
00101
00103
00105
00110 size_t CPUUsage::getNumCPUs() {
00111 if (mCPUUsage.size() == 0) {
00112 if (!filesystem::exists(path(PROC_STAT_PATH))) {
00113 cdbg << "Can not update CPU Usage Stats!" << endl;
00114 return -1;
00115 }
00116
00117
00118 ifstream StatFile(PROC_STAT_PATH);
00119 if (!StatFile.is_open()) {
00120 cdbg << "Error Updating CPU Usage Stats!" << endl;
00121 return -1;
00122 }
00123
00124
00125 string Line;
00126 int cpus = 0;
00127 while (true) {
00128
00129 getline(StatFile, Line);
00130 if (Line.find("cpu") != 0)
00131 break;
00132 cpus ++;
00133 }
00134
00135 mCPUUsage.resize(cpus);
00136 for (int lp = 0; lp < cpus; lp ++)
00137 mCPUUsage[lp] = shared_ptr<CPUUsageInfo>(new CPUUsageInfo);
00138 }
00139
00140 return mCPUUsage.size() - 1;
00141 }
00142
00146 void CPUUsage::init() {
00147 if (getNumCPUs() < 0) {
00148 cdbg << "Cannot give CPU Usage Stats! -- Cannot access [" << PROC_STAT_PATH << "]" << endl;
00149 return;
00150 }
00151
00152
00153 thread thrd(mThreadProc);
00154 }
00155
00160 void CPUUsage::onCPUUsage(std::vector< boost::shared_ptr<CPUUsageInfo> > const & Event) {
00161
00162 }
00163
00168 void CPUUsage::setTimeBetweenUpdates(float Seconds) {
00169 mSecsBetweenUpdates = Seconds;
00170 }
00171
00175 void CPUUsage::shutdown() {
00176 mWatching = false;
00177 while (mThreading) {
00178 cdbg5 << "Waiting on CPUUsage Thread to Finish..." << endl;
00179 UtilTime::sleep(0.1f);
00180 }
00181 }
00182
00186 void CPUUsage::threadProc() {
00187
00188 mWatching = true;
00189 while (mWatching) {
00190 updateUsageStats();
00191 UtilTime::sleep(mSecsBetweenUpdates);
00192 }
00193 }
00194
00198 void CPUUsage::updateUsageStats() {
00199
00200 FILE * StatFile;
00201 if ((StatFile = fopen(PROC_STAT_PATH, "r")) == NULL) {
00202 cdbg << "Failed get CPU Usage Information" << endl;
00203 return;
00204 }
00205
00206
00207 for (size_t cpu = 0; cpu < mCPUUsage.size(); cpu ++) {
00208 double Info[CPUUSAGE_MAX];
00209 int CpuIndex = 0;
00210 shared_ptr<CPUUsageInfo> pUsage = mCPUUsage[cpu];
00211 if (cpu == 0)
00212 fscanf(StatFile, "cpu %lf %lf %lf %lf %lf %lf %lf %lf\n", Info, Info + 1, Info + 2, Info + 3, Info + 4, Info + 5, Info + 6, Info + 7);
00213 else {
00214 fscanf(StatFile, "cpu%d %lf %lf %lf %lf %lf %lf %lf %lf\n", &CpuIndex, Info, Info + 1, Info + 2, Info + 3, Info + 4, Info + 5, Info + 6, Info + 7);
00215 }
00216
00217
00218 double Total = 0.0;
00219 for (int lp = 0; lp < CPUUSAGE_MAX; lp ++) {
00220
00221 pUsage->Field[lp] = Info[lp] - pUsage->Stat[lp];
00222 Total += pUsage->Field[lp];
00223 pUsage->Stat[lp] = Info[lp];
00224 }
00225 pUsage->Usage = ((Total - pUsage->Field[CPUUSAGE_IDLE] - pUsage->Field[CPUUSAGE_IOWAIT]) / Total) * 100.0;
00226 pUsage->mAverager.push(pUsage->Usage);
00227 pUsage->Average = pUsage->mAverager.average();
00228 }
00229 fclose(StatFile);
00230
00231
00232 onCPUUsage(mCPUUsage);
00233 }