On 08/19/2014 09:22 AM, pi-cheng.chen wrote:
Currently the serial terminal connected to the boards running idlestat are
restricted to be at least 80 characters wide to output the report. Otherwise
idlestat quits with message "The terminal must be at least 80 columns wide".

Fix it by adding a "-o" option to save report output to a file.

Yes, but please do it in the unix way.

1. open file
2. close stdout
3. dup[2] opened file to stdout (fd 1)
4. close opened file

So no need to change all the code around.

Thanks
  -- Daniel

Signed-off-by: Pi-Cheng Chen <pi-cheng.c...@linaro.org>
---
  idlestat.c | 136 ++++++++++++++++++++++++++++++++++++++++---------------------
  idlestat.h |   1 +
  2 files changed, 90 insertions(+), 47 deletions(-)

diff --git a/idlestat.c b/idlestat.c
index bba8951..fb0ae8f 100644
--- a/idlestat.c
+++ b/idlestat.c
@@ -51,6 +51,7 @@
  #define USEC_PER_SEC 1000000

  static char buffer[BUFSIZE];
+static FILE *output;

  static inline int error(const char *str)
  {
@@ -68,19 +69,40 @@ static void charrep(char c, int count)
  {
        int i;
        for (i = 0; i < count; i++)
-               printf("%c", c);
+               fprintf(output, "%c", c);
+}
+
+static int open_report_file(const char *path)
+{
+       if (path) {
+               output = fopen(path, "w+");
+
+               if (!output) {
+                       fprintf(stderr, "%s: failed to open '%s'\n", __func__, 
path);
+                       return -1;
+               }
+       } else
+               output = stdout;
+
+       return 0;
+}
+
+static void close_report_file(void)
+{
+       if (output != stdout)
+               fclose(output);
  }

  static void display_cpu_header(char *cpu, int length)
  {
        charrep('-', length);
-       printf("\n");
+       fprintf(output, "\n");

        if (strstr(cpu, "cluster"))
-               printf("| %-*s |\n", length - 4, cpu);
+               fprintf(output, "| %-*s |\n", length - 4, cpu);
        else if (strstr(cpu, "core"))
-               printf("|      %-*s |\n", length - 9, cpu);
-       else printf("|             %-*s |\n", length - 16, cpu);
+               fprintf(output, "|      %-*s |\n", length - 9, cpu);
+       else fprintf(output, "|             %-*s |\n", length - 16, cpu);
  }

  static void display_factored_time(double time, int align)
@@ -89,15 +111,15 @@ static void display_factored_time(double time, int align)

        if (time < 1000) {
                sprintf(buffer, "%.0lfus", time);
-               printf("%*s", align, buffer);
+               fprintf(output, "%*s", align, buffer);
        }
        else if (time < 1000000) {
                sprintf(buffer, "%.2lfms", time / 1000.0);
-               printf("%*s", align, buffer);
+               fprintf(output, "%*s", align, buffer);
        }
        else {
                sprintf(buffer, "%.2lfs", time / 1000000.0);
-               printf("%*s", align, buffer);
+               fprintf(output, "%*s", align, buffer);
        }
  }

@@ -107,28 +129,29 @@ static void display_factored_freq(int freq, int align)

        if (freq < 1000) {
                sprintf(buffer, "%dHz", freq);
-               printf("%*s", align, buffer);
+               fprintf(output, "%*s", align, buffer);
        } else if (freq < 1000000) {
                sprintf(buffer, "%.2fMHz", (float)freq / 1000.0);
-               printf("%*s", align, buffer);
+               fprintf(output, "%*s", align, buffer);
        } else {
                sprintf(buffer, "%.2fGHz", (float)freq / 1000000.0);
-               printf("%*s", align, buffer);
+               fprintf(output, "%*s", align, buffer);
        }
  }

  static void display_cstates_header(void)
  {
        charrep('-', 80);
-       printf("\n");
+       fprintf(output, "\n");

-       printf("| C-state  |   min    |   max    |   avg    |   total  | hits  |  
over | under |\n");
+       fprintf(output, "| C-state  |   min    |   max    |   avg    |   total"
+                                       "  | hits  |  over | under |\n");
  }

  static void display_cstates_footer(void)
  {
        charrep('-', 80);
-       printf("\n\n");
+       fprintf(output, "\n\n");
  }

  static int display_cstates(void *arg, char *cpu)
@@ -148,23 +171,23 @@ static int display_cstates(void *arg, char *cpu)
                        display_cpu_header(cpu, 80);
                        cpu_header = true;
                        charrep('-', 80);
-                       printf("\n");
+                       fprintf(output, "\n");
                }

