summaryrefslogtreecommitdiff
path: root/src/gpm-load.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpm-load.c')
-rw-r--r--src/gpm-load.c282
1 files changed, 282 insertions, 0 deletions
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 <[email protected]>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#if defined(sun) && defined(__SVR4)
+#include <kstat.h>
+#include <sys/sysinfo.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+
+#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);
+}
+