From 51175189c6d7313a3b84019e39496f957c4e6164 Mon Sep 17 00:00:00 2001 From: Stefano Karapetsas Date: Sun, 11 Dec 2011 12:55:19 +0100 Subject: moved from Mate-Extra --- src/gpm-load.c | 282 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 src/gpm-load.c (limited to 'src/gpm-load.c') diff --git a/src/gpm-load.c b/src/gpm-load.c new file mode 100644 index 0000000..eab0129 --- /dev/null +++ b/src/gpm-load.c @@ -0,0 +1,282 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include +#if defined(sun) && defined(__SVR4) +#include +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ + +#include + +#include "gpm-common.h" +#include "gpm-marshal.h" +#include "egg-debug.h" + +#include "gpm-load.h" + +static void gpm_load_finalize (GObject *object); + +#define GPM_LOAD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_LOAD, GpmLoadPrivate)) + +struct GpmLoadPrivate +{ + long unsigned old_idle; + long unsigned old_total; +}; + +static gpointer gpm_load_object = NULL; + +G_DEFINE_TYPE (GpmLoad, gpm_load, G_TYPE_OBJECT) + +/** + * gpm_load_class_init: + * @klass: This class instance + **/ +static void +gpm_load_class_init (GpmLoadClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = gpm_load_finalize; + g_type_class_add_private (klass, sizeof (GpmLoadPrivate)); +} + +#if defined(sun) && defined(__SVR4) + +/** + * gpm_load_get_cpu_values: + * @cpu_idle: The idle time reported by the CPU + * @cpu_total: The total time reported by the CPU + * Return value: Success of reading /proc/stat. + **/ +static gboolean +gpm_load_get_cpu_values (long unsigned *cpu_idle, long unsigned *cpu_total) +{ + long unsigned cpu_user = 0; + long unsigned cpu_kernel = 0; + long unsigned cpu_wait = 0; + kstat_ctl_t *kc = NULL; + kstat_named_t *kn = NULL; + kstat_t *ks = NULL; + cpu_stat_t data; + int ncpus; + int count; + + kc = kstat_open(); + if (!kc) { + egg_warning ("Cannot open kstat!\n"); + return FALSE; + } + + ks = kstat_lookup(kc, "unix", 0, "system_misc"); + if (kstat_read(kc, ks, NULL) == -1) { + egg_warning ("Cannot read kstat on module unix!\n"); + goto out; + } + kn = kstat_data_lookup (ks, "ncpus"); + if (!kn) { + egg_warning ("Cannot get number of cpus in current system!\n"); + goto out; + } + ncpus = kn->value.ui32; + + /* + * To aggresive ticks used of all cpus, + * traverse kstat chain to access very cpu_stat instane. + */ + for(count = 0, *cpu_idle =0, *cpu_total = 0; count < ncpus; count++){ + + ks = kstat_lookup(kc, "cpu_stat", count, NULL); + if (ks == NULL) { + egg_warning ("Null output for kstat on cpu%d\n", count); + goto out; + } + + if (kstat_read(kc, ks, &data) == -1) { + egg_warning ("Cannot read kstat entry on cpu%d\n", count); + goto out; + } + + egg_debug ("cpu%d:\t%lu\t%lu\t%lu\t%lu\n", count, + data.cpu_sysinfo.cpu[CPU_IDLE], + data.cpu_sysinfo.cpu[CPU_USER], + data.cpu_sysinfo.cpu[CPU_KERNEL], + data.cpu_sysinfo.cpu[CPU_WAIT]); + + *cpu_idle += data.cpu_sysinfo.cpu[CPU_IDLE]; + cpu_user += data.cpu_sysinfo.cpu[CPU_USER]; + cpu_kernel += data.cpu_sysinfo.cpu[CPU_KERNEL]; + cpu_wait += data.cpu_sysinfo.cpu[CPU_WAIT]; + } + kstat_close(kc); + /* + * Summing up all these times gives you the system uptime. + * This is what the uptime command does. + */ + *cpu_total = cpu_user + cpu_kernel + cpu_wait + *cpu_idle; + return TRUE; + +out: + kstat_close(kc); + return FALSE; +} + +#else + +/** + * gpm_load_get_cpu_values: + * @cpu_idle: The idle time reported by the CPU + * @cpu_total: The total time reported by the CPU + * Return value: Success of reading /proc/stat. + **/ +static gboolean +gpm_load_get_cpu_values (long unsigned *cpu_idle, long unsigned *cpu_total) +{ + long unsigned cpu_user; + long unsigned cpu_nice; + long unsigned cpu_system; + int len; + char tmp[5]; + char str[80]; + FILE *fd; + char *suc; + gboolean ret = FALSE; + + /* open file */ + fd = fopen("/proc/stat", "r"); + if (!fd) + goto out; + + /* get data */ + suc = fgets (str, 80, fd); + if (suc == NULL) + goto out; + + /* parse */ + len = sscanf (str, "%s %lu %lu %lu %lu", tmp, + &cpu_user, &cpu_nice, &cpu_system, cpu_idle); + if (len != 5) + goto out; + + /* summing up all these times gives you the system uptime in jiffies */ + *cpu_total = cpu_user + cpu_nice + cpu_system + *cpu_idle; + ret = TRUE; +out: + if (!fd) + fclose (fd); + return ret; +} +#endif /* sun & __SVR4 */ + +/** + * gpm_load_get_current: + * @load: This class instance + * Return value: The CPU idle load + **/ +gdouble +gpm_load_get_current (GpmLoad *load) +{ + double percentage_load; + long unsigned cpu_idle; + long unsigned cpu_total; + long unsigned diff_idle; + long unsigned diff_total; + gboolean ret; + + /* work out the differences */ + ret = gpm_load_get_cpu_values (&cpu_idle, &cpu_total); + if (!ret) + return 0.0; + + diff_idle = cpu_idle - load->priv->old_idle; + diff_total = cpu_total - load->priv->old_total; + + /* If we divide the total time by idle time we get the load. */ + if (diff_idle > 0) + percentage_load = (double) diff_total / (double) diff_idle; + else + percentage_load = 100; + + load->priv->old_idle = cpu_idle; + load->priv->old_total = cpu_total; + + return percentage_load; +} + +/** + * gpm_load_init: + */ +static void +gpm_load_init (GpmLoad *load) +{ + load->priv = GPM_LOAD_GET_PRIVATE (load); + + load->priv->old_idle = 0; + load->priv->old_total = 0; + + /* we have to populate the values at startup */ + gpm_load_get_cpu_values (&load->priv->old_idle, &load->priv->old_total); +} + +/** + * gpm_load_coldplug: + * + * @object: This load instance + */ +static void +gpm_load_finalize (GObject *object) +{ + GpmLoad *load; + g_return_if_fail (object != NULL); + g_return_if_fail (GPM_IS_LOAD (object)); + load = GPM_LOAD (object); + g_return_if_fail (load->priv != NULL); + G_OBJECT_CLASS (gpm_load_parent_class)->finalize (object); +} + +/** + * gpm_load_new: + * Return value: new GpmLoad instance. + **/ +GpmLoad * +gpm_load_new (void) +{ + if (gpm_load_object != NULL) { + g_object_ref (gpm_load_object); + } else { + gpm_load_object = g_object_new (GPM_TYPE_LOAD, NULL); + g_object_add_weak_pointer (gpm_load_object, &gpm_load_object); + } + return GPM_LOAD (gpm_load_object); +} + -- cgit v1.2.1