GNOME Bugzilla – Bug 168356
[PATCH] Add FreeBSD support to the cpufreq applet
Last modified: 2020-11-06 19:55:55 UTC
Please describe the problem: The attached patch adds FreeBSD for cpufreq. Cpufreq support was added recently to FreeBSD 6-CURRENT, but even older versions support simply reporting the CPU clockrate. The attached patch handles both cases, and even supports setting the CPU frequency. Steps to reproduce: Actual results: Expected results: Does this happen every time? Other information:
Created attachment 37877 [details] [review] Add FreeBSD support to cpufreq
looks great :P
Sorry for the long delay in reply. I'm very busy these days because of exams. I'm going to review it as soon as I finish the exams
Comment on attachment 37877 [details] [review] Add FreeBSD support to cpufreq Apologies for the long delay. Some comments below >--- cpufreq/src/Makefile.am.orig Thu Feb 24 03:06:59 2005 >+++ cpufreq/src/Makefile.am Thu Feb 24 03:07:42 2005 >@@ -22,6 +22,7 @@ > cpufreq-monitor-factory.c cpufreq-monitor-factory.h \ > cpufreq-monitor-procfs.c cpufreq-monitor-procfs.h \ > cpufreq-monitor-sysfs.c cpufreq-monitor-sysfs.h \ >+ cpufreq-monitor-sysctl.c cpufreq-monitor-sysctl.c.h \ > cpufreq-monitor-cpuinfo.c cpufreq-monitor-cpuinfo.h > > cpufreq_applet_LDADD = \ >--- cpufreq/src/cpufreq-monitor-sysctl.h.orig Sun Feb 13 01:00:25 2005 >+++ cpufreq/src/cpufreq-monitor-sysctl.h Sat Feb 12 20:25:21 2005 >@@ -0,0 +1,48 @@ >+/* >+ * Copyright (C) 2001, 2002 Free Software Foundation >+ * >+ * This library 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 library 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 library; if not, write to the Free >+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. >+ * >+ * Authors : Joe Marcus Clarke <marcus@FreeBSD.org> >+ */ >+ >+#ifndef __CPUFREQ_MONITOR_SYSCTL_H__ >+#define __CPUFREQ_MONITOR_SYSCTL_H__ >+ >+#include <glib-object.h> >+#include "cpufreq-monitor.h" >+ >+#define TYPE_CPUFREQ_MONITOR_SYSCTL (cpufreq_monitor_sysctl_get_type ()) >+#define CPUFREQ_MONITOR_SYSCTL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CPUFREQ_MONITOR_SYSCTL, CPUFreqMonitorSysctl)) >+#define CPUFREQ_MONITOR_SYSCTL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_CPUFREQ_MONITOR_SYSCTL, CPUFreqMonitorSysctlClass)) >+#define IS_CPUFREQ_MONITOR_SYSCTL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CPUFREQ_MONITOR_SYSCTL)) >+#define IS_CPUFREQ_MONITOR_SYSCTL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CPUFREQ_MONITOR_SYSCTL)) >+#define CPUFREQ_MONITOR_SYSCTL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CPUFREQ_MONITOR_SYSCTL, CPUFreqMonitorSysctlClass)) >+ >+typedef struct _CPUFreqMonitorSysctl CPUFreqMonitorSysctl; >+typedef struct _CPUFreqMonitorSysctlClass CPUFreqMonitorSysctlClass; >+ >+struct _CPUFreqMonitorSysctl { >+ CPUFreqMonitor parent; >+}; >+ >+struct _CPUFreqMonitorSysctlClass { >+ CPUFreqMonitorClass parent_class; >+}; >+ >+GType cpufreq_monitor_sysctl_get_type (); >+CPUFreqMonitor *cpufreq_monitor_sysctl_new (guint cpu); >+ >+#endif /* __CPUFREQ_MONITOR_SYSCTL_H__ */ >--- cpufreq/src/cpufreq-monitor-cpuinfo.c.orig Fri Dec 31 14:39:04 2004 >+++ cpufreq/src/cpufreq-monitor-cpuinfo.c Sun Feb 13 23:58:38 2005 >@@ -22,6 +22,10 @@ > #include <glib/gi18n.h> > #include <libgnomevfs/gnome-vfs.h> > >+#ifdef __FreeBSD__ >+#include <sys/types.h> >+#include <sys/sysctl.h> >+#endif /* __FreeBSD__ */ > #include <string.h> > > #include "cpufreq-monitor-cpuinfo.h" >@@ -102,6 +106,7 @@ > static gboolean > cpufreq_monitor_cpuinfo_get (gpointer gdata) > { >+#ifndef __FreeBSD__ > GnomeVFSHandle *handle; > GnomeVFSFileSize bytes_read; > GnomeVFSResult result; >@@ -109,6 +114,9 @@ > gchar **lines; > gchar buffer[256]; > gchar *p; >+#else >+ size_t len; >+#endif /* __FreeBSD__ */ > gchar *freq, *perc, *unit, *governor; > gint cpu, i; > CPUFreqMonitorCPUInfo *monitor; >@@ -118,6 +126,7 @@ > > private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor)); > >+#ifndef __FreeBSD__ > uri = gnome_vfs_get_uri_from_local_path ("/proc/cpuinfo"); > > result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ); >@@ -178,6 +187,12 @@ > > g_strfreev (lines); > g_free (file); >+#else >+ len = sizeof (cpu); >+ >+ if (sysctlbyname ("hw.clockrate", &cpu, &len, NULL, 0) == -1) >+ return FALSE; >+#endif /* __FreeBSD__ */ > > governor = g_strdup (_("Frequency Scaling Unsupported")); > freq = parent_class->get_human_readable_freq (cpu * 1000); /* kHz are expected*/ I don't like #ifdefs, they make hard to read the code, so I prefer to avoid them when it's possible. I think we can use another file for the specific FreeBSD code in this case. >--- cpufreq/src/cpufreq-monitor-factory.c.orig Mon Dec 27 12:53:46 2004 >+++ cpufreq/src/cpufreq-monitor-factory.c Sun Feb 13 23:58:44 2005 >@@ -16,13 +16,21 @@ > * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > * > * Authors : Carlos Garc�a Campos <carlosgc@gnome.org> >+ * Joe Marcus Clarke <marcus@FreeBSD.org> > */ > > #include <glib.h> >+#ifdef __FreeBSD__ >+#include <sys/types.h> >+#include <sys/sysctl.h> >+#endif /* __FreeBSD__ */ > > #include "cpufreq-applet.h" > #include "cpufreq-monitor-sysfs.h" > #include "cpufreq-monitor-procfs.h" >+#ifdef __FreeBSD__ >+#include "cpufreq-monitor-sysctl.h" >+#endif /* __FreeBSD__ */ > #include "cpufreq-monitor-cpuinfo.h" > #include "cpufreq-monitor-factory.h" > >@@ -30,6 +38,7 @@ > cpufreq_monitor_factory_create_monitor (guint cpu) > { > CPUFreqMonitor *monitor = NULL; >+#ifndef __FreeBSD__ > > if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.6 kernel */ > monitor = cpufreq_monitor_sysfs_new (cpu); >@@ -48,6 +57,20 @@ > > monitor = cpufreq_monitor_cpuinfo_new (cpu); > } >+#else >+ size_t len; >+ >+ if (sysctlbyname ("dev.cpu.0.freq", NULL, &len, NULL, 0) == 0) { >+ monitor = cpufreq_monitor_sysctl_new (cpu); >+ } else { >+ cpufreq_applet_display_error (_("CPU frequency scaling unsupported"), >+ _("You will not be able to modify the frequency of your machine. " >+ "Your machine may be misconfigured or not have hardware support " >+ "for CPU frequency scaling.")); >+ >+ monitor = cpufreq_monitor_cpuinfo_new (cpu); >+ } >+#endif /* __FreeBSD__ */ > > return monitor; > } >--- cpufreq/src/cpufreq-monitor-sysctl.c.orig Sun Feb 13 03:52:42 2005 >+++ cpufreq/src/cpufreq-monitor-sysctl.c Mon Feb 14 00:42:07 2005 >@@ -0,0 +1,269 @@ >+/* >+ * Copyright (C) 2001, 2002 Free Software Foundation >+ * >+ * This library 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 library 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 library; if not, write to the Free >+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. >+ * >+ * Authors : Joe Marcus Clarke <marcus@FreeBSD.org> >+ */ >+ >+#include <glib.h> >+#include <glib/gi18n.h> >+ >+#include <string.h> >+ >+#ifdef __FreeBSD__ >+#include <sys/types.h> >+#include <sys/sysctl.h> >+ >+#include "cpufreq-monitor-sysctl.h" >+#include "cpufreq-monitor-protected.h" >+ >+#define PARENT_TYPE TYPE_CPUFREQ_MONITOR >+ >+#define CPUFREQ_MONITOR_GET_PROTECTED(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PARENT_TYPE, CPUFreqMonitorProtected)) >+ >+static void cpufreq_monitor_sysctl_class_init (CPUFreqMonitorSysctlClass *klass); >+static void cpufreq_monitor_sysctl_finalize (GObject *object); >+ >+static void cpufreq_monitor_sysctl_run (CPUFreqMonitor *monitor); >+static GList *cpufreq_monitor_sysctl_get_available_frequencies (CPUFreqMonitor *monitor); >+ >+static gboolean cpufreq_monitor_sysctl_get (gpointer gdata); >+ >+ >+static CPUFreqMonitorClass *parent_class = NULL; >+ >+typedef struct _CPUFreqMonitorProtected CPUFreqMonitorProtected; >+ >+GType cpufreq_monitor_sysctl_get_type () >+{ >+ static GType type = 0; >+ >+ if (!type) { >+ static const GTypeInfo info = { >+ sizeof (CPUFreqMonitorSysctlClass), >+ (GBaseInitFunc) NULL, >+ (GBaseFinalizeFunc) NULL, >+ (GClassInitFunc) cpufreq_monitor_sysctl_class_init, >+ NULL, >+ NULL, >+ sizeof (CPUFreqMonitorSysctl), >+ 0, >+ NULL >+ }; >+ >+ type = g_type_register_static (PARENT_TYPE, "CPUFreqMonitorSysctl", >+ &info, 0); >+ } >+ >+ return type; >+} >+ >+static void >+cpufreq_monitor_sysctl_class_init (CPUFreqMonitorSysctlClass *klass) >+{ >+ GObjectClass *object_class = G_OBJECT_CLASS (klass); >+ CPUFreqMonitorClass *monitor_class = CPUFREQ_MONITOR_CLASS (klass); >+ >+ parent_class = g_type_class_peek_parent (klass); >+ >+ monitor_class->run = cpufreq_monitor_sysctl_run; >+ monitor_class->get_available_frequencies = cpufreq_monitor_sysctl_get_available_frequencies; >+ >+ object_class->finalize = cpufreq_monitor_sysctl_finalize; >+} >+ >+static void >+cpufreq_monitor_sysctl_finalize (GObject *object) >+{ >+ g_return_if_fail (IS_CPUFREQ_MONITOR_SYSCTL (object)); >+ >+ if (G_OBJECT_CLASS (parent_class)->finalize) >+ (* G_OBJECT_CLASS (parent_class)->finalize) (object); >+} >+ >+CPUFreqMonitor * >+cpufreq_monitor_sysctl_new (guint cpu) >+{ >+ CPUFreqMonitorSysctl *monitor; >+ >+ monitor = g_object_new (TYPE_CPUFREQ_MONITOR_SYSCTL, "cpu", cpu, NULL); >+ >+ return CPUFREQ_MONITOR (monitor); >+} >+ >+static gboolean >+cpufreq_monitor_sysctl_get (gpointer gdata) >+{ >+ gint fmax, fmin, ifreq; >+ gchar *freq, *perc, *unit, *governor; >+ gboolean changed; >+ size_t len; >+ gchar *freq_oid; >+ CPUFreqMonitorSysctl *monitor; >+ CPUFreqMonitorProtected *private; >+ >+ monitor = (CPUFreqMonitorSysctl *) gdata; >+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor)); >+ >+ if (private->available_freqs == NULL) { >+ if (!cpufreq_monitor_sysctl_get_available_frequencies (CPUFREQ_MONITOR (monitor))) >+ return FALSE; >+ } >+ >+ fmax = atoi ((gchar *) private->available_freqs->data); >+ fmin = atoi ((gchar *) g_list_nth_data (private->available_freqs, (g_list_length (private->available_freqs) - 1))); >+ >+ len = sizeof (ifreq); >+ freq_oid = g_strdup_printf ("dev.cpu.%d.freq", private->cpu); >+ >+ if (sysctlbyname (freq_oid, &ifreq, &len, NULL, 0) == -1) { >+ g_free (freq_oid); >+ return FALSE; >+ } >+ >+ ifreq *= 1000; >+ >+ if (ifreq == fmax) >+ governor = g_strdup ("performance"); >+ else if (ifreq == fmin) >+ governor = g_strdup ("economy"); The other monitors use powersave instead of economy, which is the Linux Kernel terminology. Is "economy" a specific FreeBSD kernel term?, if not, I prefer to be consistent with the other monitors by using powersave instead. >+ else >+ governor = g_strdup ("other"); I think it's better "Unknown", for consistency with other monitors. >+ freq = parent_class->get_human_readable_freq (ifreq); >+ perc = parent_class->get_human_readable_perc (fmax, ifreq); >+ unit = parent_class->get_human_readable_unit (ifreq); >+ >+ changed = FALSE; >+ >+ if (!private->governor || (g_ascii_strcasecmp (governor, private->governor) != 0)) { >+ changed = TRUE; >+ } >+ >+ if (!private->freq || (g_ascii_strcasecmp (freq, private->freq) != 0)) { >+ changed = TRUE; >+ } >+ >+ if (!private->perc || (g_ascii_strcasecmp (perc, private->perc) != 0)) { >+ changed = TRUE; >+ } >+ >+ if (!private->unit || (g_ascii_strcasecmp (unit, private->unit) != 0)) { >+ changed = TRUE; >+ } >+ >+ parent_class->free_data (CPUFREQ_MONITOR (monitor)); >+ >+ private->governor = governor; >+ private->freq = freq; >+ private->perc = perc; >+ private->unit = unit; >+ >+ if (private->governor == NULL) >+ return FALSE; >+ if (private->freq == NULL) >+ return FALSE; >+ if (private->perc == NULL) >+ return FALSE; >+ if (private->unit == NULL) >+ return FALSE; >+ >+ if (changed) >+ g_signal_emit (CPUFREQ_MONITOR (monitor), parent_class->signals[CHANGED], 0); >+ >+ return TRUE; >+} >+ >+static void >+cpufreq_monitor_sysctl_run (CPUFreqMonitor *monitor) >+{ >+ CPUFreqMonitorProtected *private; >+ >+ g_return_if_fail (IS_CPUFREQ_MONITOR_SYSCTL (monitor)); >+ >+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor)); >+ >+ if (private->timeout_handler > 0) >+ g_source_remove (private->timeout_handler); >+ >+ private->timeout_handler = g_timeout_add (1000, cpufreq_monitor_sysctl_get, (gpointer) monitor); >+} >+ >+static void >+free_string (gpointer str, gpointer gdata) >+{ >+ if (str) g_free (str); >+} >+ >+static GList * >+cpufreq_monitor_sysctl_get_available_frequencies (CPUFreqMonitor *monitor) >+{ >+ CPUFreqMonitorProtected *private; >+ gchar *levels_oid, *levels; >+ gchar **levelsp, **l; >+ gint mib[4]; >+ size_t len; >+ >+ g_return_val_if_fail (IS_CPUFREQ_MONITOR_SYSCTL (monitor), NULL); >+ >+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor)); >+ >+ if (private->available_freqs) { >+ g_list_foreach (private->available_freqs, >+ free_string, NULL); >+ g_list_free (private->available_freqs); >+ private->available_freqs = NULL; >+ } >+ >+ levels_oid = g_strdup_printf ("dev.cpu.%d.freq_levels", >+ private->cpu); >+ len = 4; >+ sysctlnametomib (levels_oid, mib, &len); >+ len = sizeof (levels); >+ g_free (levels_oid); >+ >+ if (sysctl (mib, 4, NULL, &len, NULL, 0) == -1) >+ return NULL; >+ >+ levels = g_malloc (len); >+ if (sysctl (mib, 4, levels, &len, NULL, 0) == -1) >+ return NULL; >+ >+ levelsp = g_strsplit (levels, " ", 0); >+ g_free (levels); >+ >+ for (l = levelsp; l && *l; l++) { >+ gchar **frpr; >+ >+ frpr = g_strsplit (*l, "/", 0); >+ if (frpr && frpr[0] != NULL) { >+ /* sysctl format is %d/%d where the >+ * first %d is the frequency, and >+ * the second is the power used in >+ * mW. >+ */ >+ int freq = atoi (frpr[0]); >+ private->available_freqs = >+ g_list_append (private->available_freqs, g_strdup_printf ("%d", freq * 1000)); >+ } >+ g_strfreev (frpr); >+ } >+ >+ g_strfreev (levelsp); >+ >+ return private->available_freqs; >+} >+#endif /* __FreeBSD__ */ >--- cpufreq/src/cpufreq-applet.c.orig Fri Jan 14 23:38:20 2005 >+++ cpufreq/src/cpufreq-applet.c Mon Feb 14 00:47:36 2005 >@@ -16,6 +16,7 @@ > * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > * > * Authors : Carlos Garc�a Campos <carlosgc@gnome.org> >+ * Joe Marcus Clarke <marcus@FreeBSD.org> > */ > > #include <config.h> >@@ -25,6 +26,10 @@ > #include <panel-applet-gconf.h> > #include <glade/glade.h> > #include <glib/gi18n.h> >+#ifdef __FreeBSD__ >+#include <sys/types.h> >+#include <sys/sysctl.h> >+#endif /* __FreeBSD__ */ > #include <string.h> > > #include "cpufreq-applet.h" >@@ -192,6 +197,7 @@ > { > static const gchar *authors[] = { > "Carlos Garcia Campos <carlosgc@gnome.org>", >+ "Joe Marcus Clarke <marcus@FreeBSD.org> (FreeBSD support)", > NULL > }; > static const gchar *documenters[] = { >@@ -231,6 +237,7 @@ > cpufreq_applet_get_max_cpu () > { > gint mcpu = -1; >+#ifndef __FreeBSD__ > gchar *file = NULL; > > do { >@@ -253,6 +260,14 @@ > } while (g_file_test (file, G_FILE_TEST_EXISTS)); > g_free (file); > mcpu --; >+#else >+ size_t len; >+ >+ len = sizeof (mcpu); >+ >+ sysctlbyname ("hw.ncpu", &mcpu, &len, NULL, 0); >+ mcpu --; >+#endif /* __FreeBSD__ */ > > if (mcpu >= 0) > return mcpu; Please redefine the whole function and put the #ifdef out of the function. I think the code is easier to read in this way. >--- cpufreq/src/cpufreq-selector/Makefile.am.orig Thu Feb 24 03:09:19 2005 >+++ cpufreq/src/cpufreq-selector/Makefile.am Thu Feb 24 03:09:49 2005 >@@ -15,6 +15,7 @@ > cpufreq.c cpufreq.h \ > cpufreq-sysfs.c cpufreq-sysfs.h \ > cpufreq-procfs.c cpufreq-procfs.h \ >+ cpufreq-sysctl.c cpufreq-sysctl.h \ > main.c > > cpufreq_selector_LDADD = $(CPUFREQ_SELECTOR_LIBS) -lpopt >--- cpufreq/src/cpufreq-selector/cpufreq-sysctl.h.orig Mon Feb 14 00:38:57 2005 >+++ cpufreq/src/cpufreq-selector/cpufreq-sysctl.h Mon Feb 14 00:21:39 2005 >@@ -0,0 +1,51 @@ >+/* >+ * Copyright (C) 2001, 2002 Free Software Foundation >+ * >+ * This library 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 library 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 library; if not, write to the Free >+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. >+ * >+ * Authors : Joe Marcus Clarke <marcus@FreeBSD.org> >+ */ >+ >+#ifndef __CPUFREQ_SYSCTL_H__ >+#define __CPUFREQ_SYSCTL_H__ >+ >+#include <glib-object.h> >+ >+#include "cpufreq.h" >+ >+#define TYPE_CPUFREQ_SYSCTL (cpufreq_sysctl_get_type ()) >+#define CPUFREQ_SYSCTL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CPUFREQ_SYSCTL, CPUFreqSysctl)) >+#define CPUFREQ_SYSCTL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_CPUFREQ_SYSCTL, CPUFreqSysctlClass)) >+#define IS_CPUFREQ_SYSCTL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CPUFREQ_SYSCTL)) >+#define IS_CPUFREQ_SYSCTL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CPUFREQ_SYSCTL)) >+#define CPUFREQ_SYSCTL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CPUFREQ_SYSCTL, CPUFreqSysctlClass)) >+ >+typedef struct _CPUFreqSysctl CPUFreqSysctl; >+typedef struct _CPUFreqSysctlClass CPUFreqSysctlClass; >+typedef struct _CPUFreqSysctlPriv CPUFreqSysctlPriv; >+ >+struct _CPUFreqSysctl { >+ CPUFreq parent; >+}; >+ >+struct _CPUFreqSysctlClass { >+ CPUFreqClass parent_class; >+}; >+ >+ >+GType cpufreq_sysctl_get_type (); >+CPUFreqSysctl *cpufreq_sysctl_new (); >+ >+#endif /* __CPUFREQ_SYSCTL_H__ */ >--- cpufreq/src/cpufreq-selector/main.c.orig Mon Feb 14 00:22:12 2005 >+++ cpufreq/src/cpufreq-selector/main.c Mon Feb 14 00:26:04 2005 >@@ -16,6 +16,7 @@ > * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > * > * Authors : Carlos Garc�a Campos <carlosgc@gnome.org> >+ * Joe Marcus Clarke <marcus@FreeBSD.org> > */ > > #include <glib-object.h> >@@ -26,6 +27,9 @@ > #include "cpufreq.h" > #include "cpufreq-sysfs.h" > #include "cpufreq-procfs.h" >+#ifdef __FreeBSD__ >+#include "cpufreq-sysctl.h" >+#endif /* __FreeBSD__ */ > > gint > main (gint argc, gchar **argv) >@@ -35,6 +39,9 @@ > gulong frequency = 0; > poptContext ctx; > gint nextopt; >+#ifdef __FreeBSD__ >+ size_t len; >+#endif /* __FreeBSD__ */ > CPUFreq *cfq; > > struct poptOption options[] = { >@@ -76,10 +83,15 @@ > > poptFreeContext(ctx); > >+#ifndef __FreeBSD__ > if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.6 kernel */ > cfq = CPUFREQ (cpufreq_sysfs_new ()); > } else if (g_file_test ("/proc/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.4 kernel */ > cfq = CPUFREQ (cpufreq_procfs_new ()); >+#else >+ if (sysctlbyname ("dev.cpu.0.freq", NULL, &len, NULL, 0) == 0) { >+ cfq = CPUFREQ (cpufreq_sysctl_new ()); >+#endif /* __FreeBSD __ */ > } else { > g_print ("No cpufreq support\n"); > return 1; >--- cpufreq/src/cpufreq-selector/cpufreq-sysctl.c.orig Mon Feb 14 00:38:52 2005 >+++ cpufreq/src/cpufreq-selector/cpufreq-sysctl.c Mon Feb 14 00:44:43 2005 >@@ -0,0 +1,235 @@ >+/* >+ * Copyright (C) 2001, 2002 Free Software Foundation >+ * >+ * This library 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 library 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 library; if not, write to the Free >+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. >+ * >+ * Authors : Joe Marcus Clarke <marcus@FreeBSD.org> >+ */ >+ >+#include <glib.h> >+#include <stdio.h> >+#include <stdlib.h> >+ >+#ifdef __FreeBSD__ >+#include <sys/types.h> >+#include <sys/sysctl.h> >+#endif /* __FreeBSD__ */ >+ >+#include "cpufreq-sysctl.h" >+ >+#define PARENT_TYPE TYPE_CPUFREQ >+ >+#define CPUFREQ_SYSCTL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), TYPE_CPUFREQ_SYSCTL, CPUFreqSysctlPrivate)) >+ >+static void cpufreq_sysctl_init (CPUFreqSysctl *cfq); >+static void cpufreq_sysctl_class_init (CPUFreqSysctlClass *klass); >+static void cpufreq_sysctl_finalize (GObject *object); >+ >+static void cpufreq_sysctl_set_governor (CPUFreq *cfq, const gchar *governor); >+static void cpufreq_sysctl_set_frequency (CPUFreq *cfq, gint frequency); >+ >+static void cpufreq_sysctl_setup (CPUFreqSysctl *cfq); >+ >+static GObjectClass *parent_class = NULL; >+ >+typedef struct _CPUFreqSysctlPrivate CPUFreqSysctlPrivate; >+ >+struct _CPUFreqSysctlPrivate >+{ >+ gint pmax; >+}; >+ >+GType cpufreq_sysctl_get_type () >+{ >+ static GType type = 0; >+ >+ if (!type) { >+ static const GTypeInfo info = { >+ sizeof (CPUFreqSysctlClass), >+ (GBaseInitFunc) NULL, >+ (GBaseFinalizeFunc) NULL, >+ (GClassInitFunc) cpufreq_sysctl_class_init, >+ NULL, >+ NULL, >+ sizeof (CPUFreqSysctl), >+ 0, >+ (GInstanceInitFunc) cpufreq_sysctl_init >+ }; >+ >+ type = g_type_register_static (PARENT_TYPE, "CPUFreqSysctl", >+ &info, 0); >+ } >+ >+ return type; >+} >+ >+static void >+cpufreq_sysctl_init (CPUFreqSysctl *cfq) >+{ >+ CPUFreqSysctlPrivate *private; >+ >+ g_return_if_fail (IS_CPUFREQ_SYSCTL (cfq)); >+ >+ private = CPUFREQ_SYSCTL_GET_PRIVATE (cfq); >+} >+ >+static void >+cpufreq_sysctl_class_init (CPUFreqSysctlClass *klass) >+{ >+ GObjectClass *object_class = G_OBJECT_CLASS (klass); >+ CPUFreqClass *cfq_class = CPUFREQ_CLASS (klass); >+ >+ parent_class = g_type_class_peek_parent (klass); >+ >+ g_type_class_add_private (klass, sizeof (CPUFreqSysctlPrivate)); >+ >+ cfq_class->set_governor = cpufreq_sysctl_set_governor; >+ cfq_class->set_frequency = cpufreq_sysctl_set_frequency; >+ >+ object_class->finalize = cpufreq_sysctl_finalize; >+} >+ >+static void >+cpufreq_sysctl_finalize (GObject *object) >+{ >+ if (G_OBJECT_CLASS (parent_class)->finalize) >+ (* G_OBJECT_CLASS (parent_class)->finalize) (object); >+} >+ >+CPUFreqSysctl * >+cpufreq_sysctl_new () >+{ >+ CPUFreqSysctl *cfq; >+ >+ cfq = g_object_new (TYPE_CPUFREQ_SYSCTL, NULL); >+ >+ cpufreq_sysctl_setup (cfq); >+ >+ return cfq; >+} >+ >+static void >+cpufreq_sysctl_set_governor (CPUFreq *cfq, const gchar *governor) >+{ >+ /* Not implemented. */ >+} >+ >+static void >+cpufreq_sysctl_set_frequency (CPUFreq *cfq, gint frequency) >+{ >+ gint cpu, i; >+ size_t len; >+ gchar *freq_oid; >+ >+ g_return_if_fail (IS_CPUFREQ_SYSCTL (cfq)); >+ >+ g_object_get (G_OBJECT (cfq), "n_cpu", &cpu, NULL); >+ >+ frequency = (gint) ((gdouble) frequency / 1000); /* Convert back to MHz*/ >+ >+ for (i = 0; i < cpu; i++) { >+ freq_oid = g_strdup_printf ("dev.cpu.%d.freq", i); >+ >+ sysctlbyname (freq_oid, NULL, &len, &frequency, sizeof (frequency)); >+ g_free (freq_oid); >+ } >+} >+ >+ >+static void >+cpufreq_sysctl_setup (CPUFreqSysctl *cfq) >+{ >+ guint cpu; >+ gint fmax, fmin; >+ gint pmax; >+ gint ifreq; >+ gint mib[4]; >+ gchar *governor, *levels; >+ gchar **levelsp, **frpr, **l; >+ size_t len; >+ CPUFreqSysctlPrivate *private; >+ >+ g_return_if_fail (IS_CPUFREQ_SYSCTL (cfq)); >+ >+ private = CPUFREQ_SYSCTL_GET_PRIVATE (cfq); >+ >+ pmax = 100; >+ fmax = 0; >+ fmin = 0; >+ ifreq = 0; >+ >+ private->pmax = pmax; >+ >+ len = sizeof (cpu); >+ >+ if (sysctlbyname ("hw.ncpu", &cpu, &len, NULL, 0) == -1) >+ cpu = 1; >+ >+ len = 4; >+ sysctlnametomib ("dev.cpu.0.freq_levels", mib, &len); >+ len = sizeof (levels); >+ >+ if (sysctl (mib, 4, NULL, &len, NULL, 0) == -1) { >+ g_warning ("Failed to fetch dev.cpu.0.freq_levels"); >+ return; >+ } >+ >+ levels = g_malloc (len); >+ if (sysctl (mib, 4, levels, &len, NULL, 0) == -1) { >+ g_warning ("Failed to fetch data for dev.cpu.0.freq_levels"); >+ return; >+ } >+ >+ levelsp = g_strsplit (levels, " ", 0); >+ g_free (levels); >+ >+ frpr = g_strsplit (levelsp[0], "/", 0); /* MAX */ >+ if (frpr && frpr[0] != NULL) >+ fmax = atoi (frpr[0]); >+ g_strfreev (frpr); >+ >+ for (l = levelsp; l && *l; l++) /* Walk to the last frequency */ >+ ; >+ >+ l --; >+ frpr = g_strsplit (*l, "/", 0); >+ if (frpr && frpr[0] != NULL) >+ fmin = atoi (frpr[0]); >+ >+ g_strfreev (frpr); >+ g_strfreev (levelsp); >+ >+ len = sizeof (ifreq); >+ if (sysctlbyname ("dev.cpu.0.freq", &ifreq, &len, NULL, 0) == -1) { >+ g_warning ("Failed to fetch data for dev.cpu.0.freq"); >+ return; >+ } >+ >+ if (ifreq == fmax) >+ governor = g_strdup ("performance"); >+ else if (ifreq == fmin) >+ governor = g_strdup ("economy"); >+ else >+ governor = g_strdup ("other"); >+ >+ fmax *= 1000; >+ fmin *= 1000; >+ >+ g_object_set (G_OBJECT (cfq), "n_cpu", cpu, >+ "sc_max", fmax, "sc_min", fmin, >+ "governor", governor, NULL); >+ >+ g_free (governor); >+} Thank you very much for the patch.
Sorry, I forgot to remove unrelevant code :-P I hope you can find the comments . . .
Did this make it in?
Ping?
This code has still not been committed, but it no longer applies to the new gnome-applets. I have a new diff, but I'm still debugging it.
I recall that libcpufreq support has been added to the applet. Does this abstraction already have the required support?
There is no libcpufreq port for FreeBSD of which I am aware. I added back the sysctl backend with my patches.
bugzilla.gnome.org is being replaced by gitlab.gnome.org. We are closing all old bug reports in Bugzilla which have not seen updates for many years. If you can still reproduce this issue in a currently supported version of GNOME (currently that would be 3.38), then please feel free to report it at https://gitlab.gnome.org/GNOME/gnome-applets/-/issues/ Thank you for reporting this issue and we are sorry it could not be fixed.