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.