logo       

[PATCH 9/11] improve cpu applet for multi cpu systems: msg#00022

window-managers.icewm.devel

Subject: [PATCH 9/11] improve cpu applet for multi cpu systems

a) change the TaskBar::updateLayout() to use a dynamic array
b) change types of cpu stats to unsigned long long
c) add steal cpu state (in linux 2.6.11)
d) add option to display all available cpus (the multi cpu code is only
tested on linux). this is controlled with the CPUStatusCombine option

bert wesarg

---
diff -urp old/src/acpustatus.cc new/src/acpustatus.cc
--- old/src/acpustatus.cc 2006-09-10 18:12:10.000000000 +0200
+++ new/src/acpustatus.cc 2006-11-12 19:28:14.061396350 +0100
@@ -60,11 +60,17 @@

extern ref<YPixmap> taskbackPixmap;

-CPUStatus::CPUStatus(YWindow *aParent): YWindow(aParent) {
- cpu = new int *[taskBarCPUSamples];
+CPUStatus::CPUStatus(YWindow *aParent, int cpuid) : YWindow(aParent) {
+ fCpuID = cpuid;

- for (int a(0); a < taskBarCPUSamples; a++)
- cpu[a] = new int[IWM_STATES];
+ cpu = new unsigned long long *[taskBarCPUSamples];
+
+ for (int a(0); a < taskBarCPUSamples; a++) {
+ cpu[a] = new unsigned long long[IWM_STATES];
+ memset(cpu[a], 0, IWM_STATES * sizeof(cpu[0][0]));
+ cpu[a][IWM_IDLE] = 1;
+ }
+ memset(last_cpu, 0, sizeof(last_cpu));

fUpdateTimer = new YTimer(taskBarCPUDelay);
if (fUpdateTimer) {
@@ -72,24 +78,16 @@ CPUStatus::CPUStatus(YWindow *aParent):
fUpdateTimer->startTimer();
}

- color[IWM_USER] = new YColor(clrCpuUser);
- color[IWM_NICE] = new YColor(clrCpuNice);
- color[IWM_SYS] = new YColor(clrCpuSys);
- color[IWM_INTR] = new YColor(clrCpuIntr);
- color[IWM_IOWAIT] = new YColor(clrCpuIoWait);
+ color[IWM_USER] = new YColor(clrCpuUser);
+ color[IWM_NICE] = new YColor(clrCpuNice);
+ color[IWM_SYS] = new YColor(clrCpuSys);
+ color[IWM_IDLE] = *clrCpuIdle ? new YColor(clrCpuIdle) : NULL;
+ color[IWM_IOWAIT] = new YColor(clrCpuIoWait);
+ color[IWM_INTR] = new YColor(clrCpuIntr);
color[IWM_SOFTIRQ] = new YColor(clrCpuSoftIrq);
- color[IWM_IDLE] = *clrCpuIdle
- ? new YColor(clrCpuIdle) : NULL;
- for (int i = 0; i < taskBarCPUSamples; i++) {
- cpu[i][IWM_USER] = cpu[i][IWM_NICE] =
- cpu[i][IWM_SYS] = cpu[i][IWM_INTR] =
- cpu[i][IWM_IOWAIT] = cpu[i][IWM_SOFTIRQ] = 0;
- cpu[i][IWM_IDLE] = 1;
- }
+ color[IWM_STEAL] = new YColor(clrCpuSteal);
+
setSize(taskBarCPUSamples, 20);
- last_cpu[IWM_USER] = last_cpu[IWM_NICE] = last_cpu[IWM_SYS] =
- last_cpu[IWM_IDLE] = last_cpu[IWM_INTR] =
- last_cpu[IWM_IOWAIT] = last_cpu[IWM_SOFTIRQ] = 0;
getStatus();
updateStatus();
updateToolTip();
@@ -100,59 +98,75 @@ CPUStatus::~CPUStatus() {
delete cpu[a]; cpu[a] = 0;
}
delete cpu; cpu = 0;
- delete color[IWM_USER]; color[IWM_USER] = 0;
- delete color[IWM_NICE]; color[IWM_NICE] = 0;
- delete color[IWM_SYS]; color[IWM_SYS] = 0;
- delete color[IWM_IDLE]; color[IWM_IDLE] = 0;
- delete color[IWM_INTR]; color[IWM_INTR] = 0;
- delete color[IWM_IOWAIT]; color[IWM_IOWAIT] = 0;
+ delete color[IWM_USER]; color[IWM_USER] = 0;
+ delete color[IWM_NICE]; color[IWM_NICE] = 0;
+ delete color[IWM_SYS]; color[IWM_SYS] = 0;
+ delete color[IWM_IDLE]; color[IWM_IDLE] = 0;
+ delete color[IWM_INTR]; color[IWM_INTR] = 0;
+ delete color[IWM_IOWAIT]; color[IWM_IOWAIT] = 0;
delete color[IWM_SOFTIRQ]; color[IWM_SOFTIRQ] = 0;
+ delete color[IWM_STEAL]; color[IWM_STEAL] = 0;
}

void CPUStatus::paint(Graphics &g, const YRect &/*r*/) {
int h = height();

for (int i(0); i < taskBarCPUSamples; i++) {
- int user = cpu[i][IWM_USER];
- int nice = cpu[i][IWM_NICE];
- int sys = cpu[i][IWM_SYS];
- int idle = cpu[i][IWM_IDLE];
- int intr = cpu[i][IWM_INTR];
- int iowait = cpu[i][IWM_IOWAIT];
- int softirq = cpu[i][IWM_SOFTIRQ];
- int total = user + sys + intr + nice + idle + iowait + softirq;
+ unsigned long long
+ user = cpu[i][IWM_USER],
+ nice = cpu[i][IWM_NICE],
+ sys = cpu[i][IWM_SYS],
+ idle = cpu[i][IWM_IDLE],
+ iowait = cpu[i][IWM_IOWAIT],
+ intr = cpu[i][IWM_INTR],
+ softirq = cpu[i][IWM_SOFTIRQ],
+ steal = cpu[i][IWM_STEAL],
+ total = user + sys + nice + idle + iowait + intr + softirq +
steal;

int y = height() - 1;

if (total > 1) { /* better show 0 % CPU than nonsense on startup */
- int intrbar, sysbar, nicebar, userbar, iowaitbar, softirqbar;
- int round = total / h / 2; /* compute also with rounding errs */
+ unsigned long long
+ intrbar, sysbar, nicebar, userbar,
+ iowaitbar, softirqbar, stealbar, totalbar = 0,
+ round = total / h / 2; /* compute also with rounding errs */
+
+ if ((stealbar = (h * (steal + round)) / total)) {
+ g.setColor(color[IWM_STEAL]);
+ g.drawLine(i, y, i, y - (stealbar - 1));
+ y -= stealbar;
+ }
+ totalbar += stealbar;

if ((intrbar = (h * (intr + round)) / total)) {
g.setColor(color[IWM_INTR]);
g.drawLine(i, y, i, y - (intrbar - 1));
y -= intrbar;
}
+ totalbar += intrbar;
+
if ((softirqbar = (h * (softirq + round)) / total)) {
g.setColor(color[IWM_SOFTIRQ]);
g.drawLine(i, y, i, y - (softirqbar - 1));
y -= softirqbar;
}
+ totalbar += softirqbar;
+
iowaitbar = (h * (iowait + round)) / total;
+ totalbar += iowaitbar;
+
if ((sysbar = (h * (sys + round)) / total)) {
g.setColor(color[IWM_SYS]);
g.drawLine(i, y, i, y - (sysbar - 1));
y -= sysbar;
}
+ totalbar += sysbar;

nicebar = (h * (nice + round)) / total;
+ totalbar += nicebar;

/* minor rounding errors are counted into user bar: */
- if ((userbar = (h * ((sys + nice + user + intr + iowait + softirq)
+
- round)) / total -
- (sysbar + nicebar + intrbar + iowaitbar +
softirqbar)
- ))
- {
+ if ((userbar = (h * ((total - idle) + round)) / total - totalbar))
{
g.setColor(color[IWM_USER]);
g.drawLine(i, y, i, y - (userbar - 1));
y -= userbar;
@@ -168,10 +182,17 @@ void CPUStatus::paint(Graphics &g, const
g.drawLine(i, y, i, y - (iowaitbar - 1));
y -= iowaitbar;
}
-#if 0
- msg(_("stat:\tuser = %i, nice = %i, sys = %i, idle = %i"),
cpu[i][IWM_USER], cpu[i][IWM_NICE], cpu[i][IWM_SYS], cpu[i][IWM_IDLE]);
- msg(_("bars:\tuser = %i, nice = %i, sys = %i (h = %i)\n"),
userbar, nicebar, sysbar, h);
-#endif
+
+ MSG((_("stat:\tuser = %llu, nice = %llu, sys = %llu, idle = %llu, "
+ "iowait = %llu, intr = %llu, softirq = %llu, steal = %llu\n"),
+ cpu[i][IWM_USER], cpu[i][IWM_NICE], cpu[i][IWM_SYS],
+ cpu[i][IWM_IDLE], cpu[i][IWM_IOWAIT], cpu[i][IWM_INTR],
+ cpu[i][IWM_SOFTIRQ], cpu[i][IWM_STEAL]));
+ MSG((_("bars:\tuser = %llu, nice = %llu, sys = %llu, iowait =
%llu, "
+ "intr = %llu, softirq = %llu, steal = %llu (h = %i)\n"),
+ userbar, nicebar, sysbar, iowaitbar, intrbar,
+ softirqbar, stealbar, h));
+
}
if (y > 0) {
if (color[IWM_IDLE]) {
@@ -204,30 +225,41 @@ bool CPUStatus::handleTimer(YTimer *t) {
}

void CPUStatus::updateToolTip() {
+ char cpuid[16] = "";
+ if (fCpuID >= 0)
+ snprintf(cpuid, sizeof(cpuid), "%d", fCpuID);
+
#ifdef linux
- char load[31];
+ char load[512];
struct sysinfo sys;
float l1, l5, l15;

sysinfo(&sys);
- l1 = (float)sys.loads[0] / 65536.0;
- l5 = (float)sys.loads[1] / 65536.0;
+ l1 = (float)sys.loads[0] / 65536.0;
+ l5 = (float)sys.loads[1] / 65536.0;
l15 = (float)sys.loads[2] / 65536.0;
- sprintf(load, "%3.2f %3.2f %3.2f, %d",
- l1, l5, l15, sys.procs);
- char *loadmsg = strJoin(_("CPU Load: "), load, _(" processes."), NULL);
- setToolTip(loadmsg);
- delete [] loadmsg;
+ snprintf(load, sizeof(load),
+ "CPU%s:\n"
+ " %-5s %3.2f %3.2f %3.2f, %d %s\n"
+ " %-5s %7luk/%7luk (%4.1f%%)\n"
+ " %-5s %7luM/%7luM (%4.1f%%)",
+ cpuid,
+ "Load:", l1, l5, l15, sys.procs, _("procs."),
+ "Mem:",
+ (sys.totalram - sys.freeram) / 1024, sys.totalram / 1024,
+ (double)(sys.totalram - sys.freeram) / (double)sys.totalram *
100.0,
+ "Swap:",
+ (sys.totalswap - sys.freeswap) / (1024*1024), sys.totalswap /
(1024*1024),
+ (double)(sys.totalswap - sys.freeswap) / (double)sys.totalswap *
100.0);
+ setToolTip(load);
#elif defined HAVE_GETLOADAVG2
- char load[31]; // enough for "CPU Load: 999.99 999.99 999.99\0"
+ char load[64]; // enough for "CPU Load: 999.99 999.99 999.99\0"
double loadavg[3];
if (getloadavg(loadavg, 3) < 0)
return;
- snprintf(load, sizeof(load), "CPU Load: %3.2f %3.2f %3.2f",
- loadavg[0], loadavg[1], loadavg[2]);
- char *loadmsg = strJoin(_("CPU Load: "), load, NULL);
- setToolTip(loadmsg);
- delete [] loadmsg;
+ snprintf(load, sizeof(load), "CPU%s Load: %3.2f %3.2f %3.2f",
+ cpuid, loadavg[0], loadavg[1], loadavg[2]);
+ setToolTip(load);
#endif
}

@@ -240,80 +272,71 @@ void CPUStatus::handleClick(const XButto
}

void CPUStatus::updateStatus() {
- for (int i(1); i < taskBarCPUSamples; i++) {
- cpu[i - 1][IWM_USER] = cpu[i][IWM_USER];
- cpu[i - 1][IWM_NICE] = cpu[i][IWM_NICE];
- cpu[i - 1][IWM_SYS] = cpu[i][IWM_SYS];
- cpu[i - 1][IWM_IDLE] = cpu[i][IWM_IDLE];
- cpu[i - 1][IWM_INTR] = cpu[i][IWM_INTR];
- cpu[i - 1][IWM_IOWAIT] = cpu[i][IWM_IOWAIT];
- cpu[i - 1][IWM_SOFTIRQ] = cpu[i][IWM_SOFTIRQ];
- }
+ for (int i(1); i < taskBarCPUSamples; i++)
+ memcpy(cpu[i - 1], cpu[i], IWM_STATES * sizeof(cpu[0][0]));
getStatus(),
repaint();
}

void CPUStatus::getStatus() {
+ memset(cpu[taskBarCPUSamples - 1], 0, IWM_STATES * sizeof(cpu[0][0]));
+
#ifdef linux
- char *p, buf[128];
- unsigned long cur[IWM_STATES];
- int len, s, fd = open("/proc/stat", O_RDONLY);
-
- cpu[taskBarCPUSamples - 1][IWM_USER] = 0;
- cpu[taskBarCPUSamples - 1][IWM_NICE] = 0;
- cpu[taskBarCPUSamples - 1][IWM_INTR] = 0;
- cpu[taskBarCPUSamples - 1][IWM_IOWAIT] = 0;
- cpu[taskBarCPUSamples - 1][IWM_SOFTIRQ] = 0;
- cpu[taskBarCPUSamples - 1][IWM_SYS] = 0;
- cpu[taskBarCPUSamples - 1][IWM_IDLE] = 0;
+ char *p, buf[128], *tok;
+ unsigned long long cur[IWM_STATES];
+ int s;
+ FILE *fd = fopen("/proc/stat", "r");
+ char cpuname[32] = "cpu";
+
+ if (fCpuID >= 0)
+ snprintf(cpuname, sizeof(cpuname), "cpu%d", fCpuID);

- if (fd == -1)
+ if (!fd)
return;
- len = read(fd, buf, sizeof(buf) - 1);
- if (len != sizeof(buf) - 1) {
- close(fd);
+
+ /* find the line that starts with `cpuname` */
+ do {
+ if (!fgets(buf, sizeof(buf) - 1, fd)) {
+ fclose(fd);
+ return;
+ }
+ tok = strtok_r(buf, " \t", &p);
+ if (!tok) {
+ fclose(fd);
+ return;
+ }
+ } while (strcmp(tok, cpuname));
+ fclose(fd);
+
+ s = sscanf(p, "%llu %llu %llu %llu %llu %llu %llu %llu",
+ &cur[IWM_USER], &cur[IWM_NICE],
+ &cur[IWM_SYS], &cur[IWM_IDLE],
+ &cur[IWM_IOWAIT], &cur[IWM_INTR],
+ &cur[IWM_SOFTIRQ], &cur[IWM_STEAL]);
+
+ switch (s) {
+ case 4:
+ /* Linux 2.4 */
+ cur[IWM_INTR] =
+ cur[IWM_IOWAIT] =
+ cur[IWM_SOFTIRQ] = 0;
+ /* FALL THROUGH */
+ case 7:
+ /* Linux < 2.6.11 */
+ cur[IWM_STEAL] = 0;
+ /* FALL THROUGH */
+ case 8:
+ break;
+ default:
return;
}
- close(fd);
- buf[len] = 0;
-
- p = buf;
- while (*p && (*p < '0' || *p > '9'))
- p++;
- /* Linux 2.4: cpu 3557 8 1052 7049
- * Linux 2.6: cpu 3537 44 1064 676229 7792 142 5
- */
- if ((s = strcspn(p, "\n")) <= 60)
- strcpy(p + s, " 0 0 0\n"); /* Linux 2.4 */

int i = 0;
- for (i = 0; i < 7; i++) {
- int d = -1;
+ for (i = 0; i < IWM_STATES; i++) {
+ cpu[taskBarCPUSamples - 1][i] = cur[i] - last_cpu[i];
+ last_cpu[i] = cur[i];
+ }

- /* linux/Documentation/filesystems/proc.txt: 1.8 */
- switch (i) {
- case 0: d = IWM_USER; break;
- case 1: d = IWM_NICE; break;
- case 2: d = IWM_SYS; break;
- case 3: d = IWM_IDLE; break;
- case 4: d = IWM_IOWAIT; break;
- case 5: d = IWM_INTR; break;
- case 6: d = IWM_SOFTIRQ; break;
- }
- cur[d] = strtoul(p, &p, 10);
- cpu[taskBarCPUSamples - 1][d] = cur[d] - last_cpu[d];
- last_cpu[d] = cur[d];
- }
-#if 0
- msg(_("cpu: %d %d %d %d %d %d %d"),
- cpu[taskBarCPUSamples-1][IWM_USER],
- cpu[taskBarCPUSamples-1][IWM_NICE],
- cpu[taskBarCPUSamples-1][IWM_SYS],
- cpu[taskBarCPUSamples-1][IWM_IDLE],
- cpu[taskBarCPUSamples-1][IWM_IOWAIT],
- cpu[taskBarCPUSamples-1][IWM_INTR],
- cpu[taskBarCPUSamples-1][IWM_SOFTIRQ]);
-#endif
#endif /* linux */
#ifdef HAVE_KSTAT_H
#ifdef HAVE_OLD_KSTAT
@@ -324,14 +347,16 @@ void CPUStatus::getStatus() {
kid_t new_kcid;
kstat_t *ks = NULL;
kstat_named_t *kn = NULL;
- int changed,change,total_change;
+ unsigned long long changed,change,total_change;
unsigned int thiscpu;
register int i,j;
static unsigned int ncpus;
static kstat_t **cpu_ks=NULL;
+ kstat_t **cpu_ks_new;
static cpu_stat_t *cpu_stat=NULL;
- static long cp_old[CPU_STATES];
- long cp_time[CPU_STATES], cp_pct[CPU_STATES];
+ cpu_stat_t *cpu_stat_new;
+ static unsigned long long cp_old[CPU_STATES];
+ unsigned long long cp_time[CPU_STATES], cp_pct[CPU_STATES];

/* Initialize the kstat */
if (!kc) {
@@ -373,18 +398,24 @@ void CPUStatus::getStatus() {
if ((kn) && (kn->value.ui32 > ncpus)) {
/* I guess I should be using 'new' here... FIXME */
ncpus = kn->value.ui32;
- if ((cpu_ks = (kstat_t **)
+ if ((cpu_ks_new = (kstat_t **)
realloc(cpu_ks, ncpus * sizeof(kstat_t *))) == NULL)
{
+ if (cpu_ks)
+ free(cpu_ks);
perror("realloc: cpu_ks ");
return;/* FIXME : need err handler? */
}
- if ((cpu_stat = (cpu_stat_t *)
+ cpu_ks = cpu_ks_new;
+ if ((cpu_stat_new = (cpu_stat_t *)
realloc(cpu_stat, ncpus * sizeof(cpu_stat_t))) == NULL)
{
+ if (cpu_stat)
+ free(cpu_stat);
perror("realloc: cpu_stat ");
return;/* FIXME : need err handler? */
}
+ cpu_stat = cpu_stat_new;
}
for (ks = kc->kc_chain; ks; ks = ks->ks_next) {
if (strncmp(ks->ks_name, "cpu_stat", 8) == 0) {
@@ -409,12 +440,20 @@ void CPUStatus::getStatus() {
ncpus = thiscpu;
changed = 0;
}
- for (i = 0; i<(int)ncpus; i++) {
- new_kcid = kstat_read(kc, cpu_ks[i], &cpu_stat[i]);
+ if (fCpuID >= 0 && fCpuID < ncpus) {
+ new_kcid = kstat_read(kc, cpu_ks[fCpuID], &cpu_stat[fCpuID]);
if (new_kcid < 0) {
perror("kstat_read ");
return;/* FIXME : need err handler? */
}
+ } else {
+ for (i = 0; i<(int)ncpus; i++) {
+ new_kcid = kstat_read(kc, cpu_ks[i], &cpu_stat[i]);
+ if (new_kcid < 0) {
+ perror("kstat_read ");
+ return;/* FIXME : need err handler? */
+ }
+ }
}
if (new_kcid != kcid)
continue; /* kstat changed - start over */
@@ -425,9 +464,14 @@ void CPUStatus::getStatus() {
/* Initialize the cp_time array */
for (i = 0; i < CPU_STATES; i++)
cp_time[i] = 0L;
- for (i = 0; i < (int)ncpus; i++) {
+ if (fCpuID >= 0 && fCpuID < ncpus) {
for (j = 0; j < CPU_STATES; j++)
- cp_time[j] += (long) cpu_stat[i].cpu_sysinfo.cpu[j];
+ cp_time[j] += (long) cpu_stat[fCpuID].cpu_sysinfo.cpu[j];
+ } else {
+ for (i = 0; i < (int)ncpus; i++) {
+ for (j = 0; j < CPU_STATES; j++)
+ cp_time[j] += (long) cpu_stat[i].cpu_sysinfo.cpu[j];
+ }
}
/* calculate the percent utilization for each category */
/* cpu_state calculations */
@@ -435,7 +479,7 @@ void CPUStatus::getStatus() {
for (i = 0; i < CPU_STATES; i++) {
change = cp_time[i] - cp_old[i];
if (change < 0) /* The counter rolled over */
- change = (int) ((unsigned long)cp_time[i] - (unsigned
long)cp_old[i]);
+ change = (unsigned long long) ((unsigned long long)cp_time[i] -
(unsigned long long)cp_old[i]);
cp_pct[i] = change;
total_change += change;
cp_old[i] = cp_time[i]; /* copy the data for the next run */
@@ -445,14 +489,14 @@ void CPUStatus::getStatus() {
for (i = 0; i < CPU_STATES; i++)
cp_pct[i] =
((total_change > 0) ?
- ((int)(((1000.0 * (float)cp_pct[i]) / total_change) + 0.5)) :
+ ((unsigned long long)(((1000.0 * (float)cp_pct[i]) /
total_change) + 0.5)) :
((i == CPU_IDLE) ? (1000) : (0)));

/* OK, we've got the data. Now copy it to cpu[][] */
- cpu[taskBarCPUSamples-1][IWM_USER] = cp_pct[CPU_USER];
- cpu[taskBarCPUSamples-1][IWM_NICE] = cp_pct[CPU_WAIT];
- cpu[taskBarCPUSamples-1][IWM_SYS] = cp_pct[CPU_KERNEL];
- cpu[taskBarCPUSamples-1][IWM_IDLE] = cp_pct[CPU_IDLE];
+ cpu[taskBarCPUSamples - 1][IWM_USER] = cp_pct[CPU_USER];
+ cpu[taskBarCPUSamples - 1][IWM_NICE] = cp_pct[CPU_WAIT];
+ cpu[taskBarCPUSamples - 1][IWM_SYS] = cp_pct[CPU_KERNEL];
+ cpu[taskBarCPUSamples - 1][IWM_IDLE] = cp_pct[CPU_IDLE];

#endif /* have_kstat_h */
#if defined HAVE_SYSCTL_CP_TIME && defined CP_INTR
@@ -469,15 +513,6 @@ void CPUStatus::getStatus() {
static int mib[] = { 0, 0 };
#endif

- cpu[taskBarCPUSamples - 1][IWM_USER] = 0;
- cpu[taskBarCPUSamples - 1][IWM_NICE] = 0;
- cpu[taskBarCPUSamples - 1][IWM_SYS] = 0;
- cpu[taskBarCPUSamples - 1][IWM_INTR] = 0;
- cpu[taskBarCPUSamples - 1][IWM_IOWAIT] = 0;
- cpu[taskBarCPUSamples - 1][IWM_SOFTIRQ] = 0;
- cpu[taskBarCPUSamples - 1][IWM_IDLE] = 0;
-
-
cp_time_t cp_time[CPUSTATES];
size_t len = sizeof( cp_time );
#if defined HAVE_SYSCTLBYNAME
@@ -488,21 +523,97 @@ void CPUStatus::getStatus() {
return;
#endif

- long cur[IWM_STATES];
- cur[IWM_USER] = cp_time[CP_USER];
- cur[IWM_NICE] = cp_time[CP_NICE];
- cur[IWM_SYS] = cp_time[CP_SYS];
- cur[IWM_INTR] = cp_time[CP_INTR];
- cur[IWM_IOWAIT] = 0;
+ unsigned long long cur[IWM_STATES];
+ cur[IWM_USER] = cp_time[CP_USER];
+ cur[IWM_NICE] = cp_time[CP_NICE];
+ cur[IWM_SYS] = cp_time[CP_SYS];
+ cur[IWM_IDLE] = cp_time[CP_IDLE];
+ cur[IWM_IOWAIT] = 0;
+ cur[IWM_INTR] = cp_time[CP_INTR];
cur[IWM_SOFTIRQ] = 0;
- cur[IWM_IDLE] = cp_time[CP_IDLE];
+ cur[IWM_IDLE] = cp_time[CP_IDLE];
+ cur[IWM_STEAL] = 0;

for (int i = 0; i < IWM_STATES; i++) {
cpu[taskBarCPUSamples - 1][i] = cur[i] - last_cpu[i];
last_cpu[i] = cur[i];
}
#endif
+
+ MSG((_("%s: %llu %llu %llu %llu %llu %llu %llu"),
+ fCpuName,
+ cpu[taskBarCPUSamples - 1][IWM_USER],
+ cpu[taskBarCPUSamples - 1][IWM_NICE],
+ cpu[taskBarCPUSamples - 1][IWM_SYS],
+ cpu[taskBarCPUSamples - 1][IWM_IDLE],
+ cpu[taskBarCPUSamples - 1][IWM_IOWAIT],
+ cpu[taskBarCPUSamples - 1][IWM_INTR],
+ cpu[taskBarCPUSamples - 1][IWM_SOFTIRQ],
+ cpu[taskBarCPUSamples - 1][IWM_STEAL]));
+
+}
+
+void CPUStatus::GetCPUStatus(YWindow *aParent, CPUStatus **&fCPUStatus, bool
combine) {
+ if (combine) {
+ CPUStatus::getCPUStatusCombined(aParent, fCPUStatus);
+ return;
+ }
+
+#if defined(linux)
+ char buf[128];
+ unsigned cnt = 0;
+ FILE *fd = fopen("/proc/stat", "r");
+
+ if (!fd) {
+ CPUStatus::getCPUStatusCombined(aParent, fCPUStatus);
+ return;
+ }
+
+ /* skip first line for combined cpu */
+ fgets(buf, sizeof(buf), fd);
+
+ /* count lines that begins with "cpu" */
+ while (1) {
+ if (!fgets(buf, sizeof(buf), fd))
+ break;
+
+ if (strncmp(buf, "cpu", 3))
+ break;
+
+ cnt++;
+
+ };
+ fclose(fd);
+
+ CPUStatus::getCPUStatus(aParent, fCPUStatus, cnt);
+
+#elif define(HAVE_KSTAT_H)
+ kstat_named_t *kn = NULL;
+ kn = (kstat_named_t *)kstat_data_lookup(ks, "ncpus");
+ if (kn) {
+ CPUStatus::getCPUStatus(aParent, fCPUStatus, kn->value.ui32);
+ } else {
+ CPUStatus::getCPUStatusCombined(aParent, fCPUStatus);
+ }
+#elif define(HAVE_SYSCTL_CP_TIME)
+ CPUStatus::getCPUStatusCombined(aParent, fCPUStatus);
+#endif
+}
+
+void CPUStatus::getCPUStatusCombined(YWindow *aParent, CPUStatus
**&fCPUStatus) {
+ fCPUStatus = new CPUStatus*[2];
+ fCPUStatus[0] = new CPUStatus(aParent);
+ fCPUStatus[1] = NULL;
}
+
+void CPUStatus::getCPUStatus(YWindow *aParent, CPUStatus **&fCPUStatus,
unsigned ncpus) {
+ fCPUStatus = new CPUStatus*[ncpus + 1];
+ /* we must reverse the order, so that left is cpu(0) and right is
cpu(ncpus-1) */
+ for (unsigned i(0); i < ncpus; i++)
+ fCPUStatus[i] = new CPUStatus(aParent, ncpus - 1 - i);
+ fCPUStatus[ncpus] = NULL;
+}
+
#endif
#endif

diff -urp old/src/acpustatus.h new/src/acpustatus.h
--- old/src/acpustatus.h 2006-09-10 18:12:11.000000000 +0200
+++ new/src/acpustatus.h 2006-11-12 19:28:14.061396350 +0100
@@ -3,21 +3,27 @@

#if defined(linux) || defined(HAVE_KSTAT_H) || defined(HAVE_SYSCTL_CP_TIME)

-#define IWM_USER (0)
-#define IWM_NICE (1)
-#define IWM_SYS (2)
-#define IWM_INTR (3)
-#define IWM_IOWAIT (4)
-#define IWM_SOFTIRQ (5)
-#define IWM_IDLE (6)
-#define IWM_STATES (7)
-
#include "ywindow.h"
#include "ytimer.h"

class CPUStatus: public YWindow, public YTimerListener {
public:
- CPUStatus(YWindow *aParent = 0);
+ enum {
+ IWM_USER,
+ IWM_NICE,
+ IWM_SYS,
+ IWM_IDLE,
+ IWM_IOWAIT,
+ IWM_INTR,
+ IWM_SOFTIRQ,
+ IWM_STEAL,
+ IWM_STATES
+ };
+
+protected:
+ CPUStatus(YWindow *aParent = 0, int cpuid = -1);
+
+public:
virtual ~CPUStatus();

virtual void paint(Graphics &g, const YRect &r);
@@ -30,11 +36,17 @@ public:
void getStatus();
void updateToolTip();

+ static void GetCPUStatus(YWindow *aParent, CPUStatus **&fCPUStatus, bool
combine);
+
private:
- int **cpu;
- unsigned long last_cpu[IWM_STATES];
+ int fCpuID;
+ unsigned long long **cpu;
+ unsigned long long last_cpu[IWM_STATES];
YColor *color[IWM_STATES];
YTimer *fUpdateTimer;
+
+ static void getCPUStatusCombined(YWindow *aParent, CPUStatus
**&fCPUStatus);
+ static void getCPUStatus(YWindow *aParent, CPUStatus **&fCPUStatus,
unsigned ncpus);
};
#else
#undef CONFIG_APPLET_CPU_STATUS
diff -urp old/src/default.h new/src/default.h
--- old/src/default.h 2006-11-12 19:27:25.059627521 +0100
+++ new/src/default.h 2006-11-12 19:28:14.062396141 +0100
@@ -158,6 +158,7 @@ XIV(int, taskBarNetSamples,
XIV(int, taskBarNetDelay, 500)
XSV(const char *, cpuCommand, "xterm -name top -title
Process\\ Status -e top")
XSV(const char *, cpuClassHint, "top.XTerm")
+XIV(bool, cpuCombine, true)
XSV(const char *, netCommand, "xterm -name netstat -title
'Network Status' -e netstat -c")
XSV(const char *, netClassHint, "netstat.XTerm")
XSV(const char *, netDevice, "ppp0 eth0")
@@ -353,6 +354,7 @@ cfoption icewm_preferences[] = {
OSV("RebootCommand", &rebootCommand,
"Command to reboot the system"),
OSV("CPUStatusCommand", &cpuCommand,
"Command to run on CPU status"),
OSV("CPUStatusClassHint", &cpuClassHint,
"WM_CLASS to allow runonce for CPUStatusCommand"),
+ OBV("CPUStatusCombine", &cpuCombine,
"Combine all CPUs to one"),
OSV("NetStatusCommand", &netCommand,
"Command to run on Net status"),
OSV("NetStatusClassHint", &netClassHint,
"WM_CLASS to allow runonce for NetStatusCommand"),
OSV("AddressBarCommand", &addressBarCommand,
"Command to run for address bar entries"),
diff -urp old/src/themable.h new/src/themable.h
--- old/src/themable.h 2006-11-09 18:13:42.043171338 +0100
+++ new/src/themable.h 2006-11-12 19:28:16.545877610 +0100
@@ -135,11 +135,12 @@ XSV(const char *, clrLabel,
XSV(const char *, clrLabelText, "rgb:00/00/00")
XSV(const char *, clrCpuUser, "rgb:00/FF/00")
XSV(const char *, clrCpuSys, "rgb:FF/00/00")
-XSV(const char *, clrCpuIntr, "rgb:FF/FF/00")
-XSV(const char *, clrCpuIoWait, "rgb:60/00/60")
-XSV(const char *, clrCpuSoftIrq, "rgb:00/FF/FF")
XSV(const char *, clrCpuNice, "rgb:00/00/FF")
XSV(const char *, clrCpuIdle, "rgb:00/00/00")
+XSV(const char *, clrCpuIoWait, "rgb:60/00/60")
+XSV(const char *, clrCpuIntr, "rgb:FF/FF/00")
+XSV(const char *, clrCpuSoftIrq, "rgb:00/FF/FF")
+XSV(const char *, clrCpuSteal, "rgb:FF/FF/FF")
XSV(const char *, clrNetSend, "rgb:FF/FF/00")
XSV(const char *, clrNetReceive, "rgb:FF/00/FF")
XSV(const char *, clrNetIdle, "rgb:00/00/00")
@@ -304,11 +305,12 @@ cfoption icewm_themable_preferences[] =
#ifdef CONFIG_APPLET_CPU_STATUS
OSV("ColorCPUStatusUser", &clrCpuUser,
"User load on the CPU monitor"),
OSV("ColorCPUStatusSystem", &clrCpuSys,
"System load on the CPU monitor"),
- OSV("ColorCPUStatusInterrupts", &clrCpuIntr,
"Interrupts on the CPU monitor"),
- OSV("ColorCPUStatusIoWait", &clrCpuIoWait,
"IO Wait on the CPU monitor"),
- OSV("ColorCPUStatusSoftIrq", &clrCpuSoftIrq,
"Soft Interrupts on the CPU monitor"),
OSV("ColorCPUStatusNice", &clrCpuNice,
"Nice load on the CPU monitor"),
OSV("ColorCPUStatusIdle", &clrCpuIdle,
"Idle (non) load on the CPU monitor, leave empty to force transparency"),
+ OSV("ColorCPUStatusIoWait", &clrCpuIoWait,
"IO Wait on the CPU monitor"),
+ OSV("ColorCPUStatusInterrupts", &clrCpuIntr,
"Interrupts on the CPU monitor"),
+ OSV("ColorCPUStatusSoftIrq", &clrCpuSoftIrq,
"Soft Interrupts on the CPU monitor"),
+ OSV("ColorCPUStatusSteal", &clrCpuSteal,
"Involuntary Wait on the CPU monitor"),
#endif
#ifdef CONFIG_APPLET_NET_STATUS
OSV("ColorNetSend", &clrNetSend,
"Outgoing load on the network monitor"),
diff -urp old/src/wmtaskbar.cc new/src/wmtaskbar.cc
--- old/src/wmtaskbar.cc 2006-09-10 18:12:10.000000000 +0200
+++ new/src/wmtaskbar.cc 2006-11-12 19:28:16.546877402 +0100
@@ -14,6 +14,7 @@
#include "ypaint.h"
#include "wmtaskbar.h"
#include "yprefs.h"
+#include "yarray.h"

#include "ymenuitem.h"
#include "wmmgr.h"
@@ -303,6 +304,9 @@ TaskBar::~TaskBar() {
#ifdef CONFIG_APPLET_APM
delete fApm; fApm = 0;
#endif
+#ifdef CONFIG_APPLET_CPU_STATUS
+ delete [] fCPUStatus;
+#endif
#ifdef HAVE_NET_STATUS
delete [] fNetStatus;
#endif
@@ -355,10 +359,9 @@ void TaskBar::initMenu() {

void TaskBar::initApplets() {
#ifdef CONFIG_APPLET_CPU_STATUS
+ fCPUStatus = 0;
if (taskBarShowCPUStatus)
- fCPUStatus = new CPUStatus(this);
- else
- fCPUStatus = 0;
+ CPUStatus::GetCPUStatus(this, fCPUStatus, cpuCombine);
#endif
#ifdef CONFIG_APPLET_NET_STATUS
fNetStatus = 0;
@@ -503,78 +506,97 @@ void TaskBar::trayChanged() {
// updateLayout();
}

+typedef struct {
+ YWindow *w;
+ bool left;
+ int row; // 0 = bottom, 1 = top
+ bool show;
+ int pre, post;
+ bool expand;
+} LayoutInfo;
+
+bool operator==(const LayoutInfo &l1, const LayoutInfo &l2)
+{
+ return memcmp(&l1, &l2, sizeof(LayoutInfo)) == 0;
+}
+
void TaskBar::updateLayout(int &size_w, int &size_h) {
- struct {
- YWindow *w;
- bool left;
- int row; // 0 = bottom, 1 = top
- bool show;
- int pre, post;
- bool expand;
- } *wl, wlist[] = {
+ LayoutInfo nw;
+ YArray<LayoutInfo> wlist;
+ wlist.setCapacity(13);
+
#ifndef NO_CONFIGURE_MENUS
- { fApplications, true, 1, true, 0, 0, true },
+ nw = (LayoutInfo){ fApplications, true, 1, true, 0, 0, true };
+ wlist.append(nw);
#endif
- { fShowDesktop, true, 0, true, 0, 0, true },
+ nw = (LayoutInfo){ fShowDesktop, true, 0, true, 0, 0, true };
+ wlist.append(nw);
#ifdef CONFIG_WINMENU
- { fWinList, true, 0, true, 0, 0, true},
+ nw = (LayoutInfo){ fWinList, true, 0, true, 0, 0, true};
+ wlist.append(nw);
#endif
#ifndef NO_CONFIGURE_MENUS
- { fObjectBar, true, 1, true, 4, 0, true },
+ nw = (LayoutInfo){ fObjectBar, true, 1, true, 4, 0, true };
+ wlist.append(nw);
#endif
- { fWorkspaces, taskBarWorkspacesLeft, 0, true, 4, 4, true },
+ nw = (LayoutInfo){ fWorkspaces, taskBarWorkspacesLeft, 0, true, 4, 4, true
};
+ wlist.append(nw);

- { fCollapseButton, false, 0, true, 0, 2, true },
+ nw = (LayoutInfo){ fCollapseButton, false, 0, true, 0, 2, true };
+ wlist.append(nw);
#ifdef CONFIG_APPLET_CLOCK
- { fClock, false, 1, true, 2, 2, false },
+ nw = (LayoutInfo){ fClock, false, 1, true, 2, 2, false };
+ wlist.append(nw);
#endif
#ifdef CONFIG_APPLET_MAILBOX
- { fMailBoxStatus ? fMailBoxStatus[0] : 0, false, 1, true, 1, 1, false
},
-/// TODO #warning "a hack"
- { fMailBoxStatus && fMailBoxStatus[0] ? fMailBoxStatus[1] : 0, false,
1, true, 1, 1, false },
- { fMailBoxStatus && fMailBoxStatus[0] && fMailBoxStatus[1] ?
fMailBoxStatus[2] : 0, false, 1, true, 1, 1, false },
- { fMailBoxStatus && fMailBoxStatus[0] && fMailBoxStatus[1] &&
fMailBoxStatus[2] ? fMailBoxStatus[3] : 0, false, 1, true, 1, 1, false },
- { fMailBoxStatus && fMailBoxStatus[0] && fMailBoxStatus[1] &&
fMailBoxStatus[2] && fMailBoxStatus[3] ? fMailBoxStatus[4] : 0, false, 1, true,
1, 1, false },
- { fMailBoxStatus && fMailBoxStatus[0] && fMailBoxStatus[1] &&
fMailBoxStatus[2] && fMailBoxStatus[3] && fMailBoxStatus[4] ? fMailBoxStatus[5]
: 0, false, 1, true, 1, 1, false },
+ for (MailBoxStatus ** m(fMailBoxStatus); m && *m; ++m) {
+ nw = (LayoutInfo){ *m, false, 1, true, 1, 1, false };
+ wlist.append(nw);
+ }
#endif
#ifdef CONFIG_APPLET_CPU_STATUS
- { fCPUStatus, false, 1, true, 2, 2, false },
+ for (CPUStatus ** c(fCPUStatus); c && *c; ++c) {
+ nw = (LayoutInfo){ *c, false, 1, true, 2, 2, false };
+ wlist.append(nw);
+ }
#endif
#ifdef CONFIG_APPLET_NET_STATUS
#ifdef CONFIG_APPLET_MAILBOX
- { fNetStatus ? fNetStatus[0] : 0, false, 1, false, 1, 1, false },
-/// TODO #warning "a hack"
- { fNetStatus && fNetStatus[0] ? fNetStatus[1] : 0, false, 1, false, 1,
1, false },
- { fNetStatus && fNetStatus[0] && fNetStatus[1] ? fNetStatus[2] : 0,
false, 1, false, 1, 1, false },
+ for (NetStatus ** n(fNetStatus); n && *n; ++n) {
+ nw = (LayoutInfo){ *n, false, 1, false, 2, 2, false };
+ wlist.append(nw);
+ }
#endif
#endif
#ifdef CONFIG_APPLET_APM
- { fApm, false, 1, true, 0, 2, false },
+ nw = (LayoutInfo){ fApm, false, 1, true, 2, 2, false };
+ wlist.append(nw);
#endif
- { fTray2, false, 1, true, 1, 1, false },
#ifdef CONFIG_TRAY
- { fTray, false, 0, true, 1, 1, true },
+ nw = (LayoutInfo){ fTray, false, 0, true, 1, 1, true };
+ wlist.append(nw);
#endif
- };
- const int wcount = sizeof(wlist)/sizeof(wlist[0]);
+ nw = (LayoutInfo){ fTray2, false, 0, true, 1, 1, false };
+ wlist.append(nw);
+
+ const unsigned long wcount = wlist.getCount();

int w = 0;
int y[2] = { 0, 0 };
int h[2] = { 0, 0 };
int left[2] = { 0, 0 };
int right[2] = { 0, 0 };
- int i;
+ unsigned long i;

- for (i = 0; wl = wlist + i, i < wcount; i++) {
- if (!taskBarDoubleHeight)
- wl->row = 0;
- }
+ if (!taskBarDoubleHeight)
+ for (i = 0; i < wcount; i++)
+ wlist[i].row = 0;

- for (i = 0; wl = wlist + i, i < wcount; i++) {
- if (wl->w == 0)
+ for (i = 0; i < wcount; i++) {
+ if (!wlist[i].w)
continue;
- if (wl->w->height() > h[wl->row])
- h[wl->row] = wl->w->height();
+ if (wlist[i].w->height() > h[wlist[i].row])
+ h[wlist[i].row] = wlist[i].w->height();
}

{
@@ -607,39 +629,41 @@ void TaskBar::updateLayout(int &size_w,
#endif
}

- for (i = 0; wl = wlist + i, i < wcount; i++) {
- if (wl->w == 0)
+ for (i = 0; i < wcount; i++) {
+ if (!wlist[i].w)
continue;
- if (!wl->show && !wl->w->visible())
+ if (!wlist[i].show && !wlist[i].w->visible())
continue;

int xx = 0;
int yy = 0;
- int ww = wl->w->width();
- int hh = h[wl->row];
+ int ww = wlist[i].w->width();
+ int hh = h[wlist[i].row];

- if (wl->expand) {
- yy = y[wl->row];
+ if (wlist[i].expand) {
+ yy = y[wlist[i].row];
} else {
- hh = wl->w->height();
- yy = y[wl->row] + (h[wl->row] - wl->w->height()) / 2;
+ hh = wlist[i].w->height();
+ yy = y[wlist[i].row] + (h[wlist[i].row] - wlist[i].w->height()) /
2;
}

- if (wl->left) {
- xx = left[wl->row] + wl->pre;
+ if (wlist[i].left) {
+ xx = left[wlist[i].row] + wlist[i].pre;

- left[wl->row] += ww + wl->pre + wl->post;
+ left[wlist[i].row] += ww + wlist[i].pre + wlist[i].post;
} else {
- xx = right[wl->row] - ww - wl->pre;
+ xx = right[wlist[i].row] - ww - wlist[i].pre;

- right[wl->row] -= ww + wl->pre + wl->post;
+ right[wlist[i].row] -= ww + wlist[i].pre + wlist[i].post;
}

- wl->w->setGeometry(YRect(xx, yy, ww, hh));
- if (wl->show)
- wl->w->show();
+ wlist[i].w->setGeometry(YRect(xx, yy, ww, hh));
+ if (wlist[i].show)
+ wlist[i].w->show();
}

+ wlist.clear();
+
/* ----------------------------------------------------------------- */

if (taskBarShowWindows) {
diff -urp old/src/wmtaskbar.h new/src/wmtaskbar.h
--- old/src/wmtaskbar.h 2006-09-10 18:12:11.000000000 +0200
+++ new/src/wmtaskbar.h 2006-11-12 19:28:16.546877402 +0100
@@ -104,7 +104,7 @@ private:
MailBoxStatus **fMailBoxStatus;
#endif
#ifdef CONFIG_APPLET_CPU_STATUS
- CPUStatus *fCPUStatus;
+ CPUStatus **fCPUStatus;
#endif
#ifdef CONFIG_APPLET_APM
YApm *fApm;

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise