[Xfce4-commits] <xfce4-cpufreq-plugin:master> Add support for the Intel P-State driver.
Harald Judt
noreply at xfce.org
Sun Aug 18 11:32:16 CEST 2013
Updating branch refs/heads/master
to f3bfa666503563ea9d0e2fb6ce2e8f1d558d738e (commit)
from e5b824087d347de8edd088834c09aa1c69cf953a (commit)
commit f3bfa666503563ea9d0e2fb6ce2e8f1d558d738e
Author: Harald Judt <h.judt at gmx.at>
Date: Sun Aug 11 13:22:48 2013 +0200
Add support for the Intel P-State driver.
This makes the current version work with the intel pstate driver.
Showing governors and performance values works, the pstate parameters
are read but not used yet; The UI has to be reworked to accommodate
for that.
panel-plugin/xfce4-cpufreq-linux.c | 251 ++++++++++++++++++++++++++---------
panel-plugin/xfce4-cpufreq-linux.h | 3 +
panel-plugin/xfce4-cpufreq-plugin.c | 2 +
panel-plugin/xfce4-cpufreq-plugin.h | 14 +-
4 files changed, 203 insertions(+), 67 deletions(-)
diff --git a/panel-plugin/xfce4-cpufreq-linux.c b/panel-plugin/xfce4-cpufreq-linux.c
index 954048e..11a7ddb 100644
--- a/panel-plugin/xfce4-cpufreq-linux.c
+++ b/panel-plugin/xfce4-cpufreq-linux.c
@@ -35,48 +35,53 @@
#endif
static gboolean
-cpufreq_cpu_parse_sysfs_init (gint cpu_number)
+cpufreq_cpu_parse_sysfs_init (gint cpu_number, CpuInfo *cpu)
{
- CpuInfo *cpu;
FILE *file;
gchar *filePath, *fileContent, **tokens;
+ gboolean add_cpu = FALSE;
- cpu = g_new0 (CpuInfo, 1);
+ if (cpu == NULL) {
+ cpu = g_new0 (CpuInfo, 1);
+ add_cpu = TRUE;
+ }
/* read available cpu freqs */
- filePath = g_strdup_printf (
- "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_available_frequencies",
- cpu_number);
- if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
- goto file_error;
- file = fopen (filePath, "r");
- if (file)
- {
- gint i = 0;
+ if (cpuFreq->intel_pstate == NULL) {
+ filePath =
+ g_strdup_printf ("/sys/devices/system/cpu/cpu%i/"
+ "cpufreq/scaling_available_frequencies",
+ cpu_number);
+ if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+ goto file_error;
+ file = fopen (filePath, "r");
+ if (file) {
+ gint i = 0;
- fileContent = g_new (gchar, 255);
- fgets (fileContent, 255, file);
- fclose (file);
+ fileContent = g_new (gchar, 255);
+ fgets (fileContent, 255, file);
+ fclose (file);
- fileContent = g_strchomp (fileContent);
- tokens = g_strsplit (fileContent, " ", 0);
- g_free (fileContent);
+ fileContent = g_strchomp (fileContent);
+ tokens = g_strsplit (fileContent, " ", 0);
+ g_free (fileContent);
- while (tokens[i] != NULL)
- {
- gint freq = atoi (tokens[i]);
- cpu->available_freqs = g_list_append (
- cpu->available_freqs, GINT_TO_POINTER(freq));
- i++;
+ while (tokens[i] != NULL) {
+ gint freq = atoi (tokens[i]);
+ cpu->available_freqs =
+ g_list_append (cpu->available_freqs,
+ GINT_TO_POINTER(freq));
+ i++;
+ }
+ g_strfreev (tokens);
}
- g_strfreev (tokens);
+ g_free (filePath);
}
- g_free (filePath);
/* read available cpu governors */
filePath = g_strdup_printf (
"/sys/devices/system/cpu/cpu%i/cpufreq/scaling_available_governors",
- cpu_number);
+ cpu_number);
if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
goto file_error;
file = fopen (filePath, "r");
@@ -112,6 +117,7 @@ cpufreq_cpu_parse_sysfs_init (gint cpu_number)
file = fopen (filePath, "r");
if (file)
{
+ g_free (cpu->scaling_driver);
cpu->scaling_driver = g_new (gchar, 15);
fscanf (file, "%15s", cpu->scaling_driver);
fclose (file);
@@ -119,18 +125,20 @@ cpufreq_cpu_parse_sysfs_init (gint cpu_number)
g_free (filePath);
/* read current cpu freq */
- filePath = g_strdup_printf (
- "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_cur_freq",
- cpu_number);
- if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
- goto file_error;
- file = fopen (filePath, "r");
- if (file)
- {
- fscanf (file, "%d", &cpu->cur_freq);
- fclose (file);
+ if (cpuFreq->intel_pstate == NULL) {
+ filePath =
+ g_strdup_printf ("/sys/devices/system/cpu/cpu%i/"
+ "cpufreq/scaling_cur_freq",
+ cpu_number);
+ if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+ goto file_error;
+ file = fopen (filePath, "r");
+ if (file) {
+ fscanf (file, "%d", &cpu->cur_freq);
+ fclose (file);
+ }
+ g_free (filePath);
}
- g_free (filePath);
/* read current cpu governor */
filePath = g_strdup_printf (
@@ -141,6 +149,7 @@ cpufreq_cpu_parse_sysfs_init (gint cpu_number)
file = fopen (filePath, "r");
if (file)
{
+ g_free (cpu->cur_governor);
cpu->cur_governor = g_new (gchar, 15);
fscanf (file, "%15s", cpu->cur_governor);
fclose (file);
@@ -175,11 +184,14 @@ cpufreq_cpu_parse_sysfs_init (gint cpu_number)
}
g_free (filePath);
- g_ptr_array_add (cpuFreq->cpus, cpu);
+ if (add_cpu)
+ g_ptr_array_add (cpuFreq->cpus, cpu);
return TRUE;
file_error:
+ if (add_cpu && cpu != NULL)
+ cpuinfo_free (cpu);
g_free (filePath);
return FALSE;
}
@@ -194,18 +206,20 @@ cpufreq_cpu_read_sysfs_current (gint cpu_number)
cpu = g_ptr_array_index (cpuFreq->cpus, cpu_number);
/* read current cpu freq */
- filePath = g_strdup_printf (
- "/sys/devices/system/cpu/cpu%i/cpufreq/scaling_cur_freq",
- cpu_number);
- if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
- goto file_error;
- file = fopen (filePath, "r");
- if (file)
- {
- fscanf (file, "%d", &cpu->cur_freq);
- fclose (file);
+ if (cpuFreq->intel_pstate == NULL) {
+ filePath =
+ g_strdup_printf ("/sys/devices/system/cpu/cpu%i/"
+ "cpufreq/scaling_cur_freq",
+ cpu_number);
+ if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+ goto file_error;
+ file = fopen (filePath, "r");
+ if (file) {
+ fscanf (file, "%d", &cpu->cur_freq);
+ fclose (file);
+ }
+ g_free (filePath);
}
- g_free (filePath);
/* read current cpu governor */
filePath = g_strdup_printf (
@@ -234,6 +248,8 @@ cpufreq_cpu_read_procfs_cpuinfo ()
CpuInfo *cpu;
FILE *file;
gchar *freq, *filePath, *fileContent;
+ gint i = 0;
+ gboolean add_cpu;
filePath = g_strdup ("/proc/cpuinfo");
if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
@@ -249,12 +265,24 @@ cpufreq_cpu_read_procfs_cpuinfo ()
{
if (g_ascii_strncasecmp (fileContent, "cpu MHz", 7) == 0)
{
- cpu = g_new0 (CpuInfo, 1);
- cpu->max_freq = 0;
- cpu->min_freq = 0;
- cpu->cur_governor = NULL;
- cpu->available_freqs = NULL;
- cpu->available_governors = NULL;
+ cpu = NULL;
+ add_cpu = FALSE;
+
+ if (cpuFreq->cpus && cpuFreq->cpus->len > i)
+ {
+ cpu = g_ptr_array_index (cpuFreq->cpus, i);
+ }
+
+ if (cpu == NULL)
+ {
+ cpu = g_new0 (CpuInfo, 1);
+ cpu->max_freq = 0;
+ cpu->min_freq = 0;
+ cpu->cur_governor = NULL;
+ cpu->available_freqs = NULL;
+ cpu->available_governors = NULL;
+ add_cpu = TRUE;
+ }
freq = g_strrstr (fileContent, ":");
if (freq != NULL)
@@ -262,10 +290,16 @@ cpufreq_cpu_read_procfs_cpuinfo ()
sscanf (++freq, "%d.", &cpu->cur_freq);
cpu->cur_freq *= 1000;
}
- else
+ else {
+ if (add_cpu)
+ cpuinfo_free (cpu);
break;
+ }
- g_ptr_array_add (cpuFreq->cpus, cpu);
+ if (add_cpu && cpu != NULL)
+ g_ptr_array_add (cpuFreq->cpus, cpu);
+
+ ++i;
}
}
fclose (file);
@@ -305,7 +339,7 @@ cpufreq_cpu_read_procfs ()
cpu->available_freqs = NULL;
cpu->available_governors = NULL;
- sscanf (fileContent,
+ sscanf (fileContent,
"CPU %*d %d kHz (%*d %%) - %d kHz (%*d %%) - %20s",
&cpu->min_freq,
&cpu->max_freq,
@@ -359,18 +393,104 @@ cpufreq_cpu_read_sysfs ()
for (j = 0; j < i; j++)
{
- cpufreq_cpu_parse_sysfs_init (j);
+ cpufreq_cpu_parse_sysfs_init (j, NULL);
}
return TRUE;
}
gboolean
+cpufreq_intel_pstate_params (void)
+{
+ FILE *file;
+ gchar *filePath, *fileContent;
+ IntelPState *ips;
+
+ ips = g_slice_new0(IntelPState);
+
+ filePath =
+ g_strdup ("/sys/devices/system/cpu/intel_pstate/min_perf_pct");
+ if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+ goto file_error;
+ file = fopen (filePath, "r");
+ if (file) {
+ fscanf (file, "%d", &ips->min_perf_pct);
+ fclose (file);
+ }
+ g_free (filePath);
+
+ filePath =
+ g_strdup ("/sys/devices/system/cpu/intel_pstate/max_perf_pct");
+ if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+ goto file_error;
+ file = fopen (filePath, "r");
+ if (file) {
+ fscanf (file, "%d", &ips->max_perf_pct);
+ fclose (file);
+ }
+ g_free (filePath);
+
+ filePath =
+ g_strdup ("/sys/devices/system/cpu/intel_pstate/no_turbo");
+ if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+ goto file_error;
+ file = fopen (filePath, "r");
+ if (file) {
+ fscanf (file, "%d", &ips->no_turbo);
+ fclose (file);
+ }
+ g_free (filePath);
+
+ g_slice_free (IntelPState, cpuFreq->intel_pstate);
+ cpuFreq->intel_pstate = ips;
+ return TRUE;
+
+file_error:
+ g_slice_free (IntelPState, ips);
+ g_free (filePath);
+ return FALSE;
+}
+
+static gboolean
+cpufreq_cpu_intel_pstate_read ()
+{
+ CpuInfo *cpu;
+ gint i;
+
+ /* gather intel pstate parameters */
+ if (!cpufreq_intel_pstate_params ())
+ return FALSE;
+
+ /* Read /proc/cpuinfo, that's where intel pstate stores
+ the "current frequencies" that are readable by
+ unprivileged users. */
+ if (!cpufreq_cpu_read_procfs_cpuinfo ())
+ return FALSE;
+
+ /* now read the remaining cpufreq info for each cpu from sysfs */
+ for (i = 0; i < cpuFreq->cpus->len; i++) {
+ cpu = g_ptr_array_index (cpuFreq->cpus, i);
+ cpufreq_cpu_parse_sysfs_init (i, cpu);
+ }
+ return TRUE;
+}
+
+gboolean
cpufreq_update_cpus (gpointer data)
{
gint i;
- if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS))
+ if (g_file_test ("/sys/devices/system/cpu/intel_pstate", G_FILE_TEST_EXISTS))
+ {
+ /* read current cpu frequencies from /proc/cpuinfo */
+ cpufreq_cpu_read_procfs_cpuinfo ();
+
+ /* read current scaling governor from sysfs */
+ for (i = 0; i < cpuFreq->cpus->len; i++)
+ cpufreq_cpu_read_sysfs_current (i);
+ }
+ else if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq",
+ G_FILE_TEST_EXISTS))
{
for (i = 0; i < cpuFreq->cpus->len; i++)
cpufreq_cpu_read_sysfs_current (i);
@@ -382,8 +502,7 @@ cpufreq_update_cpus (gpointer data)
{
CpuInfo *cpu = g_ptr_array_index (cpuFreq->cpus, i);
g_ptr_array_remove_fast (cpuFreq->cpus, cpu);
- g_free (cpu->cur_governor);
- g_free (cpu);
+ cpuinfo_free (cpu);
}
cpufreq_cpu_read_procfs ();
}
@@ -402,8 +521,10 @@ cpufreq_linux_init (void)
if (cpuFreq->cpus == NULL)
return FALSE;
- if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS) &&
- !g_file_test ("/sys/devices/system/cpu/intel_pstate", G_FILE_TEST_EXISTS))
+ if (g_file_test ("/sys/devices/system/cpu/intel_pstate", G_FILE_TEST_EXISTS))
+ return cpufreq_cpu_intel_pstate_read ();
+ else if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq",
+ G_FILE_TEST_EXISTS))
return cpufreq_cpu_read_sysfs ();
else if (g_file_test ("/proc/cpufreq", G_FILE_TEST_EXISTS))
return cpufreq_cpu_read_procfs ();
diff --git a/panel-plugin/xfce4-cpufreq-linux.h b/panel-plugin/xfce4-cpufreq-linux.h
index 04c87e1..7360c42 100644
--- a/panel-plugin/xfce4-cpufreq-linux.h
+++ b/panel-plugin/xfce4-cpufreq-linux.h
@@ -26,6 +26,9 @@ gboolean
cpufreq_update_cpus (gpointer data);
gboolean
+cpufreq_intel_pstate_params (void);
+
+gboolean
cpufreq_linux_init (void);
G_END_DECLS
diff --git a/panel-plugin/xfce4-cpufreq-plugin.c b/panel-plugin/xfce4-cpufreq-plugin.c
index ce7d7e5..f19b9d3 100644
--- a/panel-plugin/xfce4-cpufreq-plugin.c
+++ b/panel-plugin/xfce4-cpufreq-plugin.c
@@ -366,6 +366,8 @@ cpufreq_free (XfcePanelPlugin *plugin)
if (cpuFreq->timeoutHandle)
g_source_remove (cpuFreq->timeoutHandle);
+ g_slice_free (IntelPState, cpuFreq->intel_pstate);
+
for (i = 0; i < cpuFreq->cpus->len; i++)
{
CpuInfo *cpu = g_ptr_array_index (cpuFreq->cpus, i);
diff --git a/panel-plugin/xfce4-cpufreq-plugin.h b/panel-plugin/xfce4-cpufreq-plugin.h
index 890b22e..0f2d313 100644
--- a/panel-plugin/xfce4-cpufreq-plugin.h
+++ b/panel-plugin/xfce4-cpufreq-plugin.h
@@ -38,8 +38,15 @@ typedef struct
typedef struct
{
- guint timeout; /* time between refreash */
- guint show_cpu; /* cpu number in panel */
+ gint min_perf_pct;
+ gint max_perf_pct;
+ gint no_turbo;
+} IntelPState;
+
+typedef struct
+{
+ guint timeout; /* time between refresh */
+ guint show_cpu; /* cpu number in panel */
gboolean show_icon;
gboolean show_label_governor;
gboolean show_label_freq;
@@ -55,6 +62,9 @@ typedef struct
/* Array with all CPUs */
GPtrArray *cpus;
+ /* Intel P-State parameters */
+ IntelPState *intel_pstate;
+
/* Widgets */
GtkWidget *button, *box, *icon, *label;
More information about the Xfce4-commits
mailing list