7 static struct perf_file_handler
*curr_handler
;
8 static unsigned long mmap_window
= 32;
9 static char __cwd
[PATH_MAX
];
11 static int process_event_stub(event_t
*event __used
)
13 dump_printf(": unhandled!\n");
17 void register_perf_file_handler(struct perf_file_handler
*handler
)
19 if (!handler
->process_sample_event
)
20 handler
->process_sample_event
= process_event_stub
;
21 if (!handler
->process_mmap_event
)
22 handler
->process_mmap_event
= process_event_stub
;
23 if (!handler
->process_comm_event
)
24 handler
->process_comm_event
= process_event_stub
;
25 if (!handler
->process_fork_event
)
26 handler
->process_fork_event
= process_event_stub
;
27 if (!handler
->process_exit_event
)
28 handler
->process_exit_event
= process_event_stub
;
29 if (!handler
->process_lost_event
)
30 handler
->process_lost_event
= process_event_stub
;
31 if (!handler
->process_read_event
)
32 handler
->process_read_event
= process_event_stub
;
33 if (!handler
->process_throttle_event
)
34 handler
->process_throttle_event
= process_event_stub
;
35 if (!handler
->process_unthrottle_event
)
36 handler
->process_unthrottle_event
= process_event_stub
;
38 curr_handler
= handler
;
41 static const char *event__name
[] = {
43 [PERF_RECORD_MMAP
] = "MMAP",
44 [PERF_RECORD_LOST
] = "LOST",
45 [PERF_RECORD_COMM
] = "COMM",
46 [PERF_RECORD_EXIT
] = "EXIT",
47 [PERF_RECORD_THROTTLE
] = "THROTTLE",
48 [PERF_RECORD_UNTHROTTLE
] = "UNTHROTTLE",
49 [PERF_RECORD_FORK
] = "FORK",
50 [PERF_RECORD_READ
] = "READ",
51 [PERF_RECORD_SAMPLE
] = "SAMPLE",
54 unsigned long event__total
[PERF_RECORD_MAX
];
56 void event__print_totals(void)
59 for (i
= 0; i
< PERF_RECORD_MAX
; ++i
)
60 pr_info("%10s events: %10ld\n",
61 event__name
[i
], event__total
[i
]);
65 process_event(event_t
*event
, unsigned long offset
, unsigned long head
)
69 if (event
->header
.type
< PERF_RECORD_MAX
) {
70 dump_printf("%p [%p]: PERF_RECORD_%s",
71 (void *)(offset
+ head
),
72 (void *)(long)(event
->header
.size
),
73 event__name
[event
->header
.type
]);
75 ++event__total
[event
->header
.type
];
78 switch (event
->header
.type
) {
79 case PERF_RECORD_SAMPLE
:
80 return curr_handler
->process_sample_event(event
);
81 case PERF_RECORD_MMAP
:
82 return curr_handler
->process_mmap_event(event
);
83 case PERF_RECORD_COMM
:
84 return curr_handler
->process_comm_event(event
);
85 case PERF_RECORD_FORK
:
86 return curr_handler
->process_fork_event(event
);
87 case PERF_RECORD_EXIT
:
88 return curr_handler
->process_exit_event(event
);
89 case PERF_RECORD_LOST
:
90 return curr_handler
->process_lost_event(event
);
91 case PERF_RECORD_READ
:
92 return curr_handler
->process_read_event(event
);
93 case PERF_RECORD_THROTTLE
:
94 return curr_handler
->process_throttle_event(event
);
95 case PERF_RECORD_UNTHROTTLE
:
96 return curr_handler
->process_unthrottle_event(event
);
98 curr_handler
->total_unknown
++;
103 int perf_header__read_build_ids(int input
, u64 offset
, u64 size
)
105 struct build_id_event bev
;
106 char filename
[PATH_MAX
];
107 u64 limit
= offset
+ size
;
110 while (offset
< limit
) {
114 if (read(input
, &bev
, sizeof(bev
)) != sizeof(bev
))
117 len
= bev
.header
.size
- sizeof(bev
);
118 if (read(input
, filename
, len
) != len
)
121 dso
= dsos__findnew(filename
);
123 dso__set_build_id(dso
, &bev
.build_id
);
125 offset
+= bev
.header
.size
;
132 int perf_session__process_events(struct perf_session
*self
,
133 int full_paths
, int *cwdlen
, char **cwd
)
136 unsigned long head
, shift
;
137 unsigned long offset
= 0;
144 if (curr_handler
== NULL
) {
145 pr_debug("Forgot to register perf file handler\n");
149 page_size
= getpagesize();
151 head
= self
->header
.data_offset
;
152 sample_type
= perf_header__sample_type(&self
->header
);
155 if (curr_handler
->sample_type_check
&&
156 curr_handler
->sample_type_check(sample_type
) < 0)
160 if (getcwd(__cwd
, sizeof(__cwd
)) == NULL
) {
161 pr_err("failed to get the current directory\n");
166 *cwdlen
= strlen(*cwd
);
172 shift
= page_size
* (head
/ page_size
);
177 buf
= mmap(NULL
, page_size
* mmap_window
, PROT_READ
,
178 MAP_SHARED
, self
->fd
, offset
);
179 if (buf
== MAP_FAILED
) {
180 pr_err("failed to mmap file\n");
186 event
= (event_t
*)(buf
+ head
);
188 size
= event
->header
.size
;
192 if (head
+ event
->header
.size
>= page_size
* mmap_window
) {
195 shift
= page_size
* (head
/ page_size
);
197 munmap_ret
= munmap(buf
, page_size
* mmap_window
);
198 assert(munmap_ret
== 0);
205 size
= event
->header
.size
;
207 dump_printf("\n%p [%p]: event: %d\n",
208 (void *)(offset
+ head
),
209 (void *)(long)event
->header
.size
,
212 if (!size
|| process_event(event
, offset
, head
) < 0) {
214 dump_printf("%p [%p]: skipping unknown header type: %d\n",
215 (void *)(offset
+ head
),
216 (void *)(long)(event
->header
.size
),
220 * assume we lost track of the stream, check alignment, and
221 * increment a single u64 in the hope to catch on again 'soon'.
224 if (unlikely(head
& 7))
232 if (offset
+ head
>= self
->header
.data_offset
+ self
->header
.data_size
)
235 if (offset
+ head
< self
->size
)