From f929d83f372472fee824ac156a59019240454430 Mon Sep 17 00:00:00 2001 From: Mike Massonnet Date: Mon, 24 May 2010 19:08:57 +0200 Subject: [PATCH] =?UTF-8?q?[linux|solaris]=20Fix=20regression=20introduced?= =?UTF-8?q?=20with=20the=20=E2=80=9CRefresh=20rate=E2=80=9D=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CPU usage computation done for the processes were broken when the refresh rate was different than a second. The introduced fix is only necessary for the Linux and OpenSolaris implementations. --- src/task-manager-linux.c | 34 +++++++++++++++++----------------- src/task-manager-solaris.c | 24 +++++++++++++++++------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/task-manager-linux.c b/src/task-manager-linux.c index e20356b..0c8204a 100644 --- a/src/task-manager-linux.c +++ b/src/task-manager-linux.c @@ -20,6 +20,7 @@ #include "task-manager.h" static gushort _cpu_count = 0; +static gulong jiffies_total_delta = 0; gboolean get_memory_usage (guint64 *memory_total, guint64 *memory_free, guint64 *memory_cache, guint64 *memory_buffers, guint64 *swap_total, guint64 *swap_free) @@ -59,9 +60,8 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) FILE *file; gchar *filename = "/proc/stat"; gchar buffer[1024]; - static gulong cur_jiffies_user = 0, old_jiffies_user = 0; - static gulong cur_jiffies_system = 0, old_jiffies_system = 0; - static gulong cur_jiffies = 0, old_jiffies = 0; + static gulong jiffies_user = 0, jiffies_system = 0, jiffies_total = 0; + static gulong jiffies_user_old = 0, jiffies_system_old = 0, jiffies_total_old = 0; gulong user, user_nice, system, idle; if ((file = fopen (filename, "r")) == NULL) @@ -72,7 +72,6 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) if (_cpu_count == 0) { - _cpu_count = 0; while (fgets (buffer, 1024, file) != NULL) { if (buffer[0] != 'c' && buffer[1] != 'p' && buffer[2] != 'u') @@ -80,24 +79,25 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) _cpu_count += 1; } if (_cpu_count == 0) - _cpu_count += 1; + _cpu_count = 1; } fclose (file); - old_jiffies_user = cur_jiffies_user; - old_jiffies_system = cur_jiffies_system; - old_jiffies = cur_jiffies; + jiffies_user_old = jiffies_user; + jiffies_system_old = jiffies_system; + jiffies_total_old = jiffies_total; - cur_jiffies_user = user + user_nice; - cur_jiffies_system = system; - cur_jiffies = cur_jiffies_user + cur_jiffies_system + idle; + jiffies_user = user + user_nice; + jiffies_system = system; + jiffies_total = jiffies_user + jiffies_system + idle; *cpu_user = *cpu_system = 0.0; - if (cur_jiffies > old_jiffies) + if (jiffies_total > jiffies_total_old) { - *cpu_user = (cur_jiffies_user - old_jiffies_user) * 100 / (gdouble)(cur_jiffies - old_jiffies); - *cpu_system = (cur_jiffies_system - old_jiffies_system) * 100 / (gdouble)(cur_jiffies - old_jiffies); + jiffies_total_delta = jiffies_total - jiffies_total_old; + *cpu_user = (jiffies_user - jiffies_user_old) * 100 / (gdouble)(jiffies_total_delta); + *cpu_system = (jiffies_system - jiffies_system_old) * 100 / (gdouble)(jiffies_total_delta); } *cpu_count = _cpu_count; @@ -170,10 +170,10 @@ get_cpu_percent (guint pid, gulong jiffies_user, gfloat *cpu_user, gulong jiffie if (jiffies_user < jiffies_user_old || jiffies_system < jiffies_system_old) return; - if (_cpu_count > 0) + if (_cpu_count > 0 && jiffies_total_delta > 0) { - *cpu_user = (jiffies_user_old > 0) ? (jiffies_user - jiffies_user_old) / (gfloat)_cpu_count : 0; - *cpu_system = (jiffies_system_old > 0) ? (jiffies_system - jiffies_system_old) / (gfloat)_cpu_count : 0; + *cpu_user = (jiffies_user - jiffies_user_old) * 100 / (gdouble)jiffies_total_delta; + *cpu_system = (jiffies_system - jiffies_system_old) * 100 / (gdouble)jiffies_total_delta; } else { diff --git a/src/task-manager-solaris.c b/src/task-manager-solaris.c index dfea945..dc10232 100644 --- a/src/task-manager-solaris.c +++ b/src/task-manager-solaris.c @@ -25,6 +25,7 @@ static kstat_ctl_t *kc; static gushort _cpu_count = 0; +static gulong ticks_total_delta = 0; static void init_stats () @@ -107,10 +108,10 @@ get_cpu_percent (guint pid, gulong ticks_user, gfloat *cpu_user, gulong ticks_sy if (ticks_user < ticks_user_old || ticks_system < ticks_system_old) return; - if (_cpu_count > 0) + if (_cpu_count > 0 && ticks_total_delta > 0) { - *cpu_user = (ticks_user_old > 0) ? (ticks_user - ticks_user_old) / (gfloat)_cpu_count : 0; - *cpu_system = (ticks_system_old > 0) ? (ticks_system - ticks_system_old) / (gfloat)_cpu_count : 0; + *cpu_user = (ticks_user - ticks_user_old) * 100 / (gdouble)ticks_total_delta; + *cpu_system = (ticks_system - ticks_system_old) * 100 / (gdouble)ticks_total_delta; } else { @@ -123,6 +124,7 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) { kstat_t *ksp; kstat_named_t *knp; + static gulong ticks_total = 0, ticks_total_old = 0; gulong ticks_user = 0, ticks_system = 0; if (!kc) @@ -131,6 +133,9 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) _cpu_count = 0; kstat_chain_update (kc); + ticks_total_old = ticks_total; + ticks_total = 0; + for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) { if (!g_strcmp0 (ksp->ks_module, "cpu_info")) @@ -144,12 +149,18 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) ticks_user += knp->value.ul / 100000; knp = kstat_data_lookup (ksp, "cpu_nsec_kernel"); ticks_system += knp->value.ul / 100000; + knp = kstat_data_lookup (ksp, "cpu_nsec_intr"); + ticks_system += knp->value.ul / 100000; + knp = kstat_data_lookup (ksp, "cpu_nsec_idle"); + ticks_total += knp->value.ul / 100000; + ticks_total += ticks_user + ticks_system; } } + if (ticks_total > ticks_total_old) + ticks_total_delta = ticks_total - ticks_total_old; + get_cpu_percent (0, ticks_user, cpu_user, ticks_system, cpu_system); - *cpu_user /= 100.0; - *cpu_system /= 100.0; *cpu_count = _cpu_count; return TRUE; @@ -185,8 +196,7 @@ get_task_details (guint pid, Task *task) pw = getpwuid (process.pr_uid); task->uid = (guint)process.pr_uid; g_strlcpy (task->uid_name, (pw != NULL) ? pw->pw_name : "nobody", sizeof (task->uid_name)); - get_cpu_percent (task->pid, process.pr_time.tv_sec * 100000 + process.pr_time.tv_nsec / 1000, &task->cpu_user, 0, &task->cpu_system); - task->cpu_user /= 10000; + get_cpu_percent (task->pid, process.pr_time.tv_sec * 1000 + process.pr_time.tv_nsec / 100000, &task->cpu_user, 0, &task->cpu_system); fclose (file);