4
* Copyright (C) 2014, Linaro Limited.
6
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; version 2 of the License.
11
* This program is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
16
* You should have received a copy of the GNU General Public License along
17
* with this program; if not, write to the Free Software Foundation, Inc.,
18
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23
* Tuukka Tikkanen <tuukka.tikkanen@linaro.org>
31
#include <sys/ioctl.h>
32
#include "report_ops.h"
37
static void charrep(char c, int count)
40
for (i = 0; i < count; i++)
44
static int default_check_output(struct program_options *options, void *report_data)
46
if (check_window_size() && !options->outfilename) {
47
fprintf(stderr, "The terminal must be at least "
54
static int default_open_report_file(char *path, void *report_data)
56
return redirect_stdout_to_file(path);
59
static int default_close_report_file(void *report_data)
61
return (fclose(stdout) == EOF) ? -1 : 0;
65
/* Topology headers for all tables (C-state/P-state/Wakeups) */
67
static void boxless_cpu_header(const char *cpu, void *report_data)
69
/* No pipe characters and less aggressive indentions */
70
if (strstr(cpu, "cluster"))
72
else if (strstr(cpu, "core"))
74
else printf(" %s\n", cpu);
77
static void default_cpu_header(const char *cpu, int len)
82
if (strstr(cpu, "cluster"))
83
printf("| %-*s |\n", len - 4, cpu);
84
else if (strstr(cpu, "core"))
85
printf("| %-*s |\n", len - 9, cpu);
86
else printf("| %-*s |\n", len - 16, cpu);
92
static void default_end_cpu(void *report_data)
96
static void boxless_end_cpu(void *report_data)
104
static void boxless_cstate_table_header(void *report_data)
106
/* Note: Data is right-aligned, so boxless headers are too */
107
printf(" C-state min max avg total hits over under\n");
110
static void default_cstate_table_header(void *report_data)
112
/* Note: Boxed header columns appear centered */
114
printf("\n| C-state | min | max | avg | total | hits | over | under |\n");
117
static void default_cstate_cpu_header(const char *cpu, void *report_data)
119
default_cpu_header(cpu, 80);
122
static void boxless_cstate_single_state(struct cpuidle_cstate *c, void *report_data)
124
printf(" %8s ", c->name);
125
display_factored_time(c->min_time == DBL_MAX ? 0. :
128
display_factored_time(c->max_time, 8);
130
display_factored_time(c->avg_time, 8);
132
display_factored_time(c->duration, 8);
134
printf("%5d %5d %5d\n", c->nrdata, c->early_wakings, c->late_wakings);
137
static void default_cstate_single_state(struct cpuidle_cstate *c, void *report_data)
139
printf("| %8s | ", c->name);
140
display_factored_time(c->min_time == DBL_MAX ? 0. :
143
display_factored_time(c->max_time, 8);
145
display_factored_time(c->avg_time, 8);
147
display_factored_time(c->duration, 8);
149
printf("%5d | %5d | %5d |\n", c->nrdata, c->early_wakings, c->late_wakings);
152
static void boxless_cstate_table_footer(void *report_data)
157
static void default_cstate_table_footer(void *report_data)
166
static void boxless_pstate_table_header(void *report_data)
168
/* Note: Data is right-aligned, so boxless headers are too */
169
printf(" P-state min max avg total hits\n");
172
static void default_pstate_table_header(void *report_data)
177
/* Note: Boxed header columns appear centered */
178
printf("| P-state | min | max | avg | total | hits |\n");
181
static void default_pstate_cpu_header(const char *cpu, void *report_data)
183
default_cpu_header(cpu, 64);
186
static void boxless_pstate_single_freq(struct cpufreq_pstate *p, void *report_data)
189
display_factored_freq(p->freq, 8);
191
display_factored_time(p->min_time == DBL_MAX ? 0. : p->min_time, 8);
193
display_factored_time(p->max_time, 8);
195
display_factored_time(p->avg_time, 8);
197
display_factored_time(p->duration, 8);
198
printf(" %5d\n", p->count);
201
static void default_pstate_single_freq(struct cpufreq_pstate *p, void *report_data)
204
display_factored_freq(p->freq, 8);
206
display_factored_time(p->min_time == DBL_MAX ? 0. : p->min_time, 8);
208
display_factored_time(p->max_time, 8);
210
display_factored_time(p->avg_time, 8);
212
display_factored_time(p->duration, 8);
213
printf(" | %5d |\n", p->count);
216
static void boxless_pstate_table_footer(void *report_data)
221
static void default_pstate_table_footer(void *report_data)
230
static void boxless_wakeup_table_header(void *report_data)
233
* Note: Columns 1 and 2 are left-aligned, others are right-aligned.
234
* Boxless headers follow the data convention
236
printf(" IRQ Name Count early late\n");
239
static void default_wakeup_table_header(void *report_data)
244
/* Note: Boxed header columns appear centered */
245
printf("| IRQ | Name | Count | early | late |\n");
248
static void default_wakeup_cpu_header(const char *cpu, void *report_data)
250
default_cpu_header(cpu, 55);
253
static void boxless_wakeup_single_irq(struct wakeup_irq *irqinfo, void *report_data)
255
if (irqinfo->id != -1) {
256
printf(" %-3d %-15.15s %7d %7d %7d\n",
257
irqinfo->id, irqinfo->name, irqinfo->count,
258
irqinfo->early_triggers, irqinfo->late_triggers);
260
printf(" IPI %-15.15s %7d %7d %7d\n",
261
irqinfo->name, irqinfo->count,
262
irqinfo->early_triggers, irqinfo->late_triggers);
266
static void default_wakeup_single_irq(struct wakeup_irq *irqinfo, void *report_data)
268
if (irqinfo->id != -1) {
269
printf("| %-3d | %-15.15s | %7d | %7d | %7d |\n",
270
irqinfo->id, irqinfo->name, irqinfo->count,
271
irqinfo->early_triggers, irqinfo->late_triggers);
273
printf("| IPI | %-15.15s | %7d | %7d | %7d |\n",
274
irqinfo->name, irqinfo->count,
275
irqinfo->early_triggers, irqinfo->late_triggers);
279
static void boxless_wakeup_table_footer(void *report_data)
284
static void default_wakeup_table_footer(void *report_data)
291
static struct report_ops default_report_ops = {
293
.check_output = default_check_output, /* Shared */
295
.open_report_file = default_open_report_file, /* Shared */
296
.close_report_file = default_close_report_file, /* Shared */
298
.cstate_table_header = default_cstate_table_header,
299
.cstate_table_footer = default_cstate_table_footer,
300
.cstate_cpu_header = default_cstate_cpu_header,
301
.cstate_single_state = default_cstate_single_state,
302
.cstate_end_cpu = default_end_cpu,
304
.pstate_table_header = default_pstate_table_header,
305
.pstate_table_footer = default_pstate_table_footer,
306
.pstate_cpu_header = default_pstate_cpu_header,
307
.pstate_single_freq = default_pstate_single_freq,
308
.pstate_end_cpu = default_end_cpu,
310
.wakeup_table_header = default_wakeup_table_header,
311
.wakeup_table_footer = default_wakeup_table_footer,
312
.wakeup_cpu_header = default_wakeup_cpu_header,
313
.wakeup_single_irq = default_wakeup_single_irq,
314
.wakeup_end_cpu = default_end_cpu,
317
EXPORT_REPORT_OPS(default);
319
static struct report_ops boxless_report_ops = {
321
.check_output = default_check_output,
323
.open_report_file = default_open_report_file,
324
.close_report_file = default_close_report_file,
326
.cstate_table_header = boxless_cstate_table_header,
327
.cstate_table_footer = boxless_cstate_table_footer,
328
.cstate_cpu_header = boxless_cpu_header,
329
.cstate_single_state = boxless_cstate_single_state,
330
.cstate_end_cpu = boxless_end_cpu,
332
.pstate_table_header = boxless_pstate_table_header,
333
.pstate_table_footer = boxless_pstate_table_footer,
334
.pstate_cpu_header = boxless_cpu_header,
335
.pstate_single_freq = boxless_pstate_single_freq,
336
.pstate_end_cpu = boxless_end_cpu,
338
.wakeup_table_header = boxless_wakeup_table_header,
339
.wakeup_table_footer = boxless_wakeup_table_footer,
340
.wakeup_cpu_header = boxless_cpu_header,
341
.wakeup_single_irq = boxless_wakeup_single_irq,
342
.wakeup_end_cpu = boxless_end_cpu,
345
EXPORT_REPORT_OPS(boxless);