The output is now in the form of:
---------------------------------------------------------------- | P-state | min | max | avg | total | hits | ---------------------------------------------------------------- | cpu0 | ---------------------------------------------------------------- | 2.90GHz | 0us | 37.93ms | 383us | 163.89ms | 428 | | 2.20GHz | 11us | 1.69ms | 160us | 3.83ms | 24 | | 1.80GHz | 8us | 2.72ms | 106us | 6.37ms | 60 | | 1.30GHz | 1us | 4.51ms | 1.13ms | 5.65ms | 5 | | 1.20GHz | 0us | 17.75ms | 292us | 3.55s | 12148 | ---------------------------------------------------------------- | cpu1 | ---------------------------------------------------------------- | 2.90GHz | 0us | 5.59ms | 447us | 118.06ms | 264 | | 1.20GHz | 0us | 13.83ms | 656us | 3.05s | 4649 | ---------------------------------------------------------------- | cpu2 | ---------------------------------------------------------------- | 2.90GHz | 1us | 118.77ms | 1.45ms | 326.93ms | 225 | | 2.80GHz | 24us | 1.34ms | 263us | 5.26ms | 20 | | 2.50GHz | 11us | 2.49ms | 327us | 9.49ms | 29 | | 1.20GHz | 1us | 21.24ms | 404us | 3.99s | 9891 | ---------------------------------------------------------------- | cpu3 | ---------------------------------------------------------------- | 2.90GHz | 3us | 21.07ms | 720us | 127.51ms | 177 | | 1.60GHz | 3us | 5.14ms | 120us | 12.03ms | 100 | | 1.20GHz | 1us | 18.07ms | 660us | 2.76s | 4190 | ----------------------------------------------------------------
-------------------------------------------------------------------------------- | C-state | min | max | avg | total | hits | over | under | -------------------------------------------------------------------------------- | clusterA | -------------------------------------------------------------------------------- | C1-IVB | 0us | 1.24ms | 1.24ms | 1.24ms | 1 | 0 | 0 | | C7-IVB | 0us | 10.07ms | 1.78ms | 19.10s | 10739 | 0 | 0 | -------------------------------------------------------------------------------- | core0 | -------------------------------------------------------------------------------- | C1-IVB | 0us | 2.02ms | 262us | 3.14ms | 12 | 0 | 0 | | C7-IVB | 0us | 15.92ms | 2.09ms | 23.30s | 11163 | 0 | 0 | -------------------------------------------------------------------------------- | cpu0 | -------------------------------------------------------------------------------- | POLL | 3us | 3us | 3us | 3us | 1 | 0 | 0 | | C1-IVB | 0us | 2.95ms | 179us | 162.03ms | 905 | 0 | 0 | | C3-IVB | 1us | 9.07ms | 555us | 192.47ms | 347 | 0 | 0 | | C6-IVB | 6us | 3.84ms | 1.18ms | 40.13ms | 34 | 0 | 0 | | C7-IVB | 1us | 16.35ms | 2.27ms | 25.83s | 11396 | 0 | 0 | -------------------------------------------------------------------------------- | cpu1 | -------------------------------------------------------------------------------- | C1-IVB | 1us | 11.12ms | 173us | 54.09ms | 313 | 0 | 0 | | C3-IVB | 2us | 1.39ms | 399us | 55.81ms | 140 | 0 | 0 | | C6-IVB | 20us | 1.04ms | 517us | 2.07ms | 4 | 0 | 0 | | C7-IVB | 1us | 41.48ms | 5.93ms | 26.67s | 4495 | 0 | 0 | -------------------------------------------------------------------------------- | core1 | -------------------------------------------------------------------------------- | C1-IVB | 0us | 1.25ms | 116us | 4.04ms | 35 | 0 | 0 | | C7-IVB | 0us | 22.25ms | 2.17ms | 22.97s | 10605 | 0 | 0 | -------------------------------------------------------------------------------- | cpu2 | -------------------------------------------------------------------------------- | POLL | 3us | 3us | 3us | 3us | 1 | 0 | 0 | | C1-IVB | 1us | 9.65ms | 265us | 133.88ms | 505 | 0 | 0 | | C3-IVB | 1us | 3.74ms | 440us | 127.48ms | 290 | 0 | 0 | | C6-IVB | 24us | 2.34ms | 1.01ms | 32.32ms | 32 | 0 | 0 | | C7-IVB | 1us | 31.43ms | 2.70ms | 25.33s | 9369 | 0 | 0 | -------------------------------------------------------------------------------- | cpu3 | -------------------------------------------------------------------------------- | POLL | 11us | 11us | 11us | 11us | 1 | 0 | 0 | | C1-IVB | 1us | 4.80ms | 94us | 42.66ms | 455 | 0 | 0 | | C3-IVB | 1us | 2.00ms | 420us | 28.59ms | 68 | 0 | 0 | | C6-IVB | 31us | 1.42ms | 800us | 8.00ms | 10 | 0 | 0 | | C7-IVB | 0us | 98.04ms | 6.92ms | 26.99s | 3899 | 0 | 0 | --------------------------------------------------------------------------------
Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org --- idlestat.c | 209 +++++++++++++++++++++++++++++++++++++----------------------- topology.c | 27 ++++---- topology.h | 4 +- 3 files changed, 143 insertions(+), 97 deletions(-)
diff --git a/idlestat.c b/idlestat.c index fc7a31a..3fe2af6 100644 --- a/idlestat.c +++ b/idlestat.c @@ -68,11 +68,88 @@ static inline void *ptrerror(const char *str) return NULL; }
-static int display_cstates(struct cpuidle_cstates *cstates, char *str) +static void charrep(char c, int count) { int i; + for (i = 0; i < count; i++) + printf("%c", c); +} + +static void display_cstates_header(void) +{ + charrep('-', 80); + printf("\n"); + + printf("| C-state | min | max | avg | total | hits | over | under |\n"); +} + +static void display_cstates_footer(void) +{ + charrep('-', 80); + printf("\n\n"); +} + +static void display_pstates_header(void) +{ + charrep('-', 64); + printf("\n"); + + printf("| P-state | min | max | avg | total | hits |\n"); +} + +static void display_pstates_footer(void) +{ + charrep('-', 64); + printf("\n\n"); +} + +static void display_cpu_header(char *cpu, int length) +{ + charrep('-', length); + printf("\n"); + + printf("|%*s%*s|\n", (length / 2) - 1, cpu, ((length / 2) - 1), ""); +} + +static void display_factored_time(double time, int align) +{ + char buffer[128]; + + if (time < 1000) { + sprintf(buffer, "%.0lfus", time); + printf("%*s", align, buffer); + } + else if (time < 1000000) { + sprintf(buffer, "%.2lfms", time / 1000.0); + printf("%*s", align, buffer); + } + else { + sprintf(buffer, "%.2lfs", time / 1000000.0); + printf("%*s", align, buffer); + } +} + +static void display_factored_freq(int freq, int align) +{ + char buffer[128]; + + if (freq < 1000) { + sprintf(buffer, "%dHz", freq); + printf("%*s", align, buffer); + } else if (freq < 1000000) { + sprintf(buffer, "%.2fMHz", (float)freq / 1000.0); + printf("%*s", align, buffer); + } else { + sprintf(buffer, "%.2fGHz", (float)freq / 1000000.0); + printf("%*s", align, buffer); + } +}
- printf("%s@state hits\tover\tunder\t\ttotal(us)\tavg(us)\tmin(us)\tmax(us)\n", str); +static int display_cstates(void *arg, char *cpu) +{ + int i; + bool cpu_header = false; + struct cpuidle_cstates *cstates = arg;
for (i = 0; i < cstates->cstate_max + 1; i++) { struct cpuidle_cstate *c = &cstates->cstate[i]; @@ -81,33 +158,37 @@ static int display_cstates(struct cpuidle_cstates *cstates, char *str) /* nothing to report for this state */ continue;
- if (c->target_residency >= 0) { - printf("%*c %-10s%d\t%d\t%d\t%15.2lf\t%15.2lf\t%.2lf\t%.2lf\n", - (int)strlen(str), ' ', - c->name, c->nrdata, - c->premature_wakeup, - c->could_sleep_more, - c->duration, - c->avg_time, - (c->min_time == DBL_MAX ? 0. : c->min_time), - c->max_time); - } else { - printf("%*c %-10s%d\t%15.2lf\t%15.2lf\t%.2lf\t%.2lf\n", - (int)strlen(str), ' ', - c->name, c->nrdata, - c->duration, - c->avg_time, - (c->min_time == DBL_MAX ? 0. : c->min_time), - c->max_time); + if (!cpu_header) { + display_cpu_header(cpu, 80); + cpu_header = true; + charrep('-', 80); + printf("\n"); } + + printf("| %8s | ", c->name); + display_factored_time(c->min_time == DBL_MAX ? 0. : + c->min_time, 8); + printf(" | "); + display_factored_time(c->max_time, 8); + printf(" | "); + display_factored_time(c->avg_time, 8); + printf(" | "); + display_factored_time(c->duration, 8); + printf(" | "); + printf("%5d | %5d | %5d |", c->nrdata, + c->premature_wakeup, c->could_sleep_more); + + printf("\n"); }
return 0; }
-static int display_pstates(struct cpufreq_pstates *pstates, char *str) +static int display_pstates(void *arg, char *cpu) { int i; + bool cpu_header = false; + struct cpufreq_pstates *pstates = arg;
for (i = 0; i < pstates->max; i++) {
@@ -117,12 +198,28 @@ static int display_pstates(struct cpufreq_pstates *pstates, char *str) /* nothing to report for this state */ continue;
- printf("%*c %-10d\t%d\t%15.2lf\t%15.2lf\t%.2lf\t%.2lf\n", - (int)strlen(str), ' ', - p->freq/1000, p->count, p->duration, - p->avg_time, - (p->min_time == DBL_MAX ? 0. : p->min_time), - p->max_time); + if (!cpu_header) { + display_cpu_header(cpu, 64); + cpu_header = true; + charrep('-', 64); + printf("\n"); + } + + printf("| "); + display_factored_freq(p->freq, 8); + printf(" | "); + display_factored_time(p->min_time == DBL_MAX ? 0. : + p->min_time, 8); + printf(" | "); + display_factored_time(p->max_time, 8); + printf(" | "); + display_factored_time(p->avg_time, 8); + printf(" | "); + display_factored_time(p->duration, 8); + printf(" | "); + printf("%5d", p->count); + printf(" | "); + printf("\n"); }
return 0; @@ -146,47 +243,6 @@ static int display_wakeup_sources(struct wakeup_info *wakeinfo, char *str) return 0; }
-static int display_states(struct cpuidle_cstates *cstates, - struct cpufreq_pstates *pstates, char *str) -{ - if (cstates) - display_cstates(cstates, str); - - if (pstates) - display_pstates(pstates, str); - - if (strstr(str, IRQ_WAKEUP_UNIT_NAME)) - display_wakeup_sources(&cstates->wakeinfo, str); - - return 0; -} - -int dump_all_data(struct cpuidle_datas *datas, - int (*dump)(struct cpuidle_cstates *, - struct cpufreq_pstates *, char *)) -{ - int i = 0, nrcpus = datas->nrcpus; - struct cpuidle_cstates *cstates; - struct cpufreq_pstates *pstates; - - do { - cstates = &datas->cstates[i]; - pstates = &datas->pstates[i]; - - if (nrcpus == -1) - sprintf(buffer, "cluster"); - else - sprintf(buffer, "cpu%d", i); - - dump(cstates, pstates, buffer); - - i++; - - } while (i < nrcpus && nrcpus != -1); - - return 0; -} - static struct cpuidle_data *intersection(struct cpuidle_data *data1, struct cpuidle_data *data2) { @@ -1290,7 +1346,6 @@ static int execute(int argc, char *argv[], char *const envp[], int main(int argc, char *argv[], char *const envp[]) { struct cpuidle_datas *datas; - struct cpuidle_datas *cluster; struct program_options options; int args;
@@ -1373,18 +1428,14 @@ int main(int argc, char *argv[], char *const envp[]) * the same cluster */ if (0 == establish_idledata_to_topo(datas)) { - dump_cpu_topo_info(display_states); - } else { - cluster = cluster_data(datas); - if (!cluster) - return 1; - - dump_all_data(datas, display_states);
- dump_all_data(cluster, display_states); + display_cstates_header(); + dump_cpu_topo_info(display_cstates, 0); + display_cstates_footer();
- free(cluster->cstates); - free(cluster); + display_pstates_header(); + dump_cpu_topo_info(display_pstates, 1); + display_pstates_footer(); }
release_cpu_topo_cstates(); diff --git a/topology.c b/topology.c index dc71b61..5bf88a1 100644 --- a/topology.c +++ b/topology.c @@ -449,35 +449,32 @@ int establish_idledata_to_topo(struct cpuidle_datas *datas) return 0; }
-int dump_cpu_topo_info(int (*dump)(struct cpuidle_cstates *, - struct cpufreq_pstates *, char *)) +int dump_cpu_topo_info(int (*dump)(void *, char *), int pstate) { struct cpu_physical *s_phy; struct cpu_core *s_core; struct cpu_cpu *s_cpu; - char tmp[30]; - int tab = 0; + char tmp[30];
list_for_each_entry(s_phy, &g_cpu_topo_list.physical_head, list_physical) { + sprintf(tmp, "cluster%c", s_phy->physical_id + 'A'); - dump(s_phy->cstates, NULL, tmp);
- list_for_each_entry(s_core, &s_phy->core_head, list_core) { - if (s_core->is_ht) { - sprintf(tmp, " core%d", s_core->core_id); - dump(s_core->cstates, NULL, tmp); + if (!pstate) + dump(s_phy->cstates, tmp);
- tab = 1; - } else { - tab = 0; + list_for_each_entry(s_core, &s_phy->core_head, list_core) { + if (s_core->is_ht && !pstate) { + sprintf(tmp, "core%d", s_core->core_id); + dump(s_core->cstates, tmp); }
list_for_each_entry(s_cpu, &s_core->cpu_head, list_cpu) { - sprintf(tmp, "%*ccpu%d", (tab + 1) * 2, 0x20, - s_cpu->cpu_id); - dump(s_cpu->cstates, s_cpu->pstates, tmp); + sprintf(tmp, "cpu%d", s_cpu->cpu_id); + dump(pstate ? s_cpu->pstates : + s_cpu->cstates, tmp); } } } diff --git a/topology.h b/topology.h index 9e8eff8..bf05201 100644 --- a/topology.h +++ b/topology.h @@ -66,9 +66,7 @@ extern int release_cpu_topo_info(void); extern int output_cpu_topo_info(FILE *f); extern int establish_idledata_to_topo(struct cpuidle_datas *datas); extern int release_cpu_topo_cstates(void); -extern int dump_cpu_topo_info(int (*dump)(struct cpuidle_cstates *, - struct cpufreq_pstates *, char *)); - +extern int dump_cpu_topo_info(int (*dump)(void *, char *), int pstate);
extern struct cpuidle_cstates *core_cluster_data(struct cpu_core *s_core); extern struct cpuidle_cstates *