diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-07-30 12:45:14 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-07-30 12:45:14 +0200 |
commit | 64c67891a252cfee5ad155abcc49a008d7023d08 (patch) | |
tree | 21c7d492c1f39af8416b30d5cffa338d744aefcf | |
parent | 5e87c2ef150275ddb8fd7be0397881eeeb3bb081 (diff) | |
download | busybox-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.c | 42 |
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 | ||
55 | struct stats_irqcpu { | 63 | struct 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 | ||
60 | struct stats_cpu { | 68 | struct 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 | ||