diff options
author | 2014-08-18 16:44:06 -0300 | |
---|---|---|
committer | 2014-09-25 16:46:54 -0300 | |
commit | ad6765dd3b2f043e819bdec565db8f5a2f781e06 (patch) | |
tree | 0fb445dcb26922b043d240e6f087d15fe7269c2a /tools/perf/util/evlist.c | |
parent | perf evlist: We need to poll all event file descriptors (diff) | |
download | linux-ad6765dd3b2f043e819bdec565db8f5a2f781e06.tar.gz linux-ad6765dd3b2f043e819bdec565db8f5a2f781e06.tar.bz2 linux-ad6765dd3b2f043e819bdec565db8f5a2f781e06.zip |
perf evlist: Allow growing pollfd on add method
This way we will be able to add more file descriptors to be polled,
like stdin or some timer fd.
At this point we might as well yank the pollfd class from evlist so that
it can be used in other places.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/n/tip-o2mzsjl7taumsoc35ryol00i@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/evlist.c')
-rw-r--r-- | tools/perf/util/evlist.c | 38 |
1 files changed, 33 insertions, 5 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, return perf_evlist__enable_event_thread(evlist, evsel, idx); } -static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) +static int perf_evlist__grow_pollfd(struct perf_evlist *evlist, int hint) +{ + int nr_fds_alloc = evlist->nr_fds_alloc + hint; + size_t size = sizeof(struct pollfd) * nr_fds_alloc; + struct pollfd *pollfd = realloc(evlist->pollfd, size); + + if (pollfd == NULL) + return -ENOMEM; + + evlist->nr_fds_alloc = nr_fds_alloc; + evlist->pollfd = pollfd; + return 0; +} + +int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) { int nr_cpus = cpu_map__nr(evlist->cpus); int nr_threads = thread_map__nr(evlist->threads); @@ -416,16 +430,28 @@ static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) nfds += nr_cpus * nr_threads; } - evlist->pollfd = malloc(sizeof(struct pollfd) * nfds); - return evlist->pollfd != NULL ? 0 : -ENOMEM; + if (evlist->nr_fds_alloc - evlist->nr_fds < nfds && + perf_evlist__grow_pollfd(evlist, nfds) < 0) + return -ENOMEM; + + return 0; } -void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) +int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) { + /* + * XXX: 64 is arbitrary, just not to call realloc at each fd. + * Find a better autogrowing heuristic + */ + if (evlist->nr_fds == evlist->nr_fds_alloc && + perf_evlist__grow_pollfd(evlist, 64) < 0) + return -ENOMEM; + fcntl(fd, F_SETFL, O_NONBLOCK); evlist->pollfd[evlist->nr_fds].fd = fd; evlist->pollfd[evlist->nr_fds].events = POLLIN | POLLERR | POLLHUP; evlist->nr_fds++; + return 0; } 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, evlist->mmap[idx].base = NULL; return -1; } + return 0; } @@ -743,7 +770,8 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, return -1; } - perf_evlist__add_pollfd(evlist, fd); + if (perf_evlist__add_pollfd(evlist, fd) < 0) + return -1; if ((evsel->attr.read_format & PERF_FORMAT_ID) && perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) |