-               printf("| %8s | ", c->name);
+               fprintf(output, "| %8s | ", c->name);
                display_factored_time(c->min_time == DBL_MAX ? 0. :
                                      c->min_time, 8);
-               printf(" | ");
+               fprintf(output, " | ");
                display_factored_time(c->max_time, 8);
-               printf(" | ");
+               fprintf(output, " | ");
                display_factored_time(c->avg_time, 8);
-               printf(" | ");
+               fprintf(output, " | ");
                display_factored_time(c->duration, 8);
-               printf(" | ");
-               printf("%5d | %5d | %5d |", c->nrdata,
+               fprintf(output, " | ");
+               fprintf(output, "%5d | %5d | %5d |", c->nrdata,
                       c->premature_wakeup, c->could_sleep_more);

-               printf("\n");
+               fprintf(output, "\n");
        }

        return 0;
@@ -173,15 +196,16 @@ static int display_cstates(void *arg, char *cpu)
  static void display_pstates_header(void)
  {
        charrep('-', 64);
-       printf("\n");
+       fprintf(output, "\n");

-       printf("| P-state  |   min    |   max    |   avg    |   total  | hits  
|\n");
+       fprintf(output, "| P-state  |   min    |   max    |   avg    |   total"
+                                       "  | hits  |\n");
  }

  static void display_pstates_footer(void)
  {
        charrep('-', 64);
-       printf("\n\n");
+       fprintf(output, "\n\n");
  }

  static int display_pstates(void *arg, char *cpu)
@@ -202,24 +226,24 @@ static int display_pstates(void *arg, char *cpu)
                        display_cpu_header(cpu, 64);
                        cpu_header = true;
                        charrep('-', 64);
-                       printf("\n");
+                       fprintf(output, "\n");
                }

-               printf("| ");
+               fprintf(output, "| ");
                display_factored_freq(p->freq, 8);
-               printf(" | ");
+               fprintf(output, " | ");
                display_factored_time(p->min_time == DBL_MAX ? 0. :
                                      p->min_time, 8);
-               printf(" | ");
+               fprintf(output, " | ");
                display_factored_time(p->max_time, 8);
-               printf(" | ");
+               fprintf(output, " | ");
                display_factored_time(p->avg_time, 8);
-               printf(" | ");
+               fprintf(output, " | ");
                display_factored_time(p->duration, 8);
-               printf(" | ");
-               printf("%5d", p->count);
-               printf(" | ");
-               printf("\n");
+               fprintf(output, " | ");
+               fprintf(output, "%5d", p->count);
+               fprintf(output, " | ");
+               fprintf(output, "\n");
        }

        return 0;
@@ -228,15 +252,15 @@ static int display_pstates(void *arg, char *cpu)
  static void display_wakeup_header(void)
  {
        charrep('-', 44);
-       printf("\n");
+       fprintf(output, "\n");

-       printf("| Wakeup |  #  |       Name      |  Count  |\n");
+       fprintf(output, "| Wakeup |  #  |       Name      |  Count  |\n");
  }

  static void display_wakeup_footer(void)
  {
        charrep('-', 44);
-       printf("\n\n");
+       fprintf(output, "\n\n");
  }

  static int display_wakeup(void *arg, char *cpu)
@@ -253,16 +277,16 @@ static int display_wakeup(void *arg, char *cpu)
                        display_cpu_header(cpu, 44);
                        cpu_header = true;
                        charrep('-', 44);
-                       printf("\n");
+                       fprintf(output, "\n");
                }

                if (irqinfo->irq_type == HARD_IRQ)
-                       printf("| %-6s | %-3d | %15.15s | %7d |\n",
+                       fprintf(output, "| %-6s | %-3d | %15.15s | %7d |\n",
                               "irq", irqinfo->id, irqinfo->name,
                               irqinfo->count);

                if (irqinfo->irq_type == IPI_IRQ)
-                       printf("| %-6s | --- | %15.15s | %7d |\n",
+                       fprintf(output, "| %-6s | --- | %15.15s | %7d |\n",
                               "ipi", irqinfo->name, irqinfo->count);
        }

@@ -1111,11 +1135,11 @@ static void help(const char *cmd)
  {
        fprintf(stderr,
                "\nUsage:\nTrace mode:\n\t%s --trace -f|--trace-file <filename>"
-               " -t|--duration <seconds> -c|--idle -p|--frequency -w|--wakeup",
-               basename(cmd));
+               " -o|--output-file <filename> -t|--duration <seconds>"
+               " -c|--idle -p|--frequency -w|--wakeup", basename(cmd));
        fprintf(stderr,
-               "\nReporting mode:\n\t%s --import -f|--trace-file <filename>",
-               basename(cmd));
+               "\nReporting mode:\n\t%s --import -f|--trace-file <filename>"
+               " -o|--output-file <filename>", basename(cmd));
        fprintf(stderr,
                "\n\nExamples:\n1. Run a trace, post-process the results"
                " (default is to show only C-state statistics):\n\tsudo "
@@ -1131,6 +1155,15 @@ static void help(const char *cmd)
        fprintf(stderr,
                "\n4. Post-process a trace captured earlier:\n\tsudo ./%s"
                " --import -f /tmp/mytrace\n", basename(cmd));
+       fprintf(stderr,
+               "\n5. Run a trace, post-process the results and print all"
+               " statistics into a file:\n\tsudo ./%s --trace -f /tmp/mytrace -t 10 
-p -c -w"
+               " -o /tmp/myreport\n", basename(cmd));
+       fprintf(stderr,
+               "\n6. Post-process a trace captured earlier and print all"
+               " statistics into a file:\n\tsudo ./%s --import -f /tmp/mytrace -p 
-c -w"
+               " -o /tmp/myreport\n",
+               basename(cmd));
  }

  static void version(const char *cmd)
@@ -1144,6 +1177,7 @@ int getoptions(int argc, char *argv[], struct 
program_options *options)
                { "trace",       no_argument,       &options->mode, TRACE },
                { "import",      no_argument,       &options->mode, IMPORT },
                { "trace-file",  required_argument, NULL, 'f' },
+               { "output-file", required_argument, NULL, 'o' },
                { "help",        no_argument,       NULL, 'h' },
                { "duration",    required_argument, NULL, 't' },
                { "version",     no_argument,       NULL, 'V' },
@@ -1157,13 +1191,14 @@ int getoptions(int argc, char *argv[], struct 
program_options *options)

        memset(options, 0, sizeof(*options));
        options->filename = NULL;
+       options->outfilename = NULL;
        options->mode = -1;
        options->format = -1;
        while (1) {

                int optindex = 0;

-               c = getopt_long(argc, argv, ":df:ht:cpwVv",
+               c = getopt_long(argc, argv, ":df:o:ht:cpwVv",
                                long_options, &optindex);
                if (c == -1)
                        break;
@@ -1172,6 +1207,9 @@ int getoptions(int argc, char *argv[], struct 
program_options *options)
                case 'f':
                        options->filename = optarg;
                        break;
+               case 'o':
+                       options->outfilename = optarg;
+                       break;
                case 'h':
                        help(argv[0]);
                        exit(0);
@@ -1427,7 +1465,7 @@ int main(int argc, char *argv[], char *const envp[])
                return -1;
        }

-       if (check_window_size()) {
+       if (check_window_size() && !options.outfilename) {
                fprintf(stderr, "The terminal must be at least "
                        "80 columns wide\n");
                return -1;
@@ -1501,6 +1539,8 @@ int main(int argc, char *argv[], char *const envp[])
         * the same cluster
         */
        if (0 == establish_idledata_to_topo(datas)) {
+               if (open_report_file(options.outfilename))
+                       return -1;

                if (options.display & IDLE_DISPLAY) {
                        display_cstates_header();
@@ -1519,6 +1559,8 @@ int main(int argc, char *argv[], char *const envp[])
                        dump_cpu_topo_info(display_wakeup, 1);
                        display_wakeup_footer();
                }
+
+               close_report_file();
        }

        release_cpu_topo_cstates();
diff --git a/idlestat.h b/idlestat.h
index 1d5f961..735f0fe 100644
--- a/idlestat.h
+++ b/idlestat.h
@@ -132,6 +132,7 @@ struct program_options {
        int display;
        unsigned int duration;
        char *filename;
+       char *outfilename;
        int verbose;
  };




--
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to