From 58af5dce791e731c0ee095ffd9f6842e226ca5be Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 24 Dec 2021 10:36:18 +0100 Subject: [PATCH] ActivityMonitor: add CPU speed graph MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The info is now available in cpu_info, we should do something with it. Change-Id: Iac7bd697783d63b5c84c7da33770b3c9a7d417b4 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4832 Reviewed-by: Kacper Kasper Reviewed-by: Axel Dörfler Tested-by: Commit checker robot --- src/apps/activitymonitor/ActivityWindow.cpp | 3 + src/apps/activitymonitor/DataSource.cpp | 146 +++++++++++++++++++- src/apps/activitymonitor/DataSource.h | 30 ++++ src/apps/activitymonitor/SystemInfo.h | 2 + 4 files changed, 180 insertions(+), 1 deletion(-) diff --git a/src/apps/activitymonitor/ActivityWindow.cpp b/src/apps/activitymonitor/ActivityWindow.cpp index 6b64ff40e5..cd659ce7aa 100644 --- a/src/apps/activitymonitor/ActivityWindow.cpp +++ b/src/apps/activitymonitor/ActivityWindow.cpp @@ -373,6 +373,9 @@ ActivityWindow::_AddDefaultView() view->AddDataSource(new NetworkUsageDataSource(true)); view->AddDataSource(new NetworkUsageDataSource(false)); break; + case 3: + view->AddDataSource(new CPUFrequencyDataSource()); + break; case 1: default: // Everything beyond that defaults to a CPU usage view diff --git a/src/apps/activitymonitor/DataSource.cpp b/src/apps/activitymonitor/DataSource.cpp index 9c5116fdf4..08dec6768b 100644 --- a/src/apps/activitymonitor/DataSource.cpp +++ b/src/apps/activitymonitor/DataSource.cpp @@ -25,6 +25,7 @@ const DataSource* kSources[] = { new CachedMemoryDataSource(), new SwapSpaceDataSource(), new PageFaultsDataSource(), + new CPUFrequencyDataSource(), new CPUUsageDataSource(), new CPUCombinedUsageDataSource(), new NetworkUsageDataSource(true), @@ -810,6 +811,149 @@ RunningAppsDataSource::AdaptiveScale() const // #pragma mark - +CPUFrequencyDataSource::CPUFrequencyDataSource(int32 cpu) +{ + fMinimum = 0; + fMaximum = 1000000000ll; + // Maximum initially set at 1GHz, will be automatically raised if the actual frequency gets + // higher than that + + _SetCPU(cpu); +} + + +CPUFrequencyDataSource::CPUFrequencyDataSource(const CPUFrequencyDataSource& other) + : DataSource(other) +{ + fCPU = other.fCPU; + fLabel = other.fLabel; + fShortLabel = other.fShortLabel; +} + + +CPUFrequencyDataSource::~CPUFrequencyDataSource() +{ +} + + +DataSource* +CPUFrequencyDataSource::Copy() const +{ + return new CPUFrequencyDataSource(*this); +} + + +DataSource* +CPUFrequencyDataSource::CopyForCPU(int32 cpu) const +{ + CPUFrequencyDataSource* copy = new CPUFrequencyDataSource(*this); + copy->_SetCPU(cpu); + + return copy; +} + + +void +CPUFrequencyDataSource::Print(BString& text, int64 value) const +{ + text.SetToFormat("%" PRId64 " MHz", value / 1000000); +} + + +int64 +CPUFrequencyDataSource::NextValue(SystemInfo& info) +{ + int64 value = info.CPUCurrentFrequency(fCPU); + + if (value > fMaximum) + SetLimits(0, value); + + return value; +} + + +const char* +CPUFrequencyDataSource::Label() const +{ + return fLabel.String(); +} + + +const char* +CPUFrequencyDataSource::ShortLabel() const +{ + return fShortLabel.String(); +} + + +const char* +CPUFrequencyDataSource::InternalName() const +{ + return "CPU speed"; +} + + +const char* +CPUFrequencyDataSource::Name() const +{ + return B_TRANSLATE("CPU speed"); +} + + +int32 +CPUFrequencyDataSource::CPU() const +{ + return fCPU; +} + + +bool +CPUFrequencyDataSource::PerCPU() const +{ + return true; +} + + +bool +CPUFrequencyDataSource::Primary() const +{ + return true; +} + + +void +CPUFrequencyDataSource::_SetCPU(int32 cpu) +{ + fCPU = cpu; + + if (SystemInfo().CPUCount() > 1) { + fLabel.SetToFormat(B_TRANSLATE("CPU %d speed"), cpu + 1); + fShortLabel.SetToFormat(B_TRANSLATE("CPU %d"), cpu + 1); + } else { + fLabel = B_TRANSLATE("CPU usage"); + fShortLabel = B_TRANSLATE("CPU"); + } + + const rgb_color kColors[] = { + // TODO: find some better defaults... + {200, 0, 200}, + {0, 200, 200}, + {80, 80, 80}, + {230, 150, 50}, + {255, 0, 0}, + {0, 255, 0}, + {0, 0, 255}, + {0, 150, 230} + }; + const uint32 kNumColors = B_COUNT_OF(kColors); + + fColor = kColors[cpu % kNumColors]; +} + + +// #pragma mark - + + CPUUsageDataSource::CPUUsageDataSource(int32 cpu) : fPreviousActive(0), @@ -958,7 +1102,7 @@ CPUUsageDataSource::_SetCPU(int32 cpu) {0, 0, 255}, {0, 150, 230} }; - const uint32 kNumColors = sizeof(kColors) / sizeof(kColors[0]); + const uint32 kNumColors = B_COUNT_OF(kColors); fColor = kColors[cpu % kNumColors]; } diff --git a/src/apps/activitymonitor/DataSource.h b/src/apps/activitymonitor/DataSource.h index 8698b34dc1..c77adfaa2f 100644 --- a/src/apps/activitymonitor/DataSource.h +++ b/src/apps/activitymonitor/DataSource.h @@ -263,6 +263,36 @@ private: }; +class CPUFrequencyDataSource : public DataSource { +public: + CPUFrequencyDataSource(int32 cpu = 0); + CPUFrequencyDataSource(const CPUFrequencyDataSource& other); + virtual ~CPUFrequencyDataSource(); + + virtual DataSource* Copy() const; + virtual DataSource* CopyForCPU(int32 cpu) const; + + virtual void Print(BString& text, int64 value) const; + virtual int64 NextValue(SystemInfo& info); + + virtual const char* InternalName() const; + virtual const char* Name() const; + virtual const char* Label() const; + virtual const char* ShortLabel() const; + + virtual int32 CPU() const; + virtual bool PerCPU() const; + virtual bool Primary() const; + +private: + void _SetCPU(int32 cpu); + + int32 fCPU; + BString fLabel; + BString fShortLabel; +}; + + class PageFaultsDataSource : public DataSource { public: PageFaultsDataSource(); diff --git a/src/apps/activitymonitor/SystemInfo.h b/src/apps/activitymonitor/SystemInfo.h index 065eb234bd..25778392ad 100644 --- a/src/apps/activitymonitor/SystemInfo.h +++ b/src/apps/activitymonitor/SystemInfo.h @@ -45,6 +45,8 @@ public: uint32 CPUCount() const { return fSystemInfo.cpu_count; } bigtime_t CPUActiveTime(uint32 cpu) const { return fCPUInfos[cpu].active_time; } + uint64 CPUCurrentFrequency(uint32 cpu) const + { return fCPUInfos[cpu].current_frequency; } const system_info& Info() const { return fSystemInfo; } uint64 NetworkReceived();