On 2016-06-16 at 18:51 Barret Rhoden <[email protected]> wrote:
> Hi - 
> 
> I overhauled Akaros perf_events, making it PERFILE2 ABI compliant,
> making it much more usable (very similar to Linux), and fixing a bunch
> of major bugs.

I updated this branch to have perf stat correctly send its output to
*its* FD 1, instead of /dev/stdout.

        [email protected]:brho/akaros.git perf
        2a95f9c69c95 ("perf: Update documentation")

Here's the diff between the branches, if you're curious:

diff --git a/tools/dev-util/perf/perf.c b/tools/dev-util/perf/perf.c
index 059188abb080..b6b3aa17482d 100644
--- a/tools/dev-util/perf/perf.c
+++ b/tools/dev-util/perf/perf.c
@@ -40,7 +40,7 @@ static struct perf_context *pctx;
 extern char **environ; /* POSIX envp */
 
 struct perf_opts {
-       const char                                      *output_file;
+       FILE                                            *outfile;
        const char                                      *events;
        char                                            **cmd_argv;
        int                                                     cmd_argc;
@@ -299,7 +299,7 @@ static error_t parse_record_opt(int key, char *arg, struct 
argp_state *state)
                /* Our default operation is to record backtraces. */
                break;
        case 'o':
-               p_opts->output_file = arg;
+               p_opts->outfile = xfopen(arg, "wb");
                break;
        case 'q':
                p_opts->record_quiet = TRUE;
@@ -307,8 +307,8 @@ static error_t parse_record_opt(int key, char *arg, struct 
argp_state *state)
        case ARGP_KEY_END:
                if (!p_opts->events)
                        p_opts->events = "cycles";
-               if (!p_opts->output_file)
-                       p_opts->output_file = "perf.data";
+               if (!p_opts->outfile)
+                       p_opts->outfile = xfopen("perf.data", "wb");
                if (!p_opts->record_period)
                        p_opts->record_period = freq_to_period(1000);
                break;
@@ -339,7 +339,8 @@ static int perf_record(struct perf_cmd *cmd, int argc, char 
*argv[])
        perf_stop_events(pctx);
        /* Generate the Linux perf file format with the traces which have been
         * created during this operation. */
-       perf_convert_trace_data(cctx, perf_cfg.kpdata_file, opts.output_file);
+       perf_convert_trace_data(cctx, perf_cfg.kpdata_file, opts.outfile);
+       fclose(opts.outfile);
        return 0;
 }
 
@@ -360,14 +361,14 @@ static error_t parse_stat_opt(int key, char *arg, struct 
argp_state *state)
                p_opts->stat_bignum = TRUE;
                break;
        case 'o':
-               p_opts->output_file = arg;
+               p_opts->outfile = xfopen(arg, "w+");
                break;
        case ARGP_KEY_END:
                if (!p_opts->events)
                        p_opts->events = "cache-misses,cache-references,"
                                         
"branch-misses,branches,instructions,cycles";
-               if (!p_opts->output_file)
-                       p_opts->output_file = "/dev/stdout";
+               if (!p_opts->outfile)
+                       p_opts->outfile = xfdopen(1, "w+");
                break;
        default:
                return ARGP_ERR_UNKNOWN;
@@ -502,6 +503,7 @@ static int perf_stat(struct perf_cmd *cmd, int argc, char 
*argv[])
 
        collect_argp(cmd, argc, argv, children, &opts);
        opts.sampling = FALSE;
+       out = opts.outfile;
 
        /* As soon as we submit one event, that event is being tracked, meaning 
that
         * the setup/teardown of perf events is also tracked.  Each event 
(including
@@ -514,8 +516,6 @@ static int perf_stat(struct perf_cmd *cmd, int argc, char 
*argv[])
        subtract_timespecs(&diff, &end, &start);
        stat_vals = collect_stats(pctx, &diff);
        perf_stop_events(pctx);
-
-       out = xfopen(opts.output_file, "w+");
        cmd_string = cmd_as_str(opts.cmd_argc, opts.cmd_argv);
        fprintf(out, "\nPerformance counter stats for '%s':\n\n", cmd_string);
        free(cmd_string);
diff --git a/tools/dev-util/perf/perf_core.c b/tools/dev-util/perf/perf_core.c
index e926033875ec..181d2f195a8a 100644
--- a/tools/dev-util/perf/perf_core.c
+++ b/tools/dev-util/perf/perf_core.c
@@ -760,20 +760,16 @@ void perf_show_events(const char *rx, FILE *file)
 }
 
 void perf_convert_trace_data(struct perfconv_context *cctx, const char *input,
-                                                        const char *output)
+                                                        FILE *outfile)
 {
-       FILE *infile, *outfile;
+       FILE *infile;
        size_t ksize;
 
        infile = xfopen(input, "rb");
        if (xfsize(infile) > 0) {
-               outfile = xfopen(output, "wb");
-
                perfconv_add_kernel_mmap(cctx);
                perfconv_add_kernel_buildid(cctx);
                perfconv_process_input(cctx, infile, outfile);
-
-               fclose(outfile);
        }
        fclose(infile);
 }
diff --git a/tools/dev-util/perf/perf_core.h b/tools/dev-util/perf/perf_core.h
index 3d79381d05f0..ef670836efb2 100644
--- a/tools/dev-util/perf/perf_core.h
+++ b/tools/dev-util/perf/perf_core.h
@@ -71,7 +71,7 @@ uint64_t perf_get_event_count(struct perf_context *pctx, 
unsigned int idx);
 void perf_context_show_events(struct perf_context *pctx, FILE *file);
 void perf_show_events(const char *rx, FILE *file);
 void perf_convert_trace_data(struct perfconv_context *cctx, const char *input,
-                                                        const char *output);
+                                                        FILE *outfile);
 
 static inline const struct perf_arch_info *perf_context_get_arch_info(
        const struct perf_context *pctx)
diff --git a/tools/dev-util/perf/xlib.c b/tools/dev-util/perf/xlib.c
index c673f80c00fc..897b68eb3b63 100644
--- a/tools/dev-util/perf/xlib.c
+++ b/tools/dev-util/perf/xlib.c
@@ -79,6 +79,19 @@ FILE *xfopen(const char *path, const char *mode)
        return file;
 }
 
+FILE *xfdopen(int fd, const char *mode)
+{
+       FILE *file = fdopen(fd, mode);
+
+       if (!file) {
+               fprintf(stderr, "Unable to reopen fd '%d' for mode '%s;: %s\n", 
fd,
+                       mode, strerror(errno));
+               exit(1);
+       }
+
+       return file;
+}
+
 off_t xfsize(FILE *file)
 {
        struct stat stat_buf;
diff --git a/tools/dev-util/perf/xlib.h b/tools/dev-util/perf/xlib.h
index 74d3eb13f76a..6793f2694e9c 100644
--- a/tools/dev-util/perf/xlib.h
+++ b/tools/dev-util/perf/xlib.h
@@ -36,6 +36,7 @@ void xread(int fd, void *data, size_t size);
 void xpwrite(int fd, const void *data, size_t size, off_t off);
 void xpread(int fd, void *data, size_t size, off_t off);
 FILE *xfopen(const char *path, const char *mode);
+FILE *xfdopen(int fd, const char *mode);
 off_t xfsize(FILE *file);
 void xfwrite(const void *data, size_t size, FILE *file);
 void xfseek(FILE *file, off_t offset, int whence);

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to