aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-07-30 12:45:14 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-07-30 12:45:14 +0200
commit64c67891a252cfee5ad155abcc49a008d7023d08 (patch)
tree21c7d492c1f39af8416b30d5cffa338d744aefcf
parent5e87c2ef150275ddb8fd7be0397881eeeb3bb081 (diff)
downloadbusybox-w32-64c67891a252cfee5ad155abcc49a008d7023d08.tar.gz
busybox-w32-64c67891a252cfee5ad155abcc49a008d7023d08.tar.bz2
busybox-w32-64c67891a252cfee5ad155abcc49a008d7023d08.zip
mpstat: fix/improve handling of interrupt names
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--procps/mpstat.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/procps/mpstat.c b/procps/mpstat.c
index b0d187ea6..a1f3937c9 100644
--- a/procps/mpstat.c
+++ b/procps/mpstat.c
@@ -28,8 +28,16 @@
28/* Maximum number of interrupts */ 28/* Maximum number of interrupts */
29#define NR_IRQS 256 29#define NR_IRQS 256
30#define NR_IRQCPU_PREALLOC 3 30#define NR_IRQCPU_PREALLOC 3
31#define MAX_IRQ_LEN 16 31#define MAX_IRQNAME_LEN 16
32#define MAX_PF_NAME 512 32#define MAX_PF_NAME 512
33/* sysstat 9.0.6 uses width 8, but newer code which also prints /proc/softirqs
34 * data needs more: "interrupts" in /proc/softirqs have longer names,
35 * most are up to 8 chars, one (BLOCK_IOPOLL) is even longer.
36 * We are printing headers in the " IRQNAME/s" form, experimentally
37 * anything smaller than 10 chars looks ugly for /proc/softirqs stats.
38 */
39#define INTRATE_SCRWIDTH 10
40#define INTRATE_SCRWIDTH_STR "10"
33 41
34/* System files */ 42/* System files */
35#define SYSFS_DEVCPU "/sys/devices/system/cpu" 43#define SYSFS_DEVCPU "/sys/devices/system/cpu"
@@ -54,7 +62,7 @@ typedef long idata_t;
54 62
55struct stats_irqcpu { 63struct stats_irqcpu {
56 unsigned interrupt; 64 unsigned interrupt;
57 char irq_name[MAX_IRQ_LEN]; 65 char irq_name[MAX_IRQNAME_LEN];
58}; 66};
59 67
60struct stats_cpu { 68struct stats_cpu {
@@ -195,10 +203,23 @@ static void write_irqcpu_stats(struct stats_irqcpu *per_cpu_stats[],
195 203
196 /* Print header */ 204 /* Print header */
197 printf("\n%-11s CPU", prev_str); 205 printf("\n%-11s CPU", prev_str);
198 for (j = 0; j < total_irqs; j++) { 206 {
199 p0 = &per_cpu_stats[current][j]; 207 /* A bit complex code to "buy back" space if one header is too wide.
200 if (p0->irq_name[0] != '\0') 208 * Here's how it looks like. BLOCK_IOPOLL eating too much,
201 printf(" %8s/s", p0->irq_name); 209 * and latter headers use smaller width to compensate:
210 * ...BLOCK/s BLOCK_IOPOLL/s TASKLET/s SCHED/s HRTIMER/s RCU/s
211 * ... 2.32 0.00 0.01 17.58 0.14 141.96
212 */
213 int expected_len = 0;
214 int printed_len = 0;
215 for (j = 0; j < total_irqs; j++) {
216 p0 = &per_cpu_stats[current][j];
217 if (p0->irq_name[0] != '\0') {
218 int n = (INTRATE_SCRWIDTH-3) - (printed_len - expected_len);
219 printed_len += printf(" %*s/s", n > 0 ? n : 0, skip_whitespace(p0->irq_name));
220 expected_len += INTRATE_SCRWIDTH;
221 }
222 }
202 } 223 }
203 bb_putchar('\n'); 224 bb_putchar('\n');
204 225
@@ -247,7 +268,7 @@ static void write_irqcpu_stats(struct stats_irqcpu *per_cpu_stats[],
247 struct stats_irqcpu *p, *q; 268 struct stats_irqcpu *p, *q;
248 p = &per_cpu_stats[current][(cpu - 1) * total_irqs + j]; 269 p = &per_cpu_stats[current][(cpu - 1) * total_irqs + j];
249 q = &per_cpu_stats[prev][(cpu - 1) * total_irqs + offset]; 270 q = &per_cpu_stats[prev][(cpu - 1) * total_irqs + offset];
250 printf(" %10.2f", 271 printf("%"INTRATE_SCRWIDTH_STR".2f",
251 (double)(p->interrupt - q->interrupt) / itv * G.hz); 272 (double)(p->interrupt - q->interrupt) / itv * G.hz);
252 } else { 273 } else {
253 printf(" N/A"); 274 printf(" N/A");
@@ -574,10 +595,11 @@ static void get_irqs_from_interrupts(const char *fname,
574 595
575 ic = &per_cpu_stats[current][irq]; 596 ic = &per_cpu_stats[current][irq];
576 len = cp - buf; 597 len = cp - buf;
577 if (len > sizeof(ic->irq_name)) { 598 if (len >= sizeof(ic->irq_name)) {
578 len = sizeof(ic->irq_name); 599 len = sizeof(ic->irq_name) - 1;
579 } 600 }
580 safe_strncpy(ic->irq_name, buf, len); 601 safe_strncpy(ic->irq_name, buf, len + 1);
602 //bb_error_msg("%s: irq%d:'%s' buf:'%s'", fname, irq, ic->irq_name, buf);
581 digit = isdigit(buf[len - 1]); 603 digit = isdigit(buf[len - 1]);
582 cp++; 604 cp++;
583 605