[sysprof] hostinfo: actually parse cpu freq details
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof] hostinfo: actually parse cpu freq details
- Date: Wed, 29 May 2019 22:43:48 +0000 (UTC)
commit 5331e8bd7f4e49e90d5b29289b9db0e19c377c56
Author: Christian Hergert <chergert redhat com>
Date: Thu May 23 12:21:21 2019 -0700
hostinfo: actually parse cpu freq details
src/libsysprof/sysprof-hostinfo-source.c | 99 +++++++++++++++++++++++++++-----
1 file changed, 85 insertions(+), 14 deletions(-)
---
diff --git a/src/libsysprof/sysprof-hostinfo-source.c b/src/libsysprof/sysprof-hostinfo-source.c
index 05babcb..1a0a599 100644
--- a/src/libsysprof/sysprof-hostinfo-source.c
+++ b/src/libsysprof/sysprof-hostinfo-source.c
@@ -22,6 +22,7 @@
#include <ctype.h>
#include <fcntl.h>
+#include <glib/gstdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -34,22 +35,23 @@
struct _SysprofHostinfoSource
{
- GObject parent_instance;
+ GObject parent_instance;
- guint handler;
- gint n_cpu;
- gint stat_fd;
+ guint handler;
+ gint n_cpu;
+ gint stat_fd;
+
+ GArray *freqs;
SysprofCaptureWriter *writer;
- GArray *cpu_info;
- gchar *stat_buf;
+ GArray *cpu_info;
+ gchar *stat_buf;
};
typedef struct
{
gint counter_base;
gdouble total;
- gdouble freq;
glong last_user;
glong last_idle;
glong last_system;
@@ -62,6 +64,12 @@ typedef struct
glong last_guest_nice;
} CpuInfo;
+typedef struct
+{
+ gint stat_fd;
+ gint64 max;
+} CpuFreq;
+
static void source_iface_init (SysprofSourceInterface *iface);
G_DEFINE_TYPE_EXTENDED (SysprofHostinfoSource, sysprof_hostinfo_source, G_TYPE_OBJECT, 0,
@@ -195,6 +203,40 @@ poll_cpu (SysprofHostinfoSource *self)
}
}
+static gdouble
+get_cpu_freq (SysprofHostinfoSource *self,
+ guint cpu)
+{
+ const CpuFreq *freq;
+
+ g_assert (SYSPROF_IS_HOSTINFO_SOURCE (self));
+ g_assert (cpu < self->freqs->len);
+
+ freq = &g_array_index (self->freqs, CpuFreq, cpu);
+
+ if (freq->stat_fd > -1)
+ {
+ gchar buf[128];
+ gssize len;
+
+ lseek (freq->stat_fd, SEEK_SET, 0);
+ len = read (freq->stat_fd, buf, sizeof buf - 1);
+
+ if (len > 0 && len < sizeof buf)
+ {
+ gint64 val;
+
+ buf[len] = 0;
+ g_strstrip (buf);
+ val = g_ascii_strtoll (buf, NULL, 10);
+
+ return (gdouble)val / (gdouble)freq->max * 100.0;
+ }
+ }
+
+ return 0.0;
+}
+
static void
publish_cpu (SysprofHostinfoSource *self)
{
@@ -217,16 +259,16 @@ publish_cpu (SysprofHostinfoSource *self)
value++;
*id = info->counter_base + 1;
- value->vdbl = info->freq;
+ value->vdbl = get_cpu_freq (self, i);
}
sysprof_capture_writer_set_counters (self->writer,
- SYSPROF_CAPTURE_CURRENT_TIME,
- -1,
- getpid (),
- counter_ids,
- counter_values,
- self->n_cpu * 2);
+ SYSPROF_CAPTURE_CURRENT_TIME,
+ -1,
+ getpid (),
+ counter_ids,
+ counter_values,
+ self->n_cpu * 2);
}
static gboolean
@@ -256,6 +298,7 @@ sysprof_hostinfo_source_finalize (GObject *object)
g_clear_pointer (&self->writer, sysprof_capture_writer_unref);
g_clear_pointer (&self->cpu_info, g_array_unref);
g_clear_pointer (&self->stat_buf, g_free);
+ g_clear_pointer (&self->freqs, g_array_unref);
G_OBJECT_CLASS (sysprof_hostinfo_source_parent_class)->finalize (object);
}
@@ -274,6 +317,7 @@ sysprof_hostinfo_source_init (SysprofHostinfoSource *self)
self->stat_fd = -1;
self->cpu_info = g_array_new (FALSE, TRUE, sizeof (CpuInfo));
self->stat_buf = g_malloc (PROC_STAT_BUF_SIZE);
+ self->freqs = g_array_new (FALSE, FALSE, sizeof (CpuFreq));
}
static void
@@ -316,6 +360,17 @@ sysprof_hostinfo_source_stop (SysprofSource *source)
self->stat_fd = -1;
}
+ for (guint i = 0; i < self->freqs->len; i++)
+ {
+ CpuFreq *freq = &g_array_index (self->freqs, CpuFreq, i);
+
+ if (freq->stat_fd != -1)
+ close (freq->stat_fd);
+ }
+
+ if (self->freqs->len > 0)
+ g_array_remove_range (self->freqs, 0, self->freqs->len);
+
sysprof_source_emit_finished (SYSPROF_SOURCE (self));
}
@@ -336,8 +391,12 @@ sysprof_hostinfo_source_prepare (SysprofSource *source)
for (guint i = 0; i < self->n_cpu; i++)
{
+ g_autofree gchar *max_path = NULL;
+ g_autofree gchar *cur_path = NULL;
+ g_autofree gchar *maxstr = NULL;
SysprofCaptureCounter *ctr = &counters[i*2];
CpuInfo info = { 0 };
+ CpuFreq freq = { 0 };
/*
* Request 2 counter values.
@@ -358,6 +417,18 @@ sysprof_hostinfo_source_prepare (SysprofSource *source)
ctr++;
+ max_path = g_strdup_printf ("/sys/devices/system/cpu/cpu%u/cpufreq/scaling_max_freq", i);
+ cur_path = g_strdup_printf ("/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", i);
+
+ if (g_file_get_contents (max_path, &maxstr, NULL, NULL))
+ {
+ g_strstrip (maxstr);
+ freq.max = g_ascii_strtoll (maxstr, NULL, 10);
+ }
+
+ freq.stat_fd = g_open (cur_path, O_RDONLY);
+ g_array_append_val (self->freqs, freq);
+
ctr->id = info.counter_base + 1;
ctr->type = SYSPROF_CAPTURE_COUNTER_DOUBLE;
ctr->value.vdbl = 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]