1 /*
2 * CPU usage plugin to fbpanel
3 *
4 * Copyright (C) 2004 by Alexandre Pereira da Silva <alexandre.pereira@poli.usp.br>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22 /*
23 * A little bug fixed by Mykola <mykola@2ka.mipt.ru>:)
24 * FreeBSD support added by Andreas Wiese <aw@instandbesetzt.net>
25 */
26
27
28 #if defined __FreeBSD__ || defined __DragonFly__
29 #include <sys/types.h>
30 #include <sys/time.h>
31 #include <sys/resource.h>
32 #include <sys/sysctl.h>
33 #include <stdio.h>
34 #endif
35
36 #include "misc.h"
37 #include "../chart/chart.h"
38
39 //#define DEBUGPRN
40 #include "dbg.h"
41
42 /* cpu.c */
43 struct cpu_stat {
44 gulong u, n, s, i, w; // user, nice, system, idle, wait
45 };
46
47 typedef struct {
48 chart_priv chart;
49 struct cpu_stat cpu_prev;
50 int timer;
51 gchar *colors[1];
52 } cpu_priv;
53
54
55
56 static chart_class *k;
57
58 static void cpu_destructor(plugin_instance *p);
59
60 #if defined __linux__
61 static int
cpu_get_load(cpu_priv * c)62 cpu_get_load(cpu_priv *c)
63 {
64 gfloat a, b;
65 struct cpu_stat cpu, cpu_diff;
66 FILE *stat;
67 float total;
68 gchar buf[40];
69
70 ENTER;
71 total = 0;
72 stat = fopen("/proc/stat", "r");
73 if(!stat)
74 goto end;
75 fscanf(stat, "cpu %lu %lu %lu %lu %lu", &cpu.u, &cpu.n, &cpu.s,
76 &cpu.i, &cpu.w);
77 fclose(stat);
78
79 cpu_diff.u = cpu.u - c->cpu_prev.u;
80 cpu_diff.n = cpu.n - c->cpu_prev.n;
81 cpu_diff.s = cpu.s - c->cpu_prev.s;
82 cpu_diff.i = cpu.i - c->cpu_prev.i;
83 cpu_diff.w = cpu.w - c->cpu_prev.w;
84 c->cpu_prev = cpu;
85
86 a = cpu_diff.u + cpu_diff.n + cpu_diff.s;
87 b = a + cpu_diff.i + cpu_diff.w;
88 total = b ? a / b : 1.0;
89
90 end:
91 DBG("total=%f a=%f b=%f\n", total, a, b);
92 g_snprintf(buf, sizeof(buf), "<b>Cpu:</b> %d%%", (int)(total * 100));
93 gtk_widget_set_tooltip_markup(((plugin_instance *)c)->pwid, buf);
94 k->add_tick(&c->chart, &total);
95 RET(TRUE);
96
97 }
98 #elif defined __FreeBSD__ || defined __DragonFly__
99 static int
cpu_get_load(cpu_priv * c)100 cpu_get_load(cpu_priv * c)
101 {
102 static int mib[2] = {-1, -1}, init = 0;
103 static size_t j;
104 long ct[CPUSTATES];
105
106 gfloat a , b;
107 struct cpu_stat cpu;
108 float total;
109 gchar buf[40];
110
111 ENTER;
112 total = 0;
113
114 if (init == 0) {
115 j = 2;
116 if (sysctlnametomib("kern.cp_time", mib, &j) == -1) {
117 DBG("Couldn't get mib for kern.cp_time");
118 RET(FALSE);
119 }
120 c->cpu_prev.u = 0;
121 c->cpu_prev.n = 0;
122 c->cpu_prev.s = 0;
123 c->cpu_prev.i = 0;
124 c->cpu_prev.w = 0;
125 init = 1;
126 j = sizeof(ct);
127 }
128 if (sysctl(mib, 2, ct, &j, NULL, 0) == -1) {
129 DBG("Couldn't get cpu stats");
130 RET(FALSE);
131 }
132
133 a = ct[CP_USER] + ct[CP_NICE] + ct[CP_SYS] + ct[CP_INTR] -
134 (c->cpu_prev.u + c->cpu_prev.n + c->cpu_prev.s + c->cpu_prev.i);
135 b = a + ct[CP_IDLE] - c->cpu_prev.w;
136 total = b ? (float)a / b : 1.0;
137
138 c->cpu_prev.u = ct[CP_USER];
139 c->cpu_prev.n = ct[CP_NICE];
140 c->cpu_prev.s = ct[CP_SYS] ;
141 c->cpu_prev.i = ct[CP_INTR];
142 c->cpu_prev.w = ct[CP_IDLE];
143
144 end:
145 DBG("total=%f a=%f b=%f\n", total, a, b);
146 g_snprintf(buf, sizeof(buf), "<b>Cpu:</b> %d%%", (int)(total * 100));
147 gtk_widget_set_tooltip_markup(((plugin_instance *) c)->pwid, buf);
148 k->add_tick(&c->chart, &total);
149 RET(TRUE);
150
151 }
152 #else
153 static int
cpu_get_load(cpu_priv * c)154 cpu_get_load(cpu_priv *c)
155 {
156 ENTER;
157 RET(0);
158 }
159 #endif
160
161 static int
cpu_constructor(plugin_instance * p)162 cpu_constructor(plugin_instance *p)
163 {
164 cpu_priv *c;
165
166 if (!(k = class_get("chart")))
167 RET(0);
168 if (!PLUGIN_CLASS(k)->constructor(p))
169 RET(0);
170 c = (cpu_priv *) p;
171 c->colors[0] = "green";
172 XCG(p->xc, "Color", &c->colors[0], str);
173
174 k->set_rows(&c->chart, 1, c->colors);
175 gtk_widget_set_tooltip_markup(((plugin_instance *)c)->pwid, "<b>Cpu</b>");
176 cpu_get_load(c);
177 c->timer = g_timeout_add(2000, (GSourceFunc) cpu_get_load, (gpointer) c);
178 RET(1);
179 }
180
181
182 static void
cpu_destructor(plugin_instance * p)183 cpu_destructor(plugin_instance *p)
184 {
185 cpu_priv *c = (cpu_priv *) p;
186
187 ENTER;
188 g_source_remove(c->timer);
189 PLUGIN_CLASS(k)->destructor(p);
190 class_put("chart");
191 RET();
192 }
193
194
195
196 static plugin_class class = {
197 .count = 0,
198 .type = "cpu",
199 .name = "Cpu usage",
200 .version = "1.0",
201 .description = "Display cpu usage",
202 .priv_size = sizeof(cpu_priv),
203 .constructor = cpu_constructor,
204 .destructor = cpu_destructor,
205 };
206
207 static plugin_class *class_ptr = (plugin_class *) &class;
208