File procinfo-intr.dif of Package procinfo
--- procinfo.c
+++ procinfo.c 2014-10-09 11:56:25.996337561 +0000
@@ -19,6 +19,9 @@
static char *rcsid __attribute__ ((unused)) = "$Id: procinfo.c,v 1.56 2001/02/25 11:29:13 svm Exp svm $";
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
@@ -328,6 +331,8 @@ first_page (long sl)
new.cpu_iowait = VAL;
new.cpu_hirq = VAL;
new.cpu_sirq = VAL;
+ new.cpu_steal = VAL;
+ new.cpu_guest = VAL;
/*
* according to bug #1959, sometimes the cpu_idle
* seems to go backwards(!) on SMP boxes. This may
@@ -412,11 +417,34 @@ first_page (long sl)
new.swout = VAL;
} else if (ISSTR ("intr")) {
if (nr_irqs) {
+ size_t len = strlen(&line[5]);
+ char *tok, *lp = &line[5+len-1];
+
VAL; /* First value is total of all interrupts,
for compatibility with rpc.rstatd. We
ignore it. */
+
+ tok = (char*)0;
for (i = 0; i < nr_irqs; i++) {
- new.intr[i] = VAL;
+ char * cp = strtok(tok, " ");
+ if (!cp)
+ break;
+ new.intr[i] = strtoul(cp, NULL, 10);
+ tok = (char*)0;
+
+ if (*lp != '\n') {
+ off_t off = cp - line + strlen(cp) + 1;
+ if (off + sizeof(line)/4 > sizeof(line)) {
+ size_t rest = strlen(&line[off]);
+ memmove((tok = &line[0]), &line[off], rest+1);
+ if (!fgets(&line[rest], sizeof(line) - rest, statfp)) {
+ *lp = '\n';
+ continue;
+ }
+ len = strlen(&line[rest]);
+ lp = &line[rest+len-1];
+ }
+ }
}
} else
new.old_intr = VAL;
@@ -535,6 +563,19 @@ first_page (long sl)
else
putchar ('\n');
+ if (havetwosix) {
+ if (new.cpu_steal) {
+ printf ("steal : %s %s",
+ hms (bDIFF (cpu_steal)), perc (bDIFF (cpu_steal), elapsed, nr_cpus));
+ putchar ('\n');
+ }
+ if (new.cpu_guest) {
+ printf ("guest : %s %s",
+ hms (bDIFF (cpu_guest)), perc (bDIFF (cpu_guest), elapsed, nr_cpus));
+ putchar ('\n');
+ }
+ }
+
printf ("uptime: %s context :%11lu", hms (new.uptime),
bDIFF (ctxt));
if (new.syscalls) /* If we have this, we can use the old interrupts spot. */
@@ -543,66 +584,72 @@ first_page (long sl)
/****= /proc/interrupts =****/
if (nr_irqs) {
- char irq_label[nr_irqs][22];
+ char emtpy[1] = { '\0' };
+ struct irq_s { char *label; } irq[nr_irqs];
- memset (irq_label, 0, nr_irqs * 22);
+ for (i = 0; i < nr_irqs; i++)
+ irq[i].label = &emtpy[0];
if (interruptsfp) {
int i;
fseek (interruptsfp, 0L, SEEK_SET);
while (fgets (line, sizeof (line), interruptsfp)) {
- char *p;
+ char *q, *p;
+ int n;
- if (!strchr(line, ':')) /* skip " CPU0" */
+ if (!(q = strchr(line, ':'))) /* Skip CPU0 ... */
continue;
+ p = &line[0];
+ *q = '\0';
- i = atol (strtok (line, ":")); /* Get the IRQ no. */
+ while (*p == ' ')
+ p++;
- p = strtok (NULL, "\n");
+ if ((*p < '0') || (*p > '9')) /* Skip NMI, LOC, ... */
+ continue;
- /*
- Left: p = " 31273 + serial"
- or p = " 1 XT PIC serial"
- or p = " 1 IO-APIC serial"
- or whatever.
- Anyway, let's first gobble up...
- */
+ i = atol(p); /* Get the IRQ no. */
- while (*p == ' ') /* ...spaces... */
- p++;
- while (*p >= '0' && *p <= '9') /* ...digits... */
- p++;
- while (*p == ' ' || *p == '+') /* ...and the rest. */
+ if (i >= nr_irqs) /* Should not happen */
+ continue;
+
+ q++;
+ while (*q == ' ') /* Eat white spaces */
+ q++;
+
+ n = 0;
+ while (n < nr_cpus) {
+ if (*q == '\0' || *q == '\n')
+ break;
+ p = q;
+ if (!(q = strchr(p, ' '))) /* Skip no. of IRQ */
+ break;
+ while (*q == ' ') /* Eat white spaces */
+ q++;
+ n++;
+ } /* Do this for all CPUs */
+
+ if (!q || (*q == '\0') || (*q == '\n'))
+ continue;
+
+ if (!(p = strchr(q, ' '))) /* Skip type of IRQ */
+ continue;
+
+ while (*p == ' ') /* Eat white spaces */
p++;
- /* Left: "serial" or "XT PIC serial" */
+ if ((q = strchr(p, '\n'))) /* Eat newline character */
+ *q = '\0';
- if (linux_version_code >= 0x20150) {
- /*
- I don't really like hardcoding version numbers, but
- since the label itself may contain spaces, I can't
- think of a fool-proof algorithm to detect a "XT PIC"
- style /proc/interrupts.
- */
- char *q;
-
- if ((q = strstr (p, "PIC"))) {
- while (*q != ' ') /* eat up "PIC" or "PIC-foo" */
- q++;
- while (*q == ' ') /* eat up spaces */
- q++;
- p = q;
- }
+ if (*(irq[i].label) == 0) {
+ irq[i].label = strndupa(p, 21);
+ if (irq[i].label == (char*)0)
+ irq[i].label = &emtpy[0];
}
-
- /* XXX Don't let NMI:, IPI: overwrite real values */
- if (irq_label[i][0] == 0)
- strncpy (irq_label[i], p, 20);
}
}
-
/**** /proc/dma ****/
if (dmafp) {
@@ -612,18 +659,49 @@ first_page (long sl)
fseek (dmafp, 0L, SEEK_SET);
while (fgets (line, sizeof (line), dmafp)) {
- int foo = strcspn (&line[4], " \n");
+ char *q, *p;
+ size_t len;
+ int num;
+
+ q = strchr(line, ':');
+ if (!q || (*q == '\0') || (*q == '\n'))
+ continue;
+
+ p = &line[0];
+ *q = '\0';
+
+ while (*p == ' ') /* Eat white spaces */
+ p++;
+ num = atol(p);
+
+ q++;
+ while (*q == ' ') /* Eat white spaces */
+ q++;
+
+ if ((p = strchr(q, '\n'))) /* Eat newline character */
+ *p = '\0';
+
+ if ((p = strchr(q, ' '))) /* Forget rest of line */
+ *p = '\0';
+ len = strlen(q);
for (i = 0; i < nr_irqs; i++) {
- if (strncmp (&line[4], irq_label[i], foo) == 0) {
- tmplen = sprintf (tmp, " [%ld]",
- atol (strtok (line, ":")));
+ struct irq_s *s = &irq[i];
- if (strlen (irq_label[i]) > (21 - tmplen)) {
- irq_label[i][21 - tmplen] = 0;
+ if (*(s->label) == '\0')
+ continue;
- }
- strcat (irq_label[i], tmp);
+ if (strncmp (q, s->label, len) == 0) {
+ tmplen = snprintf(tmp, sizeof(tmp), " [%d]", num);
+
+ if (tmplen > 21) /* Should not happen */
+ continue;
+ tmp[tmplen] = '\0';
+
+ if (strlen(s->label) > (21 - tmplen))
+ s->label[21 - tmplen] = 0;
+
+ strcat (s->label, tmp);
}
}
}
@@ -640,10 +718,11 @@ first_page (long sl)
} squirqs[nr_irqs];
for (i = 0; i < nr_irqs; i++) {
- if (new.intr[i] || irq_label[i][0]) {
+ struct irq_s *s = &irq[i];
+ if (new.intr[i] || *(s->label)) {
squirqs[howmany].nr = i;
squirqs[howmany].count = bDIFF(intr[i]);
- squirqs[howmany].label = irq_label[i];
+ squirqs[howmany].label = s->label;
howmany++;
}
}
@@ -653,11 +732,11 @@ first_page (long sl)
for (i = 0; i < rows; i++) {
/* The last row may be incomplete if howmany is odd, hence: */
if (i == rows - 1 && howmany & 1) {
- printf ("irq%3d:%10lu %-21s\n",
+ printf ("irq%4d:%10lu %-20s\n",
squirqs[i].nr, squirqs[i].count, squirqs[i].label);
} else {
- printf ("irq%3d:%10lu %-21s "
- "irq%3d:%10lu %-21s\n",
+ printf ("irq%4d:%10lu %-20s "
+ "irq%4d:%10lu %-20s\n",
squirqs[i].nr, squirqs[i].count, squirqs[i].label,
squirqs[i+rows].nr,
squirqs[i+rows].count,
@@ -665,13 +744,15 @@ first_page (long sl)
}
}
} else {
- for (i = 0; i < nr_irqs / 2; i++)
+ for (i = 0; i < nr_irqs / 2; i++) {
+ int j = i+(nr_irqs/2);
+ struct irq_s *s = &irq[i];
+ struct irq_s *r = &irq[j];
printf ("irq%3d:%10lu %-21s "
"irq%3d:%10lu %-21s\n",
- i, bDIFF (intr[i]), irq_label[i],
- i + (nr_irqs / 2),
- bDIFF (intr[i + (nr_irqs / 2)]),
- irq_label[i + (nr_irqs / 2)]);
+ i, bDIFF (intr[i]), s->label,
+ j, bDIFF (intr[j]), r->label);
+ }
}
} else
@@ -834,7 +915,7 @@ int
main (int ac, char **av)
{
long sl = 5000000L;
- int getoptopt;
+ int getoptopt, scanintr;
struct timeval then, now;
#ifndef DEBUG
char outbuf[4096];
@@ -993,19 +1074,23 @@ main (int ac, char **av)
version = make_version (versionfp);
/* See what the intr line in /proc/stat says. */
+ scanintr = 0;
while (fgets (line, sizeof (line), statfp)) {
- if (!strncmp ("intr", line, 4)) {
+ if (scanintr || !strncmp("intr", line, 4)) {
/* Counting number of spaces after line[5] gives us */
/* number of interrupt entries in new-style intr. */
/* If zero: old style intr. */
- int i, len = strlen(line);
- for(i = 5; i < len; i++)
- if(line[i] == ' ')
+ size_t i, len = strlen(line);
+ for(i = ((scanintr) ? 0 : 5); i < len; i++) {
+ if (line[i] == '\n')
+ break;
+ if (line[i] == ' ')
nr_irqs++;
- new.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
- old.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
- memset (&base, 0, sizeof (struct info));
- base.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
+ }
+ if (line[i] != '\n')
+ scanintr = 1;
+ else
+ scanintr = 0;
continue;
}
/* While we're at it, fill in booted. */
@@ -1017,6 +1102,12 @@ main (int ac, char **av)
continue;
}
}
+ if (nr_irqs) {
+ new.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
+ old.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
+ memset (&base, 0, sizeof (struct info));
+ base.intr = my_xcalloc (nr_irqs, sizeof (unsigned long int));
+ }
if (fs)
printf ("%s%s", cl, vi);
--- procinfo.h
+++ procinfo.h 2008-04-28 13:14:11.000000000 +0200
@@ -83,7 +83,7 @@ struct info
unsigned long uptime;
long m_to, m_us, m_fr, m_sh, m_bu, m_ca;
long s_to, s_us, s_fr;
- unsigned long cpu_user, cpu_nice, cpu_sys, cpu_idle, cpu_iowait, cpu_hirq, cpu_sirq;
+ unsigned long cpu_user, cpu_nice, cpu_sys, cpu_idle, cpu_iowait, cpu_hirq, cpu_sirq, cpu_steal, cpu_guest;
unsigned long disk[8];
unsigned long disk_r[8];
unsigned long disk_w[8];
--- routines.c
+++ routines.c 2014-10-09 11:47:57.891838889 +0000
@@ -430,22 +430,21 @@ hms (unsigned long t)
char *
perc (unsigned long i, unsigned long t, int cpus)
{
- unsigned int v;
+ long double v;
static char buf[128];
t = (t*100ULL) / usr_hz;
if ((signed long) i == -1 || t == 0)
return "---.-%";
- v = (unsigned int) (i < 1000000 ?
- ((1000 * i + t / 2) / t) :
- ((i + t / 2000) / (t / 1000)));
- v /= cpus;
+ if (i < 1000000UL)
+ v = (1000.0 * i + t / 2.0) / t;
+ else
+ v = (i + t / 2000.0) / (t / 1000.0);
+ v = v / (cpus * 10.0);
- /* if (v > 1000)
- return "+++.+%";
- else */
- snprintf (buf, sizeof(buf)-1, "%3u.%u%%", v / 10, v % 10);
+ buf[0] = '\0';
+ snprintf (buf, sizeof(buf)-1, "%5.1Lf%%", v);
return buf;
}