Changeset View
Changeset View
Standalone View
Standalone View
sysutils/libsysstat/files/patch-cpustat.cpp
--- cpustat.cpp.orig 2018-05-21 17:16:59 UTC | --- cpustat.cpp.orig 2019-01-24 21:43:32 UTC | ||||
+++ cpustat.cpp | +++ cpustat.cpp | ||||
@@ -25,13 +25,64 @@ | @@ -27,11 +27,62 @@ | ||||
#include <unistd.h> | #include <unistd.h> | ||||
- | |||||
#include "cpustat.h" | #include "cpustat.h" | ||||
+#ifdef HAVE_SYSCTL_H | +#ifdef HAVE_SYSCTL_H | ||||
+extern "C" | +extern "C" | ||||
+{ | +{ | ||||
+ #include <stdlib.h> | + #include <stdlib.h> | ||||
+ #include <limits.h> | + #include <limits.h> | ||||
+ #include <string.h> | + #include <string.h> | ||||
+ #include <sys/resource.h> /* CPUSTATES */ | + #include <sys/resource.h> /* CPUSTATES */ | ||||
+ | + | ||||
+ #include <sys/types.h> | + #include <sys/types.h> | ||||
+ #include <sys/sysctl.h> | + #include <sys/sysctl.h> | ||||
+} | +} | ||||
+#endif | +#endif | ||||
+ | |||||
#include "cpustat_p.h" | #include "cpustat_p.h" | ||||
namespace SysStat { | namespace SysStat { | ||||
+#ifdef HAVE_SYSCTL_H | +#ifdef HAVE_SYSCTL_H | ||||
+char *GetFirstFragment(char *string, const char *delim) | +char *GetFirstFragment(char *string, const char *delim) | ||||
+{ | +{ | ||||
+ char *token = NULL; | + char *token = NULL; | ||||
+ | |||||
+ token = strsep(&string, delim); | + token = strsep(&string, delim); | ||||
+ if (token != NULL) | + if (token != NULL) | ||||
+ { | + { | ||||
+ /* We need only the first fragment, so no loop! */ | + /* We need only the first fragment, so no loop! */ | ||||
+ return token; | + return token; | ||||
+ } | + } | ||||
+ else | + else | ||||
+ return NULL; | + return NULL; | ||||
Show All 16 Lines | |||||
+{ | +{ | ||||
+ ulong freq=0; | + ulong freq=0; | ||||
+ size_t len = sizeof(freq); | + size_t len = sizeof(freq); | ||||
+ | + | ||||
+ if (sysctlbyname("dev.cpu.0.freq", &freq, &len, NULL, 0) < 0) // man cpufreq BUGS section all cores have the same frequency. | + if (sysctlbyname("dev.cpu.0.freq", &freq, &len, NULL, 0) < 0) // man cpufreq BUGS section all cores have the same frequency. | ||||
+ return 0; | + return 0; | ||||
+ else | + else | ||||
+ return freq; | + return freq; | ||||
+ | |||||
+} | +} | ||||
+#endif | +#endif | ||||
CpuStatPrivate::CpuStatPrivate(CpuStat *parent) | CpuStatPrivate::CpuStatPrivate(CpuStat *parent) | ||||
: BaseStatPrivate(parent) | : BaseStatPrivate(parent) | ||||
, mMonitoring(CpuStat::LoadAndFrequency) | , mMonitoring(CpuStat::LoadAndFrequency) | ||||
@@ -39,7 +90,11 @@ CpuStatPrivate::CpuStatPrivate(CpuStat * | @@ -39,7 +90,11 @@ CpuStatPrivate::CpuStatPrivate(CpuStat *parent) | ||||
mSource = defaultSource(); | mSource = defaultSource(); | ||||
connect(mTimer, SIGNAL(timeout()), SLOT(timeout())); | connect(mTimer, SIGNAL(timeout()), SLOT(timeout())); | ||||
- | - | ||||
+#ifdef HAVE_SYSCTL_H | +#ifdef HAVE_SYSCTL_H | ||||
+ size_t flen=2; | + size_t flen=2; | ||||
+ sysctlnametomib("kern.cp_times",mib0,&flen); | + sysctlnametomib("kern.cp_times",mib0,&flen); | ||||
+ sysctlnametomib("kern.cp_time",mib1,&flen); | + sysctlnametomib("kern.cp_time",mib1,&flen); | ||||
+#endif | +#endif | ||||
mUserHz = sysconf(_SC_CLK_TCK); | mUserHz = sysconf(_SC_CLK_TCK); | ||||
updateSources(); | updateSources(); | ||||
@@ -47,6 +102,49 @@ CpuStatPrivate::CpuStatPrivate(CpuStat * | @@ -47,6 +102,49 @@ CpuStatPrivate::CpuStatPrivate(CpuStat *parent) | ||||
void CpuStatPrivate::addSource(const QString &source) | void CpuStatPrivate::addSource(const QString &source) | ||||
{ | { | ||||
+#ifdef HAVE_SYSCTL_H | +#ifdef HAVE_SYSCTL_H | ||||
+ char buf[1024]; | + char buf[1024]; | ||||
+ char *tokens, *t; | + char *tokens, *t; | ||||
+ ulong min = 0, max = 0; | + ulong min = 0, max = 0; | ||||
+ size_t len = sizeof(buf); | + size_t len = sizeof(buf); | ||||
+ | + | ||||
+ /* The string returned by the dev.cpu.0.freq_levels sysctl | + /* The string returned by the dev.cpu.0.freq_levels sysctl | ||||
+ * is a space separated list of MHz/milliwatts. | + * is a space separated list of MHz/milliwatts. | ||||
+ */ | + */ | ||||
+ if (sysctlbyname("dev.cpu.0.freq_levels", buf, &len, NULL, 0) < 0) | + if (sysctlbyname("dev.cpu.0.freq_levels", buf, &len, NULL, 0) < 0) | ||||
+ return; | + return; | ||||
+ | + | ||||
+ t = strndup(buf, len); | + t = strndup(buf, len); | ||||
+ if (t == NULL) | + if (t == NULL) | ||||
+ { | + { | ||||
+ free(t); | + free(t); | ||||
+ return; | + return; | ||||
+ } | + } | ||||
+ | + | ||||
+ while ((tokens = strsep(&t, " ")) != NULL) | + while ((tokens = strsep(&t, " ")) != NULL) | ||||
+ { | + { | ||||
+ char *freq; | + char *freq; | ||||
+ ulong res; | + ulong res; | ||||
+ | + | ||||
+ freq = GetFirstFragment(tokens, "/"); | + freq = GetFirstFragment(tokens, "/"); | ||||
+ if (freq != NULL) | + if (freq != NULL) | ||||
+ { | + { | ||||
+ res = strtoul(freq, &freq, 10); | + res = strtoul(freq, &freq, 10); | ||||
+ if (res > max) | + if (res > max) | ||||
+ { | + { | ||||
+ max = res; | + max = res; | ||||
+ } | + } | ||||
+ else | + else | ||||
+ { | + { | ||||
+ if ((min == 0) || (res < min)) | + if ((min == 0) || (res < min)) | ||||
+ min = res; | + min = res; | ||||
+ } | + } | ||||
+ } | + } | ||||
+ } | + } | ||||
+ | + | ||||
+ free(t); | + free(t); | ||||
+ mBounds[source] = qMakePair(min, max); | + mBounds[source] = qMakePair(min, max); | ||||
+#else | + #else | ||||
bool ok; | bool ok; | ||||
uint min = readAllFile(qPrintable(QString("/sys/devices/system/cpu/%1/cpufreq/scaling_min_freq").arg(source))).toUInt(&ok); | uint min = readAllFile(qPrintable(QString::fromLatin1("/sys/devices/system/cpu/%1/cpufreq/scaling_min_freq").arg(source))).toUInt(&ok); | ||||
@@ -56,12 +154,27 @@ void CpuStatPrivate::addSource(const QSt | @@ -56,12 +154,27 @@ void CpuStatPrivate::addSource(const QString &source) | ||||
if (ok) | if (ok) | ||||
mBounds[source] = qMakePair(min, max); | mBounds[source] = qMakePair(min, max); | ||||
} | } | ||||
+#endif | +#endif | ||||
} | } | ||||
void CpuStatPrivate::updateSources() | void CpuStatPrivate::updateSources() | ||||
{ | { | ||||
mSources.clear(); | mSources.clear(); | ||||
+#ifdef HAVE_SYSCTL_H | +#ifdef HAVE_SYSCTL_H | ||||
+ mBounds.clear(); | + mBounds.clear(); | ||||
+ int cpu; | + int cpu; | ||||
+ | |||||
+ cpu = GetCpu(); | + cpu = GetCpu(); | ||||
+ mSources.append("cpu"); // Linux has cpu in /proc/stat | + mSources.append(QStringLiteral("cpu")); // Linux has cpu in /proc/stat | ||||
+ for (int i =0;i<cpu;i++) | + for (int i =0;i<cpu;i++) | ||||
+ { | + { | ||||
+ mSources.append(QString("cpu%1").arg(i)); | + mSources.append(QString::fromLatin1("cpu%1").arg(i)); | ||||
+ | + | ||||
+ | + | ||||
+ | |||||
+ addSource(QString("cpu%1").arg(i)); | + addSource(QString::fromLatin1("cpu%1").arg(i)); | ||||
+ } | + } | ||||
+#else | +#else | ||||
const QStringList rows = readAllFile("/proc/stat").split(QChar('\n'), QString::SkipEmptyParts); | const QStringList rows = readAllFile("/proc/stat").split(QLatin1Char('\n'), QString::SkipEmptyParts); | ||||
for (const QString &row : rows) | for (const QString &row : rows) | ||||
{ | { | ||||
@@ -99,6 +212,7 @@ void CpuStatPrivate::updateSources() | @@ -99,6 +212,7 @@ void CpuStatPrivate::updateSources() | ||||
addSource(QString("cpu%1").arg(number)); | addSource(QString::fromLatin1("cpu%1").arg(number)); | ||||
} | } | ||||
} | } | ||||
+#endif | +#endif | ||||
} | } | ||||
CpuStatPrivate::~CpuStatPrivate() | CpuStatPrivate::~CpuStatPrivate() | ||||
@@ -127,6 +241,88 @@ void CpuStatPrivate::recalculateMinMax() | @@ -127,6 +241,88 @@ void CpuStatPrivate::recalculateMinMax() | ||||
void CpuStatPrivate::timeout() | void CpuStatPrivate::timeout() | ||||
{ | { | ||||
+#ifdef HAVE_SYSCTL_H | +#ifdef HAVE_SYSCTL_H | ||||
+ if ( (mMonitoring == CpuStat::LoadOnly) | + if ( (mMonitoring == CpuStat::LoadOnly) | ||||
+ || (mMonitoring == CpuStat::LoadAndFrequency) ) | + || (mMonitoring == CpuStat::LoadAndFrequency) ) | ||||
+ { | + { | ||||
+ int cpuNumber=0; | + int cpuNumber=0; | ||||
+ long *cp_times=0; | + long *cp_times=0; | ||||
+ if(mSource!="cpu") { | + if(mSource!=QLatin1String("cpu")) { | ||||
+ size_t cp_size = sizeof(long) * CPUSTATES * GetCpu(); | + size_t cp_size = sizeof(long) * CPUSTATES * GetCpu(); | ||||
+ cp_times = (long *)malloc(cp_size); | + cp_times = (long *)malloc(cp_size); | ||||
+ cpuNumber = mSource.midRef(3).toInt(); | + cpuNumber = mSource.midRef(3).toInt(); | ||||
+ if (sysctl(mib0,2, cp_times, &cp_size, NULL, 0) < 0) | + if (sysctl(mib0,2, cp_times, &cp_size, NULL, 0) < 0) | ||||
+ free(cp_times); | + free(cp_times); | ||||
+ } else { | + } else { | ||||
+ size_t cp_size = sizeof(long)*CPUSTATES; | + size_t cp_size = sizeof(long)*CPUSTATES; | ||||
+ cp_times = (long *)malloc(cp_size); | + cp_times = (long *)malloc(cp_size); | ||||
+ if(sysctl(mib1,2,cp_times,&cp_size,NULL,0) < 0) | + if(sysctl(mib1,2,cp_times,&cp_size,NULL,0) < 0) | ||||
+ free(cp_times); | + free(cp_times); | ||||
+ } | + } | ||||
+ Values current; | + Values current; | ||||
+ current.user = static_cast<ulong>(cp_times[CP_USER+cpuNumber*CPUSTATES]); | + current.user = static_cast<ulong>(cp_times[CP_USER+cpuNumber*CPUSTATES]); | ||||
+ current.nice = static_cast<ulong>(cp_times[CP_NICE+cpuNumber*CPUSTATES]); | + current.nice = static_cast<ulong>(cp_times[CP_NICE+cpuNumber*CPUSTATES]); | ||||
+ current.system = static_cast<ulong>(cp_times[CP_SYS+cpuNumber*CPUSTATES]); | + current.system = static_cast<ulong>(cp_times[CP_SYS+cpuNumber*CPUSTATES]); | ||||
+ current.idle = static_cast<ulong>(cp_times[CP_IDLE+cpuNumber*CPUSTATES]); | + current.idle = static_cast<ulong>(cp_times[CP_IDLE+cpuNumber*CPUSTATES]); | ||||
+ current.other = static_cast<ulong>(cp_times[CP_INTR+cpuNumber*CPUSTATES]); | + current.other = static_cast<ulong>(cp_times[CP_INTR+cpuNumber*CPUSTATES]); | ||||
+ current.total = current.user + current.nice + current.system+current.idle+current.other; | + current.total = current.user + current.nice + current.system+current.idle+current.other; | ||||
+ | + | ||||
+ float sumDelta = static_cast<float>(current.total - mPrevious.total); | + float sumDelta = static_cast<float>(current.total - mPrevious.total); | ||||
+ | + | ||||
+ if ((mPrevious.total != 0) && ((sumDelta < mIntervalMin) || (sumDelta > mIntervalMax))) | + if ((mPrevious.total != 0) && ((sumDelta < mIntervalMin) || (sumDelta > mIntervalMax))) | ||||
+ { | + { | ||||
+ if (mMonitoring == CpuStat::LoadAndFrequency) | + if (mMonitoring == CpuStat::LoadAndFrequency) | ||||
+ emit update(0.0, 0.0, 0.0, 0.0, 0.0, 0); | + emit update(0.0, 0.0, 0.0, 0.0, 0.0, 0); | ||||
+ else | + else | ||||
+ emit update(0.0, 0.0, 0.0, 0.0); | + emit update(0.0, 0.0, 0.0, 0.0); | ||||
+ | + | ||||
+ mPrevious.clear(); | + mPrevious.clear(); | ||||
+ } | + } | ||||
+ else | + else | ||||
+ { | + { | ||||
+ if (mMonitoring == CpuStat::LoadAndFrequency) | + if (mMonitoring == CpuStat::LoadAndFrequency) | ||||
+ { | + { | ||||
+ float freqRate = 1.0; | + float freqRate = 1.0; | ||||
+ ulong freq = CurrentFreq(); | + ulong freq = CurrentFreq(); | ||||
+ if (freq > 0) | + if (freq > 0) | ||||
+ { | + { | ||||
+ if(mSource=="cpu") | + if(mSource==QLatin1String("cpu")) | ||||
+ freqRate = static_cast<float>(freq) / static_cast<float>(mBounds[QStringLiteral("cpu0")].second);// use max cpu0 for this case | + freqRate = static_cast<float>(freq) / static_cast<float>(mBounds[QStringLiteral("cpu0")].second);// use max cpu0 for this case | ||||
+ else | + else | ||||
+ freqRate = static_cast<float>(freq) / static_cast<float>(mBounds[mSource].second); | + freqRate = static_cast<float>(freq) / static_cast<float>(mBounds[mSource].second); | ||||
+ emit update( | + emit update( | ||||
+ static_cast<float>(current.user - mPrevious.user ) / sumDelta, | + static_cast<float>(current.user - mPrevious.user ) / sumDelta, | ||||
+ static_cast<float>(current.nice - mPrevious.nice ) / sumDelta, | + static_cast<float>(current.nice - mPrevious.nice ) / sumDelta, | ||||
+ static_cast<float>(current.system - mPrevious.system) / sumDelta, | + static_cast<float>(current.system - mPrevious.system) / sumDelta, | ||||
+ static_cast<float>(current.other - mPrevious.other ) / sumDelta, | + static_cast<float>(current.other - mPrevious.other ) / sumDelta, | ||||
+ static_cast<float>(freqRate), | + static_cast<float>(freqRate), | ||||
+ freq); | + freq); | ||||
+ } | + } | ||||
+ } | + } | ||||
+ else | + else | ||||
+ { | + { | ||||
+ emit update( | + emit update( | ||||
+ static_cast<float>(current.user - mPrevious.user ) / sumDelta, | + static_cast<float>(current.user - mPrevious.user ) / sumDelta, | ||||
+ static_cast<float>(current.nice - mPrevious.nice ) / sumDelta, | + static_cast<float>(current.nice - mPrevious.nice ) / sumDelta, | ||||
+ static_cast<float>(current.system - mPrevious.system) / sumDelta, | + static_cast<float>(current.system - mPrevious.system) / sumDelta, | ||||
+ static_cast<float>(current.other - mPrevious.other ) / sumDelta); | + static_cast<float>(current.other - mPrevious.other ) / sumDelta); | ||||
+ } | + } | ||||
+ | + | ||||
+ | + | ||||
+ mPrevious = current; | + mPrevious = current; | ||||
+ } | + } | ||||
+ | + | ||||
+ free(cp_times); | + free(cp_times); | ||||
+ } | + } | ||||
+ else | + else | ||||
+ { | + { | ||||
+ ulong freq = 0; | + ulong freq = 0; | ||||
+ | + | ||||
+ freq = CurrentFreq(); | + freq = CurrentFreq(); | ||||
+ if (freq > 0) | + if (freq > 0) | ||||
+ emit update(freq); | + emit update(freq); | ||||
+ } | + } | ||||
+#else | +#else | ||||
if ( (mMonitoring == CpuStat::LoadOnly) | if ( (mMonitoring == CpuStat::LoadOnly) | ||||
|| (mMonitoring == CpuStat::LoadAndFrequency) ) | || (mMonitoring == CpuStat::LoadAndFrequency) ) | ||||
{ | { | ||||
@@ -261,6 +457,7 @@ void CpuStatPrivate::timeout() | @@ -261,6 +457,7 @@ void CpuStatPrivate::timeout() | ||||
} | } | ||||
emit update(freq); | emit update(freq); | ||||
} | } | ||||
+#endif | +#endif | ||||
} | } | ||||
QString CpuStatPrivate::defaultSource() | QString CpuStatPrivate::defaultSource() |