Package: wmmon
Version: 1.0b2-14
Severity: wishlist
Tags: patch

If you use wmmon dockapp, the CPU stress meter shows the average of all 
processors. So if a processus takes all CPU on one processor, you don't see it. 
More informations and patch here -> http://delavergne.me/wmmon/

-- System Information:
Debian Release: squeeze/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)

Kernel: Linux 2.6.30.4 (SMP w/4 CPU cores)
Locale: LANG=fr_FR, LC_CTYPE=fr_FR (charmap=ISO-8859-1)
Shell: /bin/sh linked to /bin/bash

Versions of packages wmmon depends on:
ii  libc6                     2.9-4          GNU C Library: Shared libraries
ii  libx11-6                  2:1.2-1        X11 client-side library
ii  libxext6                  2:1.0.4-1      X11 miscellaneous extension librar
ii  libxpm4                   1:3.5.7-1      X11 pixmap library
ii  xlibs                     6.9.0.dfsg.1-4 X Window System client libraries m

wmmon recommends no packages.

wmmon suggests no packages.

-- no debconf information
--- wmmon-1.0b2.orig/wmmon/wmmon.c
+++ wmmon-1.0b2/wmmon/wmmon.c
@@ -28,6 +28,8 @@
 	Changes:
 	----
 
+	17/10/2009 (Romuald Delavergne, [email protected])
+		* Support SMP processors in realtime CPU stress meter
 	15/05/2004 (Simon Law, [email protected])
 		* Support disabling of mode-cycling
 	23/10/2003 (Simon Law, [email protected])
@@ -109,6 +111,7 @@
 
 int	stat_current = 0; /* now global */
 int mode_cycling = 1; /* Allow mode-cycling */
+int cpu_avg_max  = 0; /* CPU stress meter with average and max for SMP */
 FILE	*fp_meminfo;
 FILE	*fp_stat;
 FILE	*fp_loadavg;
@@ -148,6 +151,9 @@ int main(int argc, char *argv[]) {
 			case 'l' :
 				mode_cycling = 0;
 				break;
+			case 'c' :
+				cpu_avg_max = 1;
+				break;
 			case 'i' :
 				stat_current = 1;
 				break;
@@ -174,6 +180,7 @@ int main(int argc, char *argv[]) {
 |* wmmon_routine															   *|
 \*******************************************************************************/
 
+#define MAX_CPU (10) /* depends on graph height */
 typedef struct {
 
 	char	name[5];			/* "cpu0..cpuz", eventually.. :) */
@@ -183,6 +190,11 @@ typedef struct {
 	long	statlast;
 	long	rt_idle;
 	long	idlelast;
+	/* Processors stats */
+	long	*cpu_stat;
+	long	*cpu_last;
+	long	*idle_stat;
+	long	*idle_last;
 	
 } stat_dev;
 
@@ -194,11 +206,14 @@ char		*right_action;
 char		*middle_action;
 
 
+int	nb_cpu, cpu_max;
+int getNbCPU(void);
+unsigned long getWidth(long, long);
 int checksysdevs(void);
-void get_statistics(char *, long *, long *, long *);
+void get_statistics(char *, long *, long *, long *, long *, long *);
 void DrawActive(char *);
 
-void update_stat_cpu(stat_dev *);
+void update_stat_cpu(stat_dev *, long *, long *);
 void update_stat_io(stat_dev *);
 void update_stat_mem(stat_dev *st, stat_dev *st2);
 void update_stat_swp(stat_dev *);
@@ -225,6 +240,8 @@ void wmmon_routine(int argc, char **argv
 
 	long		istat;
 	long		idle;
+	long		*istat2;
+	long		*idle2;
 
 	FILE		*fp;
 	char		*conffile = NULL;
@@ -276,6 +293,21 @@ void wmmon_routine(int argc, char **argv
 
 	stat_online = checksysdevs();
 
+	nb_cpu = getNbCPU();
+	stat_device[0].cpu_stat = calloc(nb_cpu, sizeof(long));
+	stat_device[0].cpu_last = calloc(nb_cpu, sizeof(long));
+	stat_device[0].idle_stat = calloc(nb_cpu, sizeof(long));
+	stat_device[0].idle_last = calloc(nb_cpu, sizeof(long));
+	if (!stat_device[0].cpu_stat || !stat_device[0].cpu_last || !stat_device[0].idle_stat || !stat_device[0].idle_last) {
+		fprintf(stderr, "%s: Unable to alloc memory !\n", argv[0]);
+		exit(1);
+	}
+	istat2 = calloc(nb_cpu, sizeof(long));
+	idle2 = calloc(nb_cpu, sizeof(long));
+	if (!istat2 || !idle2) {
+		fprintf(stderr, "%s: Unable to alloc memory !!\n", argv[0]);
+		exit(1);
+	}
 
 	openXwindow(argc, argv, wmmon_master_xpm, wmmon_mask_bits, wmmon_mask_width, wmmon_mask_height);
 
@@ -288,9 +320,16 @@ void wmmon_routine(int argc, char **argv
 
 	/* Collect information on each panel */
 	for (i=0; i<stat_online; i++) {
-		get_statistics(stat_device[i].name, &k, &istat, &idle);
+		get_statistics(stat_device[i].name, &k, &istat, &idle, istat2, idle2);
 		stat_device[i].statlast = istat;
 		stat_device[i].idlelast = idle;
+		if (i == 0 && nb_cpu > 1) {
+			int cpu;
+			for (cpu = 0; cpu < nb_cpu; cpu++) {
+				stat_device[i].cpu_last[cpu] = istat2[cpu];
+				stat_device[i].idle_last[cpu] = idle2[cpu];
+			}
+		}
 	}
 
 	/* Set the mask for the current window */
@@ -320,7 +359,7 @@ void wmmon_routine(int argc, char **argv
 		waitpid(0, NULL, WNOHANG);
 
 
-		update_stat_cpu(&stat_device[0]);
+		update_stat_cpu(&stat_device[0], istat2, idle2);
 		update_stat_io(&stat_device[1]);
 
 		if(stat_current == 2) {
@@ -334,13 +373,26 @@ void wmmon_routine(int argc, char **argv
 			/* Load ding is 45 pixels hoog */
 			copyXPMArea(0, 64, 32, 12, 28, 4);
 
-			j = (stat_device[i].rt_stat + stat_device[i].rt_idle);
-			if (j != 0) {
-				j = (stat_device[i].rt_stat * 100) / j;
+			if (i == 0 && nb_cpu > 1) {
+				if (nb_cpu > MAX_CPU || cpu_avg_max) {
+					/* show average CPU */
+					j = getWidth(stat_device[i].rt_stat, stat_device[i].rt_idle);
+					copyXPMArea(32, 64, j, 6, 28, 4);
+					/* Show max CPU */
+					j = getWidth(stat_device[i].cpu_stat[cpu_max], stat_device[i].idle_stat[cpu_max]);
+					copyXPMArea(32, 70, j, 6, 28, 10);
+				} else {
+					int cpu;
+					for (cpu = 0; cpu < nb_cpu; cpu++) {
+						j = getWidth(stat_device[i].cpu_stat[cpu], stat_device[i].idle_stat[cpu]);
+						copyXPMArea(32, 65, j, MAX_CPU/nb_cpu, 28, 5+(MAX_CPU/nb_cpu)*cpu);
+					}
+				}
+			}
+			else {
+				j = getWidth(stat_device[i].rt_stat, stat_device[i].rt_idle);
+				copyXPMArea(32, 64, j, 12, 28, 4);
 			}
-			j = j * 0.32;
-			if (j > 32) j = 32;
-			copyXPMArea(32, 64, j, 12, 28, 4);
 		} else {
 			/* Nu zal ie wel 3 zijn. */
 
@@ -487,11 +539,10 @@ void wmmon_routine(int argc, char **argv
 	}
 }
 
-void update_stat_cpu(stat_dev *st) {
-
+void update_stat_cpu(stat_dev *st, long *istat2, long *idle2) {
 	long	k, istat, idle;
 
-	get_statistics(st->name, &k, &istat, &idle);
+	get_statistics(st->name, &k, &istat, &idle, istat2, idle2);
 
 	st->rt_idle = idle - st->idlelast;
 	st->idlelast = idle;
@@ -499,6 +550,26 @@ void update_stat_cpu(stat_dev *st) {
 	st->rt_stat = istat - st->statlast;
 	st->statlast = istat;
 
+	if (nb_cpu > 1) {
+		int cpu;
+		unsigned long  max, j;
+		cpu_max = 0; max = 0;
+		for (cpu = 0; cpu < nb_cpu; cpu++) {
+			st->idle_stat[cpu] = idle2[cpu] - st->idle_last[cpu];
+			st->idle_last[cpu] = idle2[cpu];
+
+			st->cpu_stat[cpu] = istat2[cpu] - st->cpu_last[cpu];
+			st->cpu_last[cpu] = istat2[cpu];
+
+			j = st->cpu_stat[cpu] + st->idle_stat[cpu];
+			if (j != 0)  j = (st->cpu_stat[cpu] << 7) / j;
+			if (j > max) {
+				max = j;
+				cpu_max = cpu;
+			}
+		}
+	}
+
 	st->his[54] += k;
 	st->hisaddcnt += 1;
 }
@@ -508,7 +579,7 @@ void update_stat_io(stat_dev *st) {
 	long			j, k, istat, idle;
 	static long		maxdiskio = 0;
 
-	get_statistics(st->name, &k, &istat, &idle);
+	get_statistics(st->name, &k, &istat, &idle, NULL, NULL);
 
 	st->rt_idle = idle - st->idlelast;
 	st->idlelast = idle;
@@ -608,7 +679,7 @@ void update_stat_swp(stat_dev *st) {
 |* get_statistics															   *|
 \*******************************************************************************/
 
-void get_statistics(char *devname, long *is, long *ds, long *idle) {
+void get_statistics(char *devname, long *is, long *ds, long *idle, long *ds2, long *idle2) {
 
 	int	i;
 	static char *line = NULL;
@@ -624,15 +695,27 @@ void get_statistics(char *devname, long 
 	if (!strncmp(devname, "cpu", 3)) {
 		fseek(fp_stat, 0, SEEK_SET);
 		while ((getline(&line, &line_size, fp_stat)) > 0) {
-			if (strstr(line, "cpu ")) {
+			if (strstr(line, "cpu")) {
+				int cpu = -1; /* by default, cumul stats => average */
+				if (!strstr(line, "cpu ")) {
+					sscanf(line, "cpu%d", &cpu);
+					ds2[cpu] = 0;
+					idle2[cpu] = 0;
+				}
 				p = strtok(line, tokens);
 				/* 1..3, 4 == idle, we don't want idle! */
 				for (i=0; i<3; i++) {
 					p = strtok(NULL, tokens);
-					*ds += atol(p);
+					if (cpu == -1)
+						*ds += atol(p);
+					else
+						ds2[cpu] += atol(p);
 				}
 				p = strtok(NULL, tokens);
-				*idle = atol(p);
+				if (cpu == -1)
+					*idle = atol(p);
+				else
+					idle2[cpu] = atol(p);
 			}
 		}
 		fp_loadavg = freopen("/proc/loadavg", "r", fp_loadavg);
@@ -676,6 +759,43 @@ void get_statistics(char *devname, long 
 }
 
 /*******************************************************************************\
+|* getWidth
+\*******************************************************************************/
+
+unsigned long getWidth(long actif, long idle) {
+	unsigned long j;
+
+	j = (actif + idle);
+	if (j != 0) {
+		j = (actif * 100) / j;
+	}
+	j = j * 0.32;
+	if (j > 32) j = 32;
+
+	return j;
+}
+
+
+/*******************************************************************************\
+|* getNbCPU																   *|
+\*******************************************************************************/
+
+int getNbCPU(void) {
+	static char *line = NULL;
+	static size_t line_size = 0;
+	int cpu = 0;
+
+	fseek(fp_stat, 0, SEEK_SET);
+	while ((getline(&line, &line_size, fp_stat)) > 0) {
+		if (strstr(line, "cpu") && !strstr(line, "cpu "))
+			sscanf(line, "cpu%d", &cpu);
+	}
+
+	return cpu+1;
+}
+
+
+/*******************************************************************************\
 |* checksysdevs																   *|
 \*******************************************************************************/
 
@@ -806,6 +926,8 @@ void usage(char *name) {
 	printf("  -display DISPLAY     contact the DISPLAY X server\n");
 	printf("  -geometry GEOMETRY   position the clock at GEOMETRY\n");
 	printf("  -l                   locked view - cannot cycle modes\n");
+	printf("  -c                   show average and max CPU for SMP machine.\n");
+	printf("                       default if there is more than %d processors\n", MAX_CPU);
 	printf("  -i                   start in Disk I/O mode\n");
 	printf("  -s                   start in System Info mode\n");
 	printf("  -h                   display this help and exit\n");

Reply via email to