0

I'm developing a server auditor in c++. The big problem i have here is that when I try to read the CPU usage, the first core gets calculated correctly, but the rest looks like this:

Core 0 percentage: 3.48259%

Core 1 percentage: 8200%

Core 2 percentage: 2562.12%

Core 3 percentage: -905.97%

The code i'm using is below

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>


#include <boost/foreach.hpp>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif // win32

#include <vector>
using namespace std;


void sleepcp(int milliseconds);

void sleepcp(int milliseconds) // cross-platform sleep function
{
    #ifdef WIN32
    Sleep(milliseconds);
    #else
    usleep(milliseconds * 1000);
    #endif // win32
}
string convertIntToString(int i){
    string result;
    ostringstream convert;
    convert << i;
    result = convert.str();
    return result;
}
int convertStringToInt(string s){
    return atoi(s.c_str());
}
bool is_digits(const std::string &str) {
    return std::all_of(str.begin(), str.end(), ::isdigit); // C++11
}
int getNumberOfCores(){
    ifstream cpuinfo;
    cpuinfo.open("/proc/cpuinfo",ios::in);
    string word;
    int cpucount = 0;
    if (cpuinfo.is_open()) {
        while ( cpuinfo >> word ) {
            if(word == "processor"){
                cpucount++;
            }
            }
        cpuinfo.close();
    }

    else cout << "Unable to open file"; 
    return cpucount;
}
string splitLineAt(const std::string str, int position){
    std::istringstream buf(str);
    std::istream_iterator<std::string> beg(buf), end;

    std::vector<std::string> tokens(beg, end);
    return tokens[position];
}

int getTotalTicks(string line){
    int total_ticks = convertStringToInt(splitLineAt(line,1)) +     convertStringToInt(splitLineAt(line,2)) + convertStringToInt(splitLineAt(line,3)) + convertStringToInt(splitLineAt(line,4)) + convertStringToInt(splitLineAt(line,5)) + convertStringToInt(splitLineAt(line,6)) + convertStringToInt(splitLineAt(line,7));
    return total_ticks;
}
int getWorkTicks(string line){
    int work_ticks = convertStringToInt(splitLineAt(line,1)) + convertStringToInt(splitLineAt(line,2)) + convertStringToInt(splitLineAt(line,3));
    return work_ticks;
}
int *prev_total_ticks;
int *prev_work_ticks;
double getCorePercentage(int i){

    ifstream currentUsage;
    currentUsage.open("/proc/stat",ios::in);
    string line;    
    if(currentUsage.is_open()){

        while(getline(currentUsage,line)){
            if(line.at(0) == 'c' && line.at(1) == 'p' && line.at(2) == 'u'){
                if(line.at(3) == convertIntToString(i).at(0)){
                    int total_ticks = getTotalTicks(line);
                    int work_ticks = getWorkTicks(line);                    
                    int total_over_period =  total_ticks - (prev_total_ticks[i-1]);
                    int work_over_period =   work_ticks - (prev_work_ticks[-1]);
                    cout << prev_total_ticks[i-1] << "\n";
                    cout << prev_work_ticks[i-1] << "\n";
                    prev_work_ticks[i-1] = work_ticks;
                    prev_total_ticks[i-1] = total_ticks;

                    return ((double)work_over_period / (double)total_over_period) * 100.0;
                }
            }
        }
    }
}


int main(){
    prev_total_ticks = new int[getNumberOfCores()];
    prev_work_ticks = new int[getNumberOfCores()];
    for(int i = 0; i < getNumberOfCores(); i++){
        prev_total_ticks[i] = 0;
        prev_work_ticks[i] = 0;
    }
    while (true){
        for(int i = 0; i < getNumberOfCores(); i++){
            cout << "Core "<<i<<" percentage: "<< getCorePercentage(i) << "%\n";
        }
        sleepcp(2000);
    }
    return 0;
}

The calculation in getCorePercentage is the culprit i belive, but i'm not sure.... Before when i was just checking one core at a time it worked perfectly...

Any ideas on how to fix this?

2
  • You should always provide a MCVE.
    – m.s.
    Commented Apr 15, 2015 at 10:31
  • Have you made sure getTotalTicks() doesn't overflow an int? Commented Apr 15, 2015 at 10:39

1 Answer 1

4
int work_over_period =   work_ticks - (prev_work_ticks[-1]);
                                                       ^^

I'm sure you want to say i-1 there.

1
  • 2
    Oh god, is thats the stupidest mistake i've made in a VERY long time! Commented Apr 15, 2015 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.