From fb31765cbe33890f325a87015507364156741321 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:59:44 +0200 Subject: Adding upstream version 42.0. Signed-off-by: Daniel Baumann --- src/smooth_refresh.cpp | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 src/smooth_refresh.cpp (limited to 'src/smooth_refresh.cpp') diff --git a/src/smooth_refresh.cpp b/src/smooth_refresh.cpp new file mode 100644 index 0000000..45f28c1 --- /dev/null +++ b/src/smooth_refresh.cpp @@ -0,0 +1,151 @@ +/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#include + +#include + +#include +#include +#include + +#include "smooth_refresh.h" +#include "application.h" +#include "settings-keys.h" +#include "util.h" + + +const string SmoothRefresh::KEY(GSM_SETTING_SMOOTH_REFRESH); + + + +unsigned SmoothRefresh::get_own_cpu_usage() +{ + glibtop_cpu cpu; + glibtop_proc_time proctime; + guint64 elapsed; + unsigned usage = PCPU_LO; + + glibtop_get_cpu (&cpu); + elapsed = cpu.total - this->last_total_time; + + if (elapsed) { // avoid division by 0 + glibtop_get_proc_time(&proctime, getpid()); + usage = (proctime.rtime - this->last_cpu_time) * 100 / elapsed; + this->last_cpu_time = proctime.rtime; + } + + usage = CLAMP(usage, 0, 100); + + this->last_total_time = cpu.total; + + return usage; +} + +void SmoothRefresh::load_settings_value(Glib::ustring key) +{ + this->active = this->settings->get_boolean(key); + + if (this->active) + procman_debug("smooth_refresh is enabled"); +} + + +SmoothRefresh::SmoothRefresh(Glib::RefPtr a_settings) + : + settings(a_settings), + active(false), + interval(0), + last_pcpu(0), + last_total_time(0ULL), + last_cpu_time(0ULL) +{ + this->connection = a_settings->signal_changed("smooth_refresh").connect([this](const Glib::ustring& key) { this->load_settings_value(key); }); + + this->reset(); + this->load_settings_value(KEY); +} + + + +void SmoothRefresh::reset() +{ + glibtop_cpu cpu; + glibtop_proc_time proctime; + + glibtop_get_cpu(&cpu); + glibtop_get_proc_time(&proctime, getpid()); + + this->interval = GsmApplication::get()->config.update_interval; + this->last_pcpu = PCPU_LO; + this->last_total_time = cpu.total; + this->last_cpu_time = proctime.rtime; +} + + + +SmoothRefresh::~SmoothRefresh() +{ + if (this->connection) + this->connection.disconnect(); +} + + + +bool +SmoothRefresh::get(guint &new_interval) +{ + const unsigned config_interval = GsmApplication::get()->config.update_interval; + + g_assert(this->interval >= config_interval); + + if (not this->active) + return false; + + + const unsigned pcpu = this->get_own_cpu_usage(); + /* + invariant: MAX_UPDATE_INTERVAL >= interval >= config_interval >= MIN_UPDATE_INTERVAL + + i see 3 cases: + + a) interval is too big (CPU usage < 10%) + -> increase interval + + b) interval is too small (CPU usage > 10%) AND interval != config_interval + > + -> decrease interval + + c) interval is config_interval (start or interval is perfect) + + */ + + if (pcpu > PCPU_HI && this->last_pcpu > PCPU_HI) + new_interval = this->interval * 11 / 10; + else if (this->interval != config_interval && pcpu < PCPU_LO && this->last_pcpu < PCPU_LO) + new_interval = this->interval * 9 / 10; + else + new_interval = this->interval; + + new_interval = CLAMP(new_interval, config_interval, config_interval * 2); + new_interval = CLAMP(new_interval, MIN_UPDATE_INTERVAL, MAX_UPDATE_INTERVAL); + + bool changed = this->interval != new_interval; + + if (changed) + this->interval = new_interval; + + this->last_pcpu = pcpu; + + + if (changed) { + procman_debug("CPU usage is %3u%%, changed refresh_interval to %u (config %u)", + this->last_pcpu, + this->interval, + config_interval); + } + + g_assert(this->interval == new_interval); + g_assert(this->interval >= config_interval); + + return changed; +} + -- cgit v1.2.3