/cpufreq/src/cpufreq-monitor.c

https://github.com/mate-desktop/mate-applets · C · 395 lines · 300 code · 70 blank · 25 comment · 26 complexity · ffe311090ee815da6f0652f92ee8a6df MD5 · raw file

  1. /*
  2. * MATE CPUFreq Applet
  3. * Copyright (C) 2004 Carlos Garcia Campos <carlosgc@gnome.org>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public
  16. * License along with this library; if not, write to the Free
  17. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
  18. *
  19. * Authors : Carlos García Campos <carlosgc@gnome.org>
  20. */
  21. #include "cpufreq-monitor.h"
  22. #define CPUFREQ_MONITOR_INTERVAL 1
  23. /* Properties */
  24. enum {
  25. PROP_0,
  26. PROP_CPU,
  27. PROP_ONLINE,
  28. PROP_FREQUENCY,
  29. PROP_MAX_FREQUENCY,
  30. PROP_GOVERNOR
  31. };
  32. /* Signals */
  33. enum {
  34. SIGNAL_CHANGED,
  35. N_SIGNALS
  36. };
  37. struct _CPUFreqMonitorPrivate {
  38. guint cpu;
  39. gboolean online;
  40. gint cur_freq;
  41. gint max_freq;
  42. gchar *governor;
  43. GList *available_freqs;
  44. GList *available_govs;
  45. guint timeout_handler;
  46. gboolean changed;
  47. };
  48. static void cpufreq_monitor_finalize (GObject *object);
  49. static void cpufreq_monitor_set_property (GObject *object,
  50. guint prop_id,
  51. const GValue *value,
  52. GParamSpec *spec);
  53. static void cpufreq_monitor_get_property (GObject *object,
  54. guint prop_id,
  55. GValue *value,
  56. GParamSpec *spec);
  57. static guint signals[N_SIGNALS] = { 0 };
  58. G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CPUFreqMonitor, cpufreq_monitor, G_TYPE_OBJECT)
  59. static void
  60. cpufreq_monitor_init (CPUFreqMonitor *monitor)
  61. {
  62. monitor->priv = cpufreq_monitor_get_instance_private (monitor);
  63. monitor->priv->governor = NULL;
  64. monitor->priv->available_freqs = NULL;
  65. monitor->priv->available_govs = NULL;
  66. monitor->priv->timeout_handler = 0;
  67. monitor->priv->changed = FALSE;
  68. }
  69. static void
  70. cpufreq_monitor_class_init (CPUFreqMonitorClass *klass)
  71. {
  72. GObjectClass *object_class = G_OBJECT_CLASS (klass);
  73. object_class->set_property = cpufreq_monitor_set_property;
  74. object_class->get_property = cpufreq_monitor_get_property;
  75. /* Public virtual methods */
  76. klass->run = NULL;
  77. klass->get_available_frequencies = NULL;
  78. klass->get_available_governors = NULL;
  79. /* Porperties */
  80. g_object_class_install_property (object_class,
  81. PROP_CPU,
  82. g_param_spec_uint ("cpu",
  83. "CPU",
  84. "The cpu to monitor",
  85. 0,
  86. G_MAXUINT,
  87. 0,
  88. G_PARAM_CONSTRUCT |
  89. G_PARAM_READWRITE));
  90. g_object_class_install_property (object_class,
  91. PROP_ONLINE,
  92. g_param_spec_boolean ("online",
  93. "Online",
  94. "Whether cpu is online",
  95. TRUE,
  96. G_PARAM_READWRITE));
  97. g_object_class_install_property (object_class,
  98. PROP_FREQUENCY,
  99. g_param_spec_int ("frequency",
  100. "Frequency",
  101. "The current cpu frequency",
  102. 0,
  103. G_MAXINT,
  104. 0,
  105. G_PARAM_READWRITE));
  106. g_object_class_install_property (object_class,
  107. PROP_MAX_FREQUENCY,
  108. g_param_spec_int ("max-frequency",
  109. "MaxFrequency",
  110. "The max cpu frequency",
  111. -1,
  112. G_MAXINT,
  113. 0,
  114. G_PARAM_READWRITE));
  115. g_object_class_install_property (object_class,
  116. PROP_GOVERNOR,
  117. g_param_spec_string ("governor",
  118. "Governor",
  119. "The current cpufreq governor",
  120. NULL,
  121. G_PARAM_READWRITE));
  122. /* Signals */
  123. signals[SIGNAL_CHANGED] =
  124. g_signal_new ("changed",
  125. G_TYPE_FROM_CLASS (klass),
  126. G_SIGNAL_RUN_LAST,
  127. G_STRUCT_OFFSET (CPUFreqMonitorClass, changed),
  128. NULL, NULL,
  129. g_cclosure_marshal_VOID__VOID,
  130. G_TYPE_NONE, 0);
  131. object_class->finalize = cpufreq_monitor_finalize;
  132. }
  133. static void
  134. cpufreq_monitor_finalize (GObject *object)
  135. {
  136. CPUFreqMonitor *monitor = CPUFREQ_MONITOR (object);
  137. monitor->priv->online = FALSE;
  138. if (monitor->priv->timeout_handler > 0) {
  139. g_source_remove (monitor->priv->timeout_handler);
  140. monitor->priv->timeout_handler = 0;
  141. }
  142. if (monitor->priv->governor) {
  143. g_free (monitor->priv->governor);
  144. monitor->priv->governor = NULL;
  145. }
  146. if (monitor->priv->available_freqs) {
  147. g_list_free_full (monitor->priv->available_freqs, g_free);
  148. monitor->priv->available_freqs = NULL;
  149. }
  150. if (monitor->priv->available_govs) {
  151. g_list_free_full (monitor->priv->available_govs, g_free);
  152. monitor->priv->available_govs = NULL;
  153. }
  154. G_OBJECT_CLASS (cpufreq_monitor_parent_class)->finalize (object);
  155. }
  156. static void
  157. cpufreq_monitor_set_property (GObject *object,
  158. guint prop_id,
  159. const GValue *value,
  160. GParamSpec *spec)
  161. {
  162. CPUFreqMonitor *monitor;
  163. monitor = CPUFREQ_MONITOR (object);
  164. switch (prop_id) {
  165. case PROP_CPU: {
  166. guint cpu = g_value_get_uint (value);
  167. if (cpu != monitor->priv->cpu) {
  168. monitor->priv->cpu = cpu;
  169. monitor->priv->changed = TRUE;
  170. }
  171. break;
  172. }
  173. case PROP_ONLINE:
  174. monitor->priv->online = g_value_get_boolean (value);
  175. break;
  176. case PROP_FREQUENCY: {
  177. gint freq = g_value_get_int (value);
  178. if (freq != monitor->priv->cur_freq) {
  179. monitor->priv->cur_freq = freq;
  180. monitor->priv->changed = TRUE;
  181. }
  182. break;
  183. }
  184. case PROP_MAX_FREQUENCY: {
  185. gint freq = g_value_get_int (value);
  186. if (freq != monitor->priv->max_freq) {
  187. monitor->priv->max_freq = freq;
  188. monitor->priv->changed = TRUE;
  189. }
  190. break;
  191. }
  192. case PROP_GOVERNOR: {
  193. const gchar *gov = g_value_get_string (value);
  194. if (monitor->priv->governor) {
  195. if (g_ascii_strcasecmp (gov, monitor->priv->governor) != 0) {
  196. g_free (monitor->priv->governor);
  197. monitor->priv->governor = gov ? g_strdup (gov) : NULL;
  198. monitor->priv->changed = TRUE;
  199. }
  200. } else {
  201. monitor->priv->governor = gov ? g_strdup (gov) : NULL;
  202. monitor->priv->changed = TRUE;
  203. }
  204. break;
  205. }
  206. default:
  207. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
  208. }
  209. }
  210. static void
  211. cpufreq_monitor_get_property (GObject *object,
  212. guint prop_id,
  213. GValue *value,
  214. GParamSpec *spec)
  215. {
  216. CPUFreqMonitor *monitor;
  217. monitor = CPUFREQ_MONITOR (object);
  218. switch (prop_id) {
  219. case PROP_CPU:
  220. g_value_set_uint (value, monitor->priv->cpu);
  221. break;
  222. case PROP_ONLINE:
  223. g_value_set_boolean (value, monitor->priv->online);
  224. break;
  225. case PROP_FREQUENCY:
  226. g_value_set_int (value, monitor->priv->cur_freq);
  227. break;
  228. case PROP_MAX_FREQUENCY:
  229. g_value_set_int (value, monitor->priv->max_freq);
  230. break;
  231. case PROP_GOVERNOR:
  232. g_value_set_string (value, monitor->priv->governor);
  233. break;
  234. default:
  235. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
  236. }
  237. }
  238. static gboolean
  239. cpufreq_monitor_run_cb (CPUFreqMonitor *monitor)
  240. {
  241. CPUFreqMonitorClass *class;
  242. gboolean retval = FALSE;
  243. class = CPUFREQ_MONITOR_GET_CLASS (monitor);
  244. if (class->run)
  245. retval = class->run (monitor);
  246. if (monitor->priv->changed) {
  247. g_signal_emit (monitor, signals[SIGNAL_CHANGED], 0);
  248. monitor->priv->changed = FALSE;
  249. }
  250. return retval;
  251. }
  252. void
  253. cpufreq_monitor_run (CPUFreqMonitor *monitor)
  254. {
  255. g_return_if_fail (CPUFREQ_IS_MONITOR (monitor));
  256. if (monitor->priv->timeout_handler > 0)
  257. return;
  258. monitor->priv->timeout_handler =
  259. g_timeout_add_seconds (CPUFREQ_MONITOR_INTERVAL,
  260. (GSourceFunc) cpufreq_monitor_run_cb,
  261. (gpointer) monitor);
  262. }
  263. GList *
  264. cpufreq_monitor_get_available_frequencies (CPUFreqMonitor *monitor)
  265. {
  266. CPUFreqMonitorClass *class;
  267. g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), NULL);
  268. if (!monitor->priv->online)
  269. return NULL;
  270. if (monitor->priv->available_freqs)
  271. return monitor->priv->available_freqs;
  272. class = CPUFREQ_MONITOR_GET_CLASS (monitor);
  273. if (class->get_available_frequencies)
  274. monitor->priv->available_freqs = class->get_available_frequencies (monitor);
  275. return monitor->priv->available_freqs;
  276. }
  277. GList *
  278. cpufreq_monitor_get_available_governors (CPUFreqMonitor *monitor)
  279. {
  280. CPUFreqMonitorClass *class;
  281. g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), NULL);
  282. if (!monitor->priv->online)
  283. return NULL;
  284. if (monitor->priv->available_govs)
  285. return monitor->priv->available_govs;
  286. class = CPUFREQ_MONITOR_GET_CLASS (monitor);
  287. if (class->get_available_governors) {
  288. monitor->priv->available_govs = class->get_available_governors (monitor);
  289. }
  290. return monitor->priv->available_govs;
  291. }
  292. guint
  293. cpufreq_monitor_get_cpu (CPUFreqMonitor *monitor)
  294. {
  295. g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), 0);
  296. return monitor->priv->cpu;
  297. }
  298. void
  299. cpufreq_monitor_set_cpu (CPUFreqMonitor *monitor, guint cpu)
  300. {
  301. g_return_if_fail (CPUFREQ_IS_MONITOR (monitor));
  302. g_object_set (G_OBJECT (monitor),
  303. "cpu", cpu, NULL);
  304. }
  305. gint
  306. cpufreq_monitor_get_frequency (CPUFreqMonitor *monitor)
  307. {
  308. g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), -1);
  309. return monitor->priv->cur_freq;
  310. }
  311. const gchar *
  312. cpufreq_monitor_get_governor (CPUFreqMonitor *monitor)
  313. {
  314. g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), NULL);
  315. return monitor->priv->governor;
  316. }
  317. gint
  318. cpufreq_monitor_get_percentage (CPUFreqMonitor *monitor)
  319. {
  320. g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), -1);
  321. if (monitor->priv->max_freq > 0) {
  322. return ((monitor->priv->cur_freq * 100) / monitor->priv->max_freq);
  323. }
  324. return -1;
  325. }