From 90416278e010b80ed2060fa15e32a3221a8b779e Mon Sep 17 00:00:00 2001 From: jackun Date: Sun, 2 Feb 2020 02:12:01 +0200 Subject: [PATCH] Total cpu periods --- src/cpu.cpp | 130 ++++++++++++++++++++++++++---------------------- src/cpu.h | 5 ++ src/overlay.cpp | 9 ++-- 3 files changed, 81 insertions(+), 63 deletions(-) diff --git a/src/cpu.cpp b/src/cpu.cpp index 2d8f67f..6ad559e 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -28,7 +28,71 @@ static bool starts_with(const std::string& s, const char *t){ return s.rfind(t, 0) == 0; } -std::vector coreMhz; +void calculateCPUData(CPUData& cpuData, + unsigned long long int usertime, + unsigned long long int nicetime, + unsigned long long int systemtime, + unsigned long long int idletime, + unsigned long long int ioWait, + unsigned long long int irq, + unsigned long long int softIrq, + unsigned long long int steal, + unsigned long long int guest, + unsigned long long int guestnice) +{ + // Guest time is already accounted in usertime + usertime = usertime - guest; + nicetime = nicetime - guestnice; + // Fields existing on kernels >= 2.6 + // (and RHEL's patched kernel 2.4...) + unsigned long long int idlealltime = idletime + ioWait; + unsigned long long int systemalltime = systemtime + irq + softIrq; + unsigned long long int virtalltime = guest + guestnice; + unsigned long long int totaltime = usertime + nicetime + systemalltime + idlealltime + steal + virtalltime; + + // Since we do a subtraction (usertime - guest) and cputime64_to_clock_t() + // used in /proc/stat rounds down numbers, it can lead to a case where the + // integer overflow. + #define WRAP_SUBTRACT(a,b) (a > b) ? a - b : 0 + cpuData.userPeriod = WRAP_SUBTRACT(usertime, cpuData.userTime); + cpuData.nicePeriod = WRAP_SUBTRACT(nicetime, cpuData.niceTime); + cpuData.systemPeriod = WRAP_SUBTRACT(systemtime, cpuData.systemTime); + cpuData.systemAllPeriod = WRAP_SUBTRACT(systemalltime, cpuData.systemAllTime); + cpuData.idleAllPeriod = WRAP_SUBTRACT(idlealltime, cpuData.idleAllTime); + cpuData.idlePeriod = WRAP_SUBTRACT(idletime, cpuData.idleTime); + cpuData.ioWaitPeriod = WRAP_SUBTRACT(ioWait, cpuData.ioWaitTime); + cpuData.irqPeriod = WRAP_SUBTRACT(irq, cpuData.irqTime); + cpuData.softIrqPeriod = WRAP_SUBTRACT(softIrq, cpuData.softIrqTime); + cpuData.stealPeriod = WRAP_SUBTRACT(steal, cpuData.stealTime); + cpuData.guestPeriod = WRAP_SUBTRACT(virtalltime, cpuData.guestTime); + cpuData.totalPeriod = WRAP_SUBTRACT(totaltime, cpuData.totalTime); + #undef WRAP_SUBTRACT + cpuData.userTime = usertime; + cpuData.niceTime = nicetime; + cpuData.systemTime = systemtime; + cpuData.systemAllTime = systemalltime; + cpuData.idleAllTime = idlealltime; + cpuData.idleTime = idletime; + cpuData.ioWaitTime = ioWait; + cpuData.irqTime = irq; + cpuData.softIrqTime = softIrq; + cpuData.stealTime = steal; + cpuData.guestTime = virtalltime; + cpuData.totalTime = totaltime; + + if (cpuData.totalPeriod == 0) + return; + float total = (float)cpuData.totalPeriod; + float v[4]; + v[0] = cpuData.nicePeriod * 100.0f / total; + v[1] = cpuData.userPeriod * 100.0f / total; + + /* if not detailed */ + v[2] = cpuData.systemAllPeriod * 100.0f / total; + v[3] = (cpuData.stealPeriod + cpuData.guestPeriod) * 100.0f / total; + //cpuData.percent = std::clamp(v[0]+v[1]+v[2]+v[3], 0.0f, 100.0f); + cpuData.percent = std::min(std::max(v[0]+v[1]+v[2]+v[3], 0.0f), 100.0f); +} CPUStats::CPUStats() { @@ -106,6 +170,7 @@ bool CPUStats::UpdateCPUData() } else if (!ret && sscanf(line.c_str(), "cpu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice) == 10) { ret = true; + calculateCPUData(m_cpuDataTotal, usertime, nicetime, systemtime, idletime, ioWait, irq, softIrq, steal, guest, guestnice); } else if (sscanf(line.c_str(), "cpu%4d %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice) == 11) { @@ -123,58 +188,9 @@ bool CPUStats::UpdateCPUData() } CPUData& cpuData = m_cpuData[cpuid]; - - // Guest time is already accounted in usertime - usertime = usertime - guest; - nicetime = nicetime - guestnice; - // Fields existing on kernels >= 2.6 - // (and RHEL's patched kernel 2.4...) - unsigned long long int idlealltime = idletime + ioWait; - unsigned long long int systemalltime = systemtime + irq + softIrq; - unsigned long long int virtalltime = guest + guestnice; - unsigned long long int totaltime = usertime + nicetime + systemalltime + idlealltime + steal + virtalltime; - - // Since we do a subtraction (usertime - guest) and cputime64_to_clock_t() - // used in /proc/stat rounds down numbers, it can lead to a case where the - // integer overflow. - #define WRAP_SUBTRACT(a,b) (a > b) ? a - b : 0 - cpuData.userPeriod = WRAP_SUBTRACT(usertime, cpuData.userTime); - cpuData.nicePeriod = WRAP_SUBTRACT(nicetime, cpuData.niceTime); - cpuData.systemPeriod = WRAP_SUBTRACT(systemtime, cpuData.systemTime); - cpuData.systemAllPeriod = WRAP_SUBTRACT(systemalltime, cpuData.systemAllTime); - cpuData.idleAllPeriod = WRAP_SUBTRACT(idlealltime, cpuData.idleAllTime); - cpuData.idlePeriod = WRAP_SUBTRACT(idletime, cpuData.idleTime); - cpuData.ioWaitPeriod = WRAP_SUBTRACT(ioWait, cpuData.ioWaitTime); - cpuData.irqPeriod = WRAP_SUBTRACT(irq, cpuData.irqTime); - cpuData.softIrqPeriod = WRAP_SUBTRACT(softIrq, cpuData.softIrqTime); - cpuData.stealPeriod = WRAP_SUBTRACT(steal, cpuData.stealTime); - cpuData.guestPeriod = WRAP_SUBTRACT(virtalltime, cpuData.guestTime); - cpuData.totalPeriod = WRAP_SUBTRACT(totaltime, cpuData.totalTime); - #undef WRAP_SUBTRACT - cpuData.userTime = usertime; - cpuData.niceTime = nicetime; - cpuData.systemTime = systemtime; - cpuData.systemAllTime = systemalltime; - cpuData.idleAllTime = idlealltime; - cpuData.idleTime = idletime; - cpuData.ioWaitTime = ioWait; - cpuData.irqTime = irq; - cpuData.softIrqTime = softIrq; - cpuData.stealTime = steal; - cpuData.guestTime = virtalltime; - cpuData.totalTime = totaltime; + calculateCPUData(cpuData, usertime, nicetime, systemtime, idletime, ioWait, irq, softIrq, steal, guest, guestnice); cpuid = -1; - float total = (float)(cpuData.totalPeriod == 0 ? 1 : cpuData.totalPeriod); - float v[4]; - v[0] = cpuData.nicePeriod * 100.0f / total; - v[1] = cpuData.userPeriod * 100.0f / total; - - /* if not detailed */ - v[2] = cpuData.systemAllPeriod * 100.0f / total; - v[3] = (cpuData.stealPeriod + cpuData.guestPeriod) * 100.0f / total; - cpuData.percent = std::min(std::max(v[0]+v[1]+v[2]+v[3], 0.0f), 100.0f); - } else { break; } @@ -186,22 +202,18 @@ bool CPUStats::UpdateCPUData() } bool CPUStats::UpdateCoreMhz() { - coreMhz.clear(); - FILE *cpuInfo = fopen(PROCCPUINFOFILE, "r"); - char line[256]; + m_coreMhz.clear(); + std::ifstream cpuInfo(PROCCPUINFOFILE); + std::string row; int i = 0; - while (fgets(line, sizeof(line), cpuInfo)) { + while (std::getline(cpuInfo, row)) { CPUData& cpuData = m_cpuData[i]; - std::string row; - row = line; if (row.find("MHz") != std::string::npos){ row = std::regex_replace(row, std::regex(R"([^0-9.])"), ""); cpuData.mhz = stoi(row); i++; } } - - fclose(cpuInfo); return true; } diff --git a/src/cpu.h b/src/cpu.h index c77977c..c4ab581 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -48,9 +48,14 @@ public: const std::vector& GetCPUData() const { return m_cpuData; } + const CPUData& GetCPUDataTotal() const { + return m_cpuDataTotal; + } private: unsigned long long int m_boottime = 0; std::vector m_cpuData; + CPUData m_cpuDataTotal {}; + std::vector m_coreMhz; double m_cpuPeriod = 0; bool m_updatedCPUs = false; // TODO use caching or just update? bool m_inited = false; diff --git a/src/overlay.cpp b/src/overlay.cpp index ff215ce..d78e926 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -909,12 +909,13 @@ static void snapshot_swapchain_frame(struct swapchain_data *data) if (capture_begin || elapsed >= instance_data->params.fps_sampling_period) { cpuStats.UpdateCPUData(); - int i = 0; + //int i = 0; cpuLoadLog = 0; - for (const CPUData &cpuData : cpuStats.GetCPUData()) - cpuLoadLog += cpuData.percent; + //for (const CPUData &cpuData : cpuStats.GetCPUData()) + // cpuLoadLog += cpuData.percent; - cpuLoadLog = cpuLoadLog / cpuStats.GetCPUData().size(); + //cpuLoadLog = cpuLoadLog / cpuStats.GetCPUData().size(); + cpuLoadLog = cpuStats.GetCPUDataTotal().percent; pthread_create(&cpuInfoThread, NULL, &cpuInfo, NULL); // get gpu usage