aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-03-10 09:15:54 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-03-10 09:15:54 -0500
commita91e5431d54f5359fccb5ec2512f252eb217707e (patch)
tree8f8ba4940d9f4e910b339baee13a710baa920378 /tools/perf/builtin-record.c
parent6547250381eb315acff3d52b4872ad775359407c (diff)
perf session: Use evlist/evsel for managing perf.data attributes
So that we can reuse things like the id to attr lookup routine (perf_evlist__id2evsel) that uses a hash table instead of the linear lookup done in the older perf_header_attr routines, etc. Also to make evsels/evlist more pervasive an API, simplyfing using the emerging perf lib. cc: Arun Sharma <arun@sharma-home.net> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c101
1 files changed, 35 insertions, 66 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index d40a81e8cc5..6febcc168a8 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -31,7 +31,6 @@
31#include <sys/mman.h> 31#include <sys/mman.h>
32 32
33#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 33#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
34#define SID(e, x, y) xyarray__entry(e->id, x, y)
35 34
36enum write_mode_t { 35enum write_mode_t {
37 WRITE_FORCE, 36 WRITE_FORCE,
@@ -40,7 +39,6 @@ enum write_mode_t {
40 39
41static u64 user_interval = ULLONG_MAX; 40static u64 user_interval = ULLONG_MAX;
42static u64 default_interval = 0; 41static u64 default_interval = 0;
43static u64 sample_type;
44 42
45static unsigned int page_size; 43static unsigned int page_size;
46static unsigned int mmap_pages = 128; 44static unsigned int mmap_pages = 128;
@@ -160,54 +158,6 @@ static void sig_atexit(void)
160 kill(getpid(), signr); 158 kill(getpid(), signr);
161} 159}
162 160
163static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr)
164{
165 struct perf_header_attr *h_attr;
166
167 if (nr < session->header.attrs) {
168 h_attr = session->header.attr[nr];
169 } else {
170 h_attr = perf_header_attr__new(a);
171 if (h_attr != NULL)
172 if (perf_header__add_attr(&session->header, h_attr) < 0) {
173 perf_header_attr__delete(h_attr);
174 h_attr = NULL;
175 }
176 }
177
178 return h_attr;
179}
180
181static void create_counter(struct perf_evsel *evsel, int cpu)
182{
183 struct perf_event_attr *attr = &evsel->attr;
184 struct perf_header_attr *h_attr;
185 struct perf_sample_id *sid;
186 int thread_index;
187
188 for (thread_index = 0; thread_index < evsel_list->threads->nr; thread_index++) {
189 h_attr = get_header_attr(attr, evsel->idx);
190 if (h_attr == NULL)
191 die("nomem\n");
192
193 if (!file_new) {
194 if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
195 fprintf(stderr, "incompatible append\n");
196 exit(-1);
197 }
198 }
199
200 sid = SID(evsel, cpu, thread_index);
201 if (perf_header_attr__add_id(h_attr, sid->id) < 0) {
202 pr_warning("Not enough memory to add id\n");
203 exit(-1);
204 }
205 }
206
207 if (!sample_type)
208 sample_type = attr->sample_type;
209}
210
211static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist) 161static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist)
212{ 162{
213 struct perf_event_attr *attr = &evsel->attr; 163 struct perf_event_attr *attr = &evsel->attr;
@@ -278,10 +228,28 @@ static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist)
278 } 228 }
279} 229}
280 230
231static bool perf_evlist__equal(struct perf_evlist *evlist,
232 struct perf_evlist *other)
233{
234 struct perf_evsel *pos, *pair;
235
236 if (evlist->nr_entries != other->nr_entries)
237 return false;
238
239 pair = list_entry(other->entries.next, struct perf_evsel, node);
240
241 list_for_each_entry(pos, &evlist->entries, node) {
242 if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0))
243 return false;
244 pair = list_entry(pair->node.next, struct perf_evsel, node);
245 }
246
247 return true;
248}
249
281static void open_counters(struct perf_evlist *evlist) 250static void open_counters(struct perf_evlist *evlist)
282{ 251{
283 struct perf_evsel *pos; 252 struct perf_evsel *pos;
284 int cpu;
285 253
286 list_for_each_entry(pos, &evlist->entries, node) { 254 list_for_each_entry(pos, &evlist->entries, node) {
287 struct perf_event_attr *attr = &pos->attr; 255 struct perf_event_attr *attr = &pos->attr;
@@ -364,10 +332,16 @@ try_again:
364 if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) 332 if (perf_evlist__mmap(evlist, mmap_pages, false) < 0)
365 die("failed to mmap with %d (%s)\n", errno, strerror(errno)); 333 die("failed to mmap with %d (%s)\n", errno, strerror(errno));
366 334
367 for (cpu = 0; cpu < evsel_list->cpus->nr; ++cpu) { 335 if (file_new)
368 list_for_each_entry(pos, &evlist->entries, node) 336 session->evlist = evlist;
369 create_counter(pos, cpu); 337 else {
370 } 338 if (!perf_evlist__equal(session->evlist, evlist)) {
339 fprintf(stderr, "incompatible append\n");
340 exit(-1);
341 }
342 }
343
344 perf_session__update_sample_type(session);
371} 345}
372 346
373static int process_buildids(void) 347static int process_buildids(void)
@@ -390,7 +364,7 @@ static void atexit_header(void)
390 364
391 if (!no_buildid) 365 if (!no_buildid)
392 process_buildids(); 366 process_buildids();
393 perf_header__write(&session->header, evsel_list, output, true); 367 perf_session__write_header(session, evsel_list, output, true);
394 perf_session__delete(session); 368 perf_session__delete(session);
395 perf_evlist__delete(evsel_list); 369 perf_evlist__delete(evsel_list);
396 symbol__exit(); 370 symbol__exit();
@@ -524,7 +498,7 @@ static int __cmd_record(int argc, const char **argv)
524 perf_header__set_feat(&session->header, HEADER_BUILD_ID); 498 perf_header__set_feat(&session->header, HEADER_BUILD_ID);
525 499
526 if (!file_new) { 500 if (!file_new) {
527 err = perf_header__read(session, output); 501 err = perf_session__read_header(session, output);
528 if (err < 0) 502 if (err < 0)
529 goto out_delete_session; 503 goto out_delete_session;
530 } 504 }
@@ -588,8 +562,6 @@ static int __cmd_record(int argc, const char **argv)
588 562
589 open_counters(evsel_list); 563 open_counters(evsel_list);
590 564
591 perf_session__set_sample_type(session, sample_type);
592
593 /* 565 /*
594 * perf_session__delete(session) will be called at atexit_header() 566 * perf_session__delete(session) will be called at atexit_header()
595 */ 567 */
@@ -600,20 +572,17 @@ static int __cmd_record(int argc, const char **argv)
600 if (err < 0) 572 if (err < 0)
601 return err; 573 return err;
602 } else if (file_new) { 574 } else if (file_new) {
603 err = perf_header__write(&session->header, evsel_list, 575 err = perf_session__write_header(session, evsel_list,
604 output, false); 576 output, false);
605 if (err < 0) 577 if (err < 0)
606 return err; 578 return err;
607 } 579 }
608 580
609 post_processing_offset = lseek(output, 0, SEEK_CUR); 581 post_processing_offset = lseek(output, 0, SEEK_CUR);
610 582
611 perf_session__set_sample_id_all(session, sample_id_all_avail);
612
613 if (pipe_output) { 583 if (pipe_output) {
614 err = perf_event__synthesize_attrs(&session->header, 584 err = perf_session__synthesize_attrs(session,
615 process_synthesized_event, 585 process_synthesized_event);
616 session);
617 if (err < 0) { 586 if (err < 0) {
618 pr_err("Couldn't synthesize attrs.\n"); 587 pr_err("Couldn't synthesize attrs.\n");
619 return err; 588 return err;