diff options
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/util/evlist.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 61d18dc..3cebc9a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -25,11 +25,12 @@ #include <linux/bitops.h> #include <linux/hash.h> +static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); +static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); + #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) -static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); - void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, struct thread_map *threads) { @@ -426,16 +427,38 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) return 0; } +static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx) +{ + int pos = fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP); + /* + * Save the idx so that when we filter out fds POLLHUP'ed we can + * close the associated evlist->mmap[] entry. + */ + if (pos >= 0) { + evlist->pollfd.priv[pos].idx = idx; + + fcntl(fd, F_SETFL, O_NONBLOCK); + } + + return pos; +} + int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) { - fcntl(fd, F_SETFL, O_NONBLOCK); + return __perf_evlist__add_pollfd(evlist, fd, -1); +} + +static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd) +{ + struct perf_evlist *evlist = container_of(fda, struct perf_evlist, pollfd); - return fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP); + perf_evlist__mmap_put(evlist, fda->priv[fd].idx); } int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) { - return fdarray__filter(&evlist->pollfd, revents_and_mask, NULL); + return fdarray__filter(&evlist->pollfd, revents_and_mask, + perf_evlist__munmap_filtered); } int perf_evlist__poll(struct perf_evlist *evlist, int timeout) @@ -777,7 +800,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, perf_evlist__mmap_get(evlist, idx); } - if (perf_evlist__add_pollfd(evlist, fd) < 0) { + if (__perf_evlist__add_pollfd(evlist, fd, idx) < 0) { perf_evlist__mmap_put(evlist, idx); return -1; } |