aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2014-09-08 10:24:01 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-09-25 15:46:55 -0400
commit2171a9256862ec139a042832a9ae737b942ca882 (patch)
tree6664a28341e22f1aa0f6486b54621033047d05a9 /tools
parent82396986032915c1572bfb74b224fcc2e4e8ba7c (diff)
tools lib fd array: Allow associating an integer cookie with each entry
We will use this in perf's evlist class so that it can, at fdarray__filter() time, to unmap the associated ring buffer. We may need to have further info associated with each fdarray entry, in that case we'll make that int array a 'union fdarray_priv' one and put a pointer there so that users can stash whatever they want there. For now, an int is enough tho. v2: Add clarification to the per array entry priv area, as well as make it a union, which makes usage a bit longer, but if/when we make it use more space by allowing per entry pointers existing users source code will not have to be changed, just rebuilt. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Borislav Petkov <bp@suse.de> 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> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Link: http://lkml.kernel.org/n/tip-0p00bn83quck3fio3kcs9vca@git.kernel.org
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/api/fd/array.c28
-rw-r--r--tools/lib/api/fd/array.h16
-rw-r--r--tools/perf/tests/fdarray.c8
-rw-r--r--tools/perf/util/evlist.c2
4 files changed, 44 insertions, 10 deletions
diff --git a/tools/lib/api/fd/array.c b/tools/lib/api/fd/array.c
index 4889c7d42961..0e636c4339b8 100644
--- a/tools/lib/api/fd/array.c
+++ b/tools/lib/api/fd/array.c
@@ -13,21 +13,31 @@
13void fdarray__init(struct fdarray *fda, int nr_autogrow) 13void fdarray__init(struct fdarray *fda, int nr_autogrow)
14{ 14{
15 fda->entries = NULL; 15 fda->entries = NULL;
16 fda->priv = NULL;
16 fda->nr = fda->nr_alloc = 0; 17 fda->nr = fda->nr_alloc = 0;
17 fda->nr_autogrow = nr_autogrow; 18 fda->nr_autogrow = nr_autogrow;
18} 19}
19 20
20int fdarray__grow(struct fdarray *fda, int nr) 21int fdarray__grow(struct fdarray *fda, int nr)
21{ 22{
23 void *priv;
22 int nr_alloc = fda->nr_alloc + nr; 24 int nr_alloc = fda->nr_alloc + nr;
25 size_t psize = sizeof(fda->priv[0]) * nr_alloc;
23 size_t size = sizeof(struct pollfd) * nr_alloc; 26 size_t size = sizeof(struct pollfd) * nr_alloc;
24 struct pollfd *entries = realloc(fda->entries, size); 27 struct pollfd *entries = realloc(fda->entries, size);
25 28
26 if (entries == NULL) 29 if (entries == NULL)
27 return -ENOMEM; 30 return -ENOMEM;
28 31
32 priv = realloc(fda->priv, psize);
33 if (priv == NULL) {
34 free(entries);
35 return -ENOMEM;
36 }
37
29 fda->nr_alloc = nr_alloc; 38 fda->nr_alloc = nr_alloc;
30 fda->entries = entries; 39 fda->entries = entries;
40 fda->priv = priv;
31 return 0; 41 return 0;
32} 42}
33 43
@@ -50,6 +60,7 @@ struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow)
50void fdarray__exit(struct fdarray *fda) 60void fdarray__exit(struct fdarray *fda)
51{ 61{
52 free(fda->entries); 62 free(fda->entries);
63 free(fda->priv);
53 fdarray__init(fda, 0); 64 fdarray__init(fda, 0);
54} 65}
55 66
@@ -61,6 +72,8 @@ void fdarray__delete(struct fdarray *fda)
61 72
62int fdarray__add(struct fdarray *fda, int fd, short revents) 73int fdarray__add(struct fdarray *fda, int fd, short revents)
63{ 74{
75 int pos = fda->nr;
76
64 if (fda->nr == fda->nr_alloc && 77 if (fda->nr == fda->nr_alloc &&
65 fdarray__grow(fda, fda->nr_autogrow) < 0) 78 fdarray__grow(fda, fda->nr_autogrow) < 0)
66 return -ENOMEM; 79 return -ENOMEM;
@@ -68,10 +81,11 @@ int fdarray__add(struct fdarray *fda, int fd, short revents)
68 fda->entries[fda->nr].fd = fd; 81 fda->entries[fda->nr].fd = fd;
69 fda->entries[fda->nr].events = revents; 82 fda->entries[fda->nr].events = revents;
70 fda->nr++; 83 fda->nr++;
71 return 0; 84 return pos;
72} 85}
73 86
74int fdarray__filter(struct fdarray *fda, short revents) 87int fdarray__filter(struct fdarray *fda, short revents,
88 void (*entry_destructor)(struct fdarray *fda, int fd))
75{ 89{
76 int fd, nr = 0; 90 int fd, nr = 0;
77 91
@@ -79,11 +93,17 @@ int fdarray__filter(struct fdarray *fda, short revents)
79 return 0; 93 return 0;
80 94
81 for (fd = 0; fd < fda->nr; ++fd) { 95 for (fd = 0; fd < fda->nr; ++fd) {
82 if (fda->entries[fd].revents & revents) 96 if (fda->entries[fd].revents & revents) {
97 if (entry_destructor)
98 entry_destructor(fda, fd);
99
83 continue; 100 continue;
101 }
84 102
85 if (fd != nr) 103 if (fd != nr) {
86 fda->entries[nr] = fda->entries[fd]; 104 fda->entries[nr] = fda->entries[fd];
105 fda->priv[nr] = fda->priv[fd];
106 }
87 107
88 ++nr; 108 ++nr;
89 } 109 }
diff --git a/tools/lib/api/fd/array.h b/tools/lib/api/fd/array.h
index de38361ba69e..45db01818f45 100644
--- a/tools/lib/api/fd/array.h
+++ b/tools/lib/api/fd/array.h
@@ -5,11 +5,24 @@
5 5
6struct pollfd; 6struct pollfd;
7 7
8/**
9 * struct fdarray: Array of file descriptors
10 *
11 * @priv: Per array entry priv area, users should access just its contents,
12 * not set it to anything, as it is kept in synch with @entries, being
13 * realloc'ed, * for instance, in fdarray__{grow,filter}.
14 *
15 * I.e. using 'fda->priv[N].idx = * value' where N < fda->nr is ok,
16 * but doing 'fda->priv = malloc(M)' is not allowed.
17 */
8struct fdarray { 18struct fdarray {
9 int nr; 19 int nr;
10 int nr_alloc; 20 int nr_alloc;
11 int nr_autogrow; 21 int nr_autogrow;
12 struct pollfd *entries; 22 struct pollfd *entries;
23 union {
24 int idx;
25 } *priv;
13}; 26};
14 27
15void fdarray__init(struct fdarray *fda, int nr_autogrow); 28void fdarray__init(struct fdarray *fda, int nr_autogrow);
@@ -20,7 +33,8 @@ void fdarray__delete(struct fdarray *fda);
20 33
21int fdarray__add(struct fdarray *fda, int fd, short revents); 34int fdarray__add(struct fdarray *fda, int fd, short revents);
22int fdarray__poll(struct fdarray *fda, int timeout); 35int fdarray__poll(struct fdarray *fda, int timeout);
23int fdarray__filter(struct fdarray *fda, short revents); 36int fdarray__filter(struct fdarray *fda, short revents,
37 void (*entry_destructor)(struct fdarray *fda, int fd));
24int fdarray__grow(struct fdarray *fda, int extra); 38int fdarray__grow(struct fdarray *fda, int extra);
25int fdarray__fprintf(struct fdarray *fda, FILE *fp); 39int fdarray__fprintf(struct fdarray *fda, FILE *fp);
26 40
diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c
index a0fea62ec368..d24b837951d4 100644
--- a/tools/perf/tests/fdarray.c
+++ b/tools/perf/tests/fdarray.c
@@ -36,7 +36,7 @@ int test__fdarray__filter(void)
36 } 36 }
37 37
38 fdarray__init_revents(fda, POLLIN); 38 fdarray__init_revents(fda, POLLIN);
39 nr_fds = fdarray__filter(fda, POLLHUP); 39 nr_fds = fdarray__filter(fda, POLLHUP, NULL);
40 if (nr_fds != fda->nr_alloc) { 40 if (nr_fds != fda->nr_alloc) {
41 pr_debug("\nfdarray__filter()=%d != %d shouldn't have filtered anything", 41 pr_debug("\nfdarray__filter()=%d != %d shouldn't have filtered anything",
42 nr_fds, fda->nr_alloc); 42 nr_fds, fda->nr_alloc);
@@ -44,7 +44,7 @@ int test__fdarray__filter(void)
44 } 44 }
45 45
46 fdarray__init_revents(fda, POLLHUP); 46 fdarray__init_revents(fda, POLLHUP);
47 nr_fds = fdarray__filter(fda, POLLHUP); 47 nr_fds = fdarray__filter(fda, POLLHUP, NULL);
48 if (nr_fds != 0) { 48 if (nr_fds != 0) {
49 pr_debug("\nfdarray__filter()=%d != %d, should have filtered all fds", 49 pr_debug("\nfdarray__filter()=%d != %d, should have filtered all fds",
50 nr_fds, fda->nr_alloc); 50 nr_fds, fda->nr_alloc);
@@ -57,7 +57,7 @@ int test__fdarray__filter(void)
57 57
58 pr_debug("\nfiltering all but fda->entries[2]:"); 58 pr_debug("\nfiltering all but fda->entries[2]:");
59 fdarray__fprintf_prefix(fda, "before", stderr); 59 fdarray__fprintf_prefix(fda, "before", stderr);
60 nr_fds = fdarray__filter(fda, POLLHUP); 60 nr_fds = fdarray__filter(fda, POLLHUP, NULL);
61 fdarray__fprintf_prefix(fda, " after", stderr); 61 fdarray__fprintf_prefix(fda, " after", stderr);
62 if (nr_fds != 1) { 62 if (nr_fds != 1) {
63 pr_debug("\nfdarray__filter()=%d != 1, should have left just one event", nr_fds); 63 pr_debug("\nfdarray__filter()=%d != 1, should have left just one event", nr_fds);
@@ -78,7 +78,7 @@ int test__fdarray__filter(void)
78 78
79 pr_debug("\nfiltering all but (fda->entries[0], fda->entries[3]):"); 79 pr_debug("\nfiltering all but (fda->entries[0], fda->entries[3]):");
80 fdarray__fprintf_prefix(fda, "before", stderr); 80 fdarray__fprintf_prefix(fda, "before", stderr);
81 nr_fds = fdarray__filter(fda, POLLHUP); 81 nr_fds = fdarray__filter(fda, POLLHUP, NULL);
82 fdarray__fprintf_prefix(fda, " after", stderr); 82 fdarray__fprintf_prefix(fda, " after", stderr);
83 if (nr_fds != 2) { 83 if (nr_fds != 2) {
84 pr_debug("\nfdarray__filter()=%d != 2, should have left just two events", 84 pr_debug("\nfdarray__filter()=%d != 2, should have left just two events",
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index efddee5a23e9..61d18dc83e8e 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -435,7 +435,7 @@ int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
435 435
436int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) 436int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask)
437{ 437{
438 return fdarray__filter(&evlist->pollfd, revents_and_mask); 438 return fdarray__filter(&evlist->pollfd, revents_and_mask, NULL);
439} 439}
440 440
441int perf_evlist__poll(struct perf_evlist *evlist, int timeout) 441int perf_evlist__poll(struct perf_evlist *evlist, int timeout)