aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index a3a871f7bda..0d414199889 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -7,10 +7,52 @@
7#include <sys/types.h> 7#include <sys/types.h>
8#include <sys/mman.h> 8#include <sys/mman.h>
9 9
10#include "evlist.h"
11#include "evsel.h"
10#include "session.h" 12#include "session.h"
11#include "sort.h" 13#include "sort.h"
12#include "util.h" 14#include "util.h"
13 15
16static int perf_session__read_evlist(struct perf_session *session)
17{
18 int i, j;
19
20 session->evlist = perf_evlist__new(NULL, NULL);
21 if (session->evlist == NULL)
22 return -ENOMEM;
23
24 for (i = 0; i < session->header.attrs; ++i) {
25 struct perf_header_attr *hattr = session->header.attr[i];
26 struct perf_evsel *evsel = perf_evsel__new(&hattr->attr, i);
27
28 if (evsel == NULL)
29 goto out_delete_evlist;
30 /*
31 * Do it before so that if perf_evsel__alloc_id fails, this
32 * entry gets purged too at perf_evlist__delete().
33 */
34 perf_evlist__add(session->evlist, evsel);
35 /*
36 * We don't have the cpu and thread maps on the header, so
37 * for allocating the perf_sample_id table we fake 1 cpu and
38 * hattr->ids threads.
39 */
40 if (perf_evsel__alloc_id(evsel, 1, hattr->ids))
41 goto out_delete_evlist;
42
43 for (j = 0; j < hattr->ids; ++j)
44 perf_evlist__id_hash(session->evlist, evsel, 0, j,
45 hattr->id[j]);
46 }
47
48 return 0;
49
50out_delete_evlist:
51 perf_evlist__delete(session->evlist);
52 session->evlist = NULL;
53 return -ENOMEM;
54}
55
14static int perf_session__open(struct perf_session *self, bool force) 56static int perf_session__open(struct perf_session *self, bool force)
15{ 57{
16 struct stat input_stat; 58 struct stat input_stat;
@@ -56,6 +98,11 @@ static int perf_session__open(struct perf_session *self, bool force)
56 goto out_close; 98 goto out_close;
57 } 99 }
58 100
101 if (perf_session__read_evlist(self) < 0) {
102 pr_err("Not enough memory to read the event selector list\n");
103 goto out_close;
104 }
105
59 self->size = input_stat.st_size; 106 self->size = input_stat.st_size;
60 return 0; 107 return 0;
61 108
@@ -141,7 +188,6 @@ struct perf_session *perf_session__new(const char *filename, int mode,
141 memcpy(self->filename, filename, len); 188 memcpy(self->filename, filename, len);
142 self->threads = RB_ROOT; 189 self->threads = RB_ROOT;
143 INIT_LIST_HEAD(&self->dead_threads); 190 INIT_LIST_HEAD(&self->dead_threads);
144 self->hists_tree = RB_ROOT;
145 self->last_match = NULL; 191 self->last_match = NULL;
146 /* 192 /*
147 * On 64bit we can mmap the data file in one go. No need for tiny mmap 193 * On 64bit we can mmap the data file in one go. No need for tiny mmap
@@ -1137,3 +1183,18 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
1137 size_t ret = machine__fprintf_dsos_buildid(&self->host_machine, fp, with_hits); 1183 size_t ret = machine__fprintf_dsos_buildid(&self->host_machine, fp, with_hits);
1138 return ret + machines__fprintf_dsos_buildid(&self->machines, fp, with_hits); 1184 return ret + machines__fprintf_dsos_buildid(&self->machines, fp, with_hits);
1139} 1185}
1186
1187size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
1188{
1189 struct perf_evsel *pos;
1190 size_t ret = fprintf(fp, "Aggregated stats:\n");
1191
1192 ret += hists__fprintf_nr_events(&session->hists, fp);
1193
1194 list_for_each_entry(pos, &session->evlist->entries, node) {
1195 ret += fprintf(fp, "%s stats:\n", event_name(pos));
1196 ret += hists__fprintf_nr_events(&pos->hists, fp);
1197 }
1198
1199 return ret;
1200}