/* * This file is part of Cockpit. * * Copyright (C) 2013 Red Hat, Inc. * * Cockpit is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * Cockpit 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Cockpit; If not, see . */ #include "config.h" #include "cockpitcpusamples.h" #include #include gint cockpit_cpu_user_hz = -1; static gint ensure_user_hz (void) { if (cockpit_cpu_user_hz <= 0) { cockpit_cpu_user_hz = sysconf (_SC_CLK_TCK); if (cockpit_cpu_user_hz == -1 || cockpit_cpu_user_hz == 0) { g_warning ("sysconf (_SC_CLK_TCK) returned %d - forcing user_hz to 100", cockpit_cpu_user_hz); cockpit_cpu_user_hz = 100; } } return cockpit_cpu_user_hz; } /* TODO: this should be optimized so we don't allocate memory and call open()/close() all the time */ void cockpit_cpu_samples (CockpitSamples *samples) { gchar *contents = NULL; GError *error = NULL; gchar **lines = NULL; guint64 user_hz; gsize len; guint n; if (!g_file_get_contents ("/proc/stat", &contents, &len, &error)) { g_message ("error loading contents /proc/stat: %s", error->message); g_error_free (error); goto out; } /* see 'man proc' for the format of /proc/stat */ lines = g_strsplit (contents, "\n", -1); for (n = 0; lines != NULL && lines[n] != NULL; n++) { const gchar *line = lines[n]; guint64 user; guint64 nice; guint64 system; guint64 idle; guint64 iowait; if (!(g_str_has_prefix (line, "cpu "))) continue; #define FMT64 "%" G_GUINT64_FORMAT " " if (sscanf (line + sizeof ("cpu ") - 1, FMT64 FMT64 FMT64 FMT64 FMT64, &user, &nice, &system, &idle, &iowait) != 5) { g_warning ("Error parsing line %d of /proc/stat with content `%s'", n, line); continue; } user_hz = ensure_user_hz (); cockpit_samples_sample (samples, "cpu.basic.nice", NULL, nice*1000/user_hz); cockpit_samples_sample (samples, "cpu.basic.user", NULL, user*1000/user_hz); cockpit_samples_sample (samples, "cpu.basic.system", NULL, system*1000/user_hz); cockpit_samples_sample (samples, "cpu.basic.iowait", NULL, iowait*1000/user_hz); break; } out: g_strfreev (lines); g_free (contents); }