Skip to content

Commit

Permalink
perf tools: Introduce perf_session class
Browse files Browse the repository at this point in the history
That does all the initialization boilerplate, opening the file,
reading the header, checking if it is valid, etc.

And that will as well have the threads list, kmap (now) global
variable, etc, so that we can handle two (or more) perf.data files
describing sessions to compare.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260573842-19720-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed Dec 12, 2009
1 parent ea08d8c commit 94c744b
Show file tree
Hide file tree
Showing 15 changed files with 206 additions and 181 deletions.
3 changes: 3 additions & 0 deletions tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,9 @@ LIB_H += util/parse-options.h
LIB_H += util/parse-events.h
LIB_H += util/quote.h
LIB_H += util/util.h
LIB_H += util/header.h
LIB_H += util/help.h
LIB_H += util/session.h
LIB_H += util/strbuf.h
LIB_H += util/string.h
LIB_H += util/strlist.h
Expand Down Expand Up @@ -405,6 +407,7 @@ LIB_OBJS += util/callchain.o
LIB_OBJS += util/values.o
LIB_OBJS += util/debug.o
LIB_OBJS += util/map.o
LIB_OBJS += util/session.o
LIB_OBJS += util/thread.o
LIB_OBJS += util/trace-event-parse.o
LIB_OBJS += util/trace-event-read.o
Expand Down
15 changes: 10 additions & 5 deletions tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "util/thread.h"
#include "util/sort.h"
#include "util/hist.h"
#include "util/session.h"
#include "util/data_map.h"

static char const *input_name = "perf.data";
Expand Down Expand Up @@ -462,21 +463,23 @@ static struct perf_file_handler file_handler = {

static int __cmd_annotate(void)
{
struct perf_header *header;
struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);
struct thread *idle;
int ret;

if (session == NULL)
return -ENOMEM;

idle = register_idle_thread();
register_perf_file_handler(&file_handler);

ret = mmap_dispatch_perf_file(&header, input_name, 0, 0,
&event__cwdlen, &event__cwd);
ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
if (ret)
return ret;
goto out_delete;

if (dump_trace) {
event__print_totals();
return 0;
goto out_delete;
}

if (verbose > 3)
Expand All @@ -489,6 +492,8 @@ static int __cmd_annotate(void)
output__resort(event__total[0]);

find_annotations();
out_delete:
perf_session__delete(session);

return ret;
}
Expand Down
55 changes: 8 additions & 47 deletions tools/perf/builtin-buildid-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#include "util/cache.h"
#include "util/data_map.h"
#include "util/debug.h"
#include "util/header.h"
#include "util/parse-options.h"
#include "util/session.h"
#include "util/symbol.h"

static char const *input_name = "perf.data";
Expand Down Expand Up @@ -55,56 +55,17 @@ static int perf_file_section__process_buildids(struct perf_file_section *self,
static int __cmd_buildid_list(void)
{
int err = -1;
struct perf_header *header;
struct perf_file_header f_header;
struct stat input_stat;
int input = open(input_name, O_RDONLY);
struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);

if (input < 0) {
pr_err("failed to open file: %s", input_name);
if (!strcmp(input_name, "perf.data"))
pr_err(" (try 'perf record' first)");
pr_err("\n");
goto out;
}

err = fstat(input, &input_stat);
if (err < 0) {
perror("failed to stat file");
goto out_close;
}

if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
pr_err("file %s not owned by current user or root\n",
input_name);
goto out_close;
}

if (!input_stat.st_size) {
pr_info("zero-sized file, nothing to do!\n");
goto out_close;
}

err = -1;
header = perf_header__new();
if (header == NULL)
goto out_close;

if (perf_file_header__read(&f_header, header, input) < 0) {
pr_warning("incompatible file format");
goto out_close;
}
if (session == NULL)
return -1;

err = perf_header__process_sections(header, input,
err = perf_header__process_sections(&session->header, session->fd,
perf_file_section__process_buildids);
if (err >= 0)
dsos__fprintf_buildid(stdout);

if (err < 0)
goto out_close;

dsos__fprintf_buildid(stdout);
out_close:
close(input);
out:
perf_session__delete(session);
return err;
}

Expand Down
13 changes: 10 additions & 3 deletions tools/perf/builtin-kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "util/symbol.h"
#include "util/thread.h"
#include "util/header.h"
#include "util/session.h"

#include "util/parse-options.h"
#include "util/trace-event.h"
Expand All @@ -20,7 +21,6 @@ typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *);

static char const *input_name = "perf.data";

static struct perf_header *header;
static u64 sample_type;

static int alloc_flag;
Expand Down Expand Up @@ -367,11 +367,18 @@ static struct perf_file_handler file_handler = {

static int read_events(void)
{
int err;
struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);

if (session == NULL)
return -ENOMEM;

register_idle_thread();
register_perf_file_handler(&file_handler);

return mmap_dispatch_perf_file(&header, input_name, 0, 0,
&event__cwdlen, &event__cwd);
err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
perf_session__delete(session);
return err;
}

static double fragmentation(unsigned long n_req, unsigned long n_alloc)
Expand Down
25 changes: 13 additions & 12 deletions tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "util/header.h"
#include "util/event.h"
#include "util/debug.h"
#include "util/session.h"
#include "util/symbol.h"

#include <unistd.h>
Expand Down Expand Up @@ -62,7 +63,7 @@ static int nr_cpu = 0;

static int file_new = 1;

struct perf_header *header = NULL;
static struct perf_session *session;

struct mmap_data {
int counter;
Expand Down Expand Up @@ -216,12 +217,12 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n
{
struct perf_header_attr *h_attr;

if (nr < header->attrs) {
h_attr = header->attr[nr];
if (nr < session->header.attrs) {
h_attr = session->header.attr[nr];
} else {
h_attr = perf_header_attr__new(a);
if (h_attr != NULL)
if (perf_header__add_attr(header, h_attr) < 0) {
if (perf_header__add_attr(&session->header, h_attr) < 0) {
perf_header_attr__delete(h_attr);
h_attr = NULL;
}
Expand Down Expand Up @@ -395,9 +396,9 @@ static void open_counters(int cpu, pid_t pid)

static void atexit_header(void)
{
header->data_size += bytes_written;
session->header.data_size += bytes_written;

perf_header__write(header, output, true);
perf_header__write(&session->header, output, true);
}

static int __cmd_record(int argc, const char **argv)
Expand Down Expand Up @@ -440,24 +441,24 @@ static int __cmd_record(int argc, const char **argv)
exit(-1);
}

header = perf_header__new();
if (header == NULL) {
session = perf_session__new(output_name, O_WRONLY, force);
if (session == NULL) {
pr_err("Not enough memory for reading perf file header\n");
return -1;
}

if (!file_new) {
err = perf_header__read(header, output);
err = perf_header__read(&session->header, output);
if (err < 0)
return err;
}

if (raw_samples) {
perf_header__set_feat(header, HEADER_TRACE_INFO);
perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
} else {
for (i = 0; i < nr_counters; i++) {
if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
perf_header__set_feat(header, HEADER_TRACE_INFO);
perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
break;
}
}
Expand All @@ -481,7 +482,7 @@ static int __cmd_record(int argc, const char **argv)
}

if (file_new) {
err = perf_header__write(header, output, false);
err = perf_header__write(&session->header, output, false);
if (err < 0)
return err;
}
Expand Down
20 changes: 13 additions & 7 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "perf.h"
#include "util/debug.h"
#include "util/header.h"
#include "util/session.h"

#include "util/parse-options.h"
#include "util/parse-events.h"
Expand Down Expand Up @@ -52,7 +53,7 @@ static int exclude_other = 1;

static char callchain_default_opt[] = "fractal,0.5";

static struct perf_header *header;
static struct perf_session *session;

static u64 sample_type;

Expand Down Expand Up @@ -701,7 +702,7 @@ static int process_read_event(event_t *event)
{
struct perf_event_attr *attr;

attr = perf_header__find_attr(event->read.id, header);
attr = perf_header__find_attr(event->read.id, &session->header);

if (show_threads) {
const char *name = attr ? __event_name(attr->type, attr->config)
Expand Down Expand Up @@ -766,6 +767,10 @@ static int __cmd_report(void)
struct thread *idle;
int ret;

session = perf_session__new(input_name, O_RDONLY, force);
if (session == NULL)
return -ENOMEM;

idle = register_idle_thread();
thread__comm_adjust(idle);

Expand All @@ -774,14 +779,14 @@ static int __cmd_report(void)

register_perf_file_handler(&file_handler);

ret = mmap_dispatch_perf_file(&header, input_name, force,
full_paths, &event__cwdlen, &event__cwd);
ret = perf_session__process_events(session, full_paths,
&event__cwdlen, &event__cwd);
if (ret)
return ret;
goto out_delete;

if (dump_trace) {
event__print_totals();
return 0;
goto out_delete;
}

if (verbose > 3)
Expand All @@ -796,7 +801,8 @@ static int __cmd_report(void)

if (show_threads)
perf_read_values_destroy(&show_threads_values);

out_delete:
perf_session__delete(session);
return ret;
}

Expand Down
13 changes: 10 additions & 3 deletions tools/perf/builtin-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "util/symbol.h"
#include "util/thread.h"
#include "util/header.h"
#include "util/session.h"

#include "util/parse-options.h"
#include "util/trace-event.h"
Expand All @@ -21,7 +22,6 @@

static char const *input_name = "perf.data";

static struct perf_header *header;
static u64 sample_type;

static char default_sort_order[] = "avg, max, switch, runtime";
Expand Down Expand Up @@ -1663,11 +1663,18 @@ static struct perf_file_handler file_handler = {

static int read_events(void)
{
int err;
struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);

if (session == NULL)
return -ENOMEM;

register_idle_thread();
register_perf_file_handler(&file_handler);

return mmap_dispatch_perf_file(&header, input_name, 0, 0,
&event__cwdlen, &event__cwd);
err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
perf_session__delete(session);
return err;
}

static void print_bad_events(void)
Expand Down
15 changes: 9 additions & 6 deletions tools/perf/builtin-timechart.c
Original file line number Diff line number Diff line change
Expand Up @@ -1059,15 +1059,17 @@ static struct perf_file_handler file_handler = {

static int __cmd_timechart(void)
{
struct perf_header *header;
struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
int ret;

if (session == NULL)
return -ENOMEM;

register_perf_file_handler(&file_handler);

ret = mmap_dispatch_perf_file(&header, input_name, 0, 0,
&event__cwdlen, &event__cwd);
ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
if (ret)
return EXIT_FAILURE;
goto out_delete;

process_samples();

Expand All @@ -1079,8 +1081,9 @@ static int __cmd_timechart(void)

pr_info("Written %2.1f seconds of trace to %s.\n",
(last_time - first_time) / 1000000000.0, output_name);

return EXIT_SUCCESS;
out_delete:
perf_session__delete(session);
return ret;
}

static const char * const timechart_usage[] = {
Expand Down
Loading

0 comments on commit 94c744b

Please sign in to comment.