|
@@ -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;
|
|
|
}
|