diff options
-rw-r--r-- | tools/perf/util/evlist.c | 38 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 5 |
2 files changed, 36 insertions, 7 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 6b13bfa7ac2c..bcf157c8a9da 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -402,7 +402,21 @@ int perf_evlist__enable_event_idx(struct perf_evlist *evlist, | |||
402 | return perf_evlist__enable_event_thread(evlist, evsel, idx); | 402 | return perf_evlist__enable_event_thread(evlist, evsel, idx); |
403 | } | 403 | } |
404 | 404 | ||
405 | static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) | 405 | static int perf_evlist__grow_pollfd(struct perf_evlist *evlist, int hint) |
406 | { | ||
407 | int nr_fds_alloc = evlist->nr_fds_alloc + hint; | ||
408 | size_t size = sizeof(struct pollfd) * nr_fds_alloc; | ||
409 | struct pollfd *pollfd = realloc(evlist->pollfd, size); | ||
410 | |||
411 | if (pollfd == NULL) | ||
412 | return -ENOMEM; | ||
413 | |||
414 | evlist->nr_fds_alloc = nr_fds_alloc; | ||
415 | evlist->pollfd = pollfd; | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) | ||
406 | { | 420 | { |
407 | int nr_cpus = cpu_map__nr(evlist->cpus); | 421 | int nr_cpus = cpu_map__nr(evlist->cpus); |
408 | int nr_threads = thread_map__nr(evlist->threads); | 422 | int nr_threads = thread_map__nr(evlist->threads); |
@@ -416,16 +430,28 @@ static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) | |||
416 | nfds += nr_cpus * nr_threads; | 430 | nfds += nr_cpus * nr_threads; |
417 | } | 431 | } |
418 | 432 | ||
419 | evlist->pollfd = malloc(sizeof(struct pollfd) * nfds); | 433 | if (evlist->nr_fds_alloc - evlist->nr_fds < nfds && |
420 | return evlist->pollfd != NULL ? 0 : -ENOMEM; | 434 | perf_evlist__grow_pollfd(evlist, nfds) < 0) |
435 | return -ENOMEM; | ||
436 | |||
437 | return 0; | ||
421 | } | 438 | } |
422 | 439 | ||
423 | void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) | 440 | int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) |
424 | { | 441 | { |
442 | /* | ||
443 | * XXX: 64 is arbitrary, just not to call realloc at each fd. | ||
444 | * Find a better autogrowing heuristic | ||
445 | */ | ||
446 | if (evlist->nr_fds == evlist->nr_fds_alloc && | ||
447 | perf_evlist__grow_pollfd(evlist, 64) < 0) | ||
448 | return -ENOMEM; | ||
449 | |||
425 | fcntl(fd, F_SETFL, O_NONBLOCK); | 450 | fcntl(fd, F_SETFL, O_NONBLOCK); |
426 | evlist->pollfd[evlist->nr_fds].fd = fd; | 451 | evlist->pollfd[evlist->nr_fds].fd = fd; |
427 | evlist->pollfd[evlist->nr_fds].events = POLLIN | POLLERR | POLLHUP; | 452 | evlist->pollfd[evlist->nr_fds].events = POLLIN | POLLERR | POLLHUP; |
428 | evlist->nr_fds++; | 453 | evlist->nr_fds++; |
454 | return 0; | ||
429 | } | 455 | } |
430 | 456 | ||
431 | int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) | 457 | int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) |
@@ -717,6 +743,7 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx, | |||
717 | evlist->mmap[idx].base = NULL; | 743 | evlist->mmap[idx].base = NULL; |
718 | return -1; | 744 | return -1; |
719 | } | 745 | } |
746 | |||
720 | return 0; | 747 | return 0; |
721 | } | 748 | } |
722 | 749 | ||
@@ -743,7 +770,8 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, | |||
743 | return -1; | 770 | return -1; |
744 | } | 771 | } |
745 | 772 | ||
746 | perf_evlist__add_pollfd(evlist, fd); | 773 | if (perf_evlist__add_pollfd(evlist, fd) < 0) |
774 | return -1; | ||
747 | 775 | ||
748 | if ((evsel->attr.read_format & PERF_FORMAT_ID) && | 776 | if ((evsel->attr.read_format & PERF_FORMAT_ID) && |
749 | perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) | 777 | perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 1082420951f9..bbc2fd01b5c5 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -30,6 +30,7 @@ struct perf_evlist { | |||
30 | int nr_entries; | 30 | int nr_entries; |
31 | int nr_groups; | 31 | int nr_groups; |
32 | int nr_fds; | 32 | int nr_fds; |
33 | int nr_fds_alloc; | ||
33 | int nr_mmaps; | 34 | int nr_mmaps; |
34 | size_t mmap_len; | 35 | size_t mmap_len; |
35 | int id_pos; | 36 | int id_pos; |
@@ -82,8 +83,8 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, | |||
82 | void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, | 83 | void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, |
83 | int cpu, int thread, u64 id); | 84 | int cpu, int thread, u64 id); |
84 | 85 | ||
85 | void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd); | 86 | int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd); |
86 | 87 | int perf_evlist__alloc_pollfd(struct perf_evlist *evlist); | |
87 | int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask); | 88 | int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask); |
88 | 89 | ||
89 | struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); | 90 | struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); |