diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-09-03 17:02:59 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-09-25 15:46:55 -0400 |
commit | 1b85337d0685d1dc5a6f9061434ba4316d69f3b8 (patch) | |
tree | 2aae4189996ae07c65c8aaa2fc205ceba58cc7fb /tools/lib/api | |
parent | f66a889dbc96dd342c87232d74f0956076707746 (diff) |
tools lib api: Adopt fdarray class from perf's evlist
The extensible file description array that grew in the perf_evlist class
can be useful for other tools, as it is not something that only evlists
need, so move it to tools/lib/api/fd to ease sharing it.
v2: Don't use {} like in:
libapi_dirs:
$(QUIET_MKDIR)mkdir -p $(OUTPUT){fs,fd}/
in Makefiles, as it will not work in some systems, as in ubuntu13.10.
v3: Add fd/*.[ch] to LIBAPIKFS_SOURCES (Fix from Jiri Olsa)
v4: Leave the fcntl(fd, O_NONBLOCK) in the evlist layer, remains to
be checked if it is really needed there, but has no place in the
fdarray class (Fix from Jiri Olsa)
v5: Remove evlist details from fdarray grow/filter tests. Improve it a
bit doing more tests about expected internal state.
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>
Link: http://lkml.kernel.org/n/tip-kleuni3hckbc3s0lu6yb9x40@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/lib/api')
-rw-r--r-- | tools/lib/api/Makefile | 7 | ||||
-rw-r--r-- | tools/lib/api/fd/array.c | 107 | ||||
-rw-r--r-- | tools/lib/api/fd/array.h | 32 |
3 files changed, 145 insertions, 1 deletions
diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index ce00f7ee6455..36c08b1f4afb 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile | |||
@@ -10,9 +10,14 @@ LIB_OBJS= | |||
10 | 10 | ||
11 | LIB_H += fs/debugfs.h | 11 | LIB_H += fs/debugfs.h |
12 | LIB_H += fs/fs.h | 12 | LIB_H += fs/fs.h |
13 | # See comment below about piggybacking... | ||
14 | LIB_H += fd/array.h | ||
13 | 15 | ||
14 | LIB_OBJS += $(OUTPUT)fs/debugfs.o | 16 | LIB_OBJS += $(OUTPUT)fs/debugfs.o |
15 | LIB_OBJS += $(OUTPUT)fs/fs.o | 17 | LIB_OBJS += $(OUTPUT)fs/fs.o |
18 | # XXX piggybacking here, need to introduce libapikfd, or rename this | ||
19 | # to plain libapik.a and make it have it all api goodies | ||
20 | LIB_OBJS += $(OUTPUT)fd/array.o | ||
16 | 21 | ||
17 | LIBFILE = libapikfs.a | 22 | LIBFILE = libapikfs.a |
18 | 23 | ||
@@ -29,7 +34,7 @@ $(LIBFILE): $(LIB_OBJS) | |||
29 | $(LIB_OBJS): $(LIB_H) | 34 | $(LIB_OBJS): $(LIB_H) |
30 | 35 | ||
31 | libapi_dirs: | 36 | libapi_dirs: |
32 | $(QUIET_MKDIR)mkdir -p $(OUTPUT)fs/ | 37 | $(QUIET_MKDIR)mkdir -p $(OUTPUT)fd $(OUTPUT)fs |
33 | 38 | ||
34 | $(OUTPUT)%.o: %.c libapi_dirs | 39 | $(OUTPUT)%.o: %.c libapi_dirs |
35 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< | 40 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< |
diff --git a/tools/lib/api/fd/array.c b/tools/lib/api/fd/array.c new file mode 100644 index 000000000000..4889c7d42961 --- /dev/null +++ b/tools/lib/api/fd/array.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> | ||
3 | * | ||
4 | * Released under the GPL v2. (and only v2, not any later version) | ||
5 | */ | ||
6 | #include "array.h" | ||
7 | #include <errno.h> | ||
8 | #include <fcntl.h> | ||
9 | #include <poll.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <unistd.h> | ||
12 | |||
13 | void fdarray__init(struct fdarray *fda, int nr_autogrow) | ||
14 | { | ||
15 | fda->entries = NULL; | ||
16 | fda->nr = fda->nr_alloc = 0; | ||
17 | fda->nr_autogrow = nr_autogrow; | ||
18 | } | ||
19 | |||
20 | int fdarray__grow(struct fdarray *fda, int nr) | ||
21 | { | ||
22 | int nr_alloc = fda->nr_alloc + nr; | ||
23 | size_t size = sizeof(struct pollfd) * nr_alloc; | ||
24 | struct pollfd *entries = realloc(fda->entries, size); | ||
25 | |||
26 | if (entries == NULL) | ||
27 | return -ENOMEM; | ||
28 | |||
29 | fda->nr_alloc = nr_alloc; | ||
30 | fda->entries = entries; | ||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow) | ||
35 | { | ||
36 | struct fdarray *fda = calloc(1, sizeof(*fda)); | ||
37 | |||
38 | if (fda != NULL) { | ||
39 | if (fdarray__grow(fda, nr_alloc)) { | ||
40 | free(fda); | ||
41 | fda = NULL; | ||
42 | } else { | ||
43 | fda->nr_autogrow = nr_autogrow; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | return fda; | ||
48 | } | ||
49 | |||
50 | void fdarray__exit(struct fdarray *fda) | ||
51 | { | ||
52 | free(fda->entries); | ||
53 | fdarray__init(fda, 0); | ||
54 | } | ||
55 | |||
56 | void fdarray__delete(struct fdarray *fda) | ||
57 | { | ||
58 | fdarray__exit(fda); | ||
59 | free(fda); | ||
60 | } | ||
61 | |||
62 | int fdarray__add(struct fdarray *fda, int fd, short revents) | ||
63 | { | ||
64 | if (fda->nr == fda->nr_alloc && | ||
65 | fdarray__grow(fda, fda->nr_autogrow) < 0) | ||
66 | return -ENOMEM; | ||
67 | |||
68 | fda->entries[fda->nr].fd = fd; | ||
69 | fda->entries[fda->nr].events = revents; | ||
70 | fda->nr++; | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | int fdarray__filter(struct fdarray *fda, short revents) | ||
75 | { | ||
76 | int fd, nr = 0; | ||
77 | |||
78 | if (fda->nr == 0) | ||
79 | return 0; | ||
80 | |||
81 | for (fd = 0; fd < fda->nr; ++fd) { | ||
82 | if (fda->entries[fd].revents & revents) | ||
83 | continue; | ||
84 | |||
85 | if (fd != nr) | ||
86 | fda->entries[nr] = fda->entries[fd]; | ||
87 | |||
88 | ++nr; | ||
89 | } | ||
90 | |||
91 | return fda->nr = nr; | ||
92 | } | ||
93 | |||
94 | int fdarray__poll(struct fdarray *fda, int timeout) | ||
95 | { | ||
96 | return poll(fda->entries, fda->nr, timeout); | ||
97 | } | ||
98 | |||
99 | int fdarray__fprintf(struct fdarray *fda, FILE *fp) | ||
100 | { | ||
101 | int fd, printed = fprintf(fp, "%d [ ", fda->nr); | ||
102 | |||
103 | for (fd = 0; fd < fda->nr; ++fd) | ||
104 | printed += fprintf(fp, "%s%d", fd ? ", " : "", fda->entries[fd].fd); | ||
105 | |||
106 | return printed + fprintf(fp, " ]"); | ||
107 | } | ||
diff --git a/tools/lib/api/fd/array.h b/tools/lib/api/fd/array.h new file mode 100644 index 000000000000..de38361ba69e --- /dev/null +++ b/tools/lib/api/fd/array.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef __API_FD_ARRAY__ | ||
2 | #define __API_FD_ARRAY__ | ||
3 | |||
4 | #include <stdio.h> | ||
5 | |||
6 | struct pollfd; | ||
7 | |||
8 | struct fdarray { | ||
9 | int nr; | ||
10 | int nr_alloc; | ||
11 | int nr_autogrow; | ||
12 | struct pollfd *entries; | ||
13 | }; | ||
14 | |||
15 | void fdarray__init(struct fdarray *fda, int nr_autogrow); | ||
16 | void fdarray__exit(struct fdarray *fda); | ||
17 | |||
18 | struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow); | ||
19 | void fdarray__delete(struct fdarray *fda); | ||
20 | |||
21 | int fdarray__add(struct fdarray *fda, int fd, short revents); | ||
22 | int fdarray__poll(struct fdarray *fda, int timeout); | ||
23 | int fdarray__filter(struct fdarray *fda, short revents); | ||
24 | int fdarray__grow(struct fdarray *fda, int extra); | ||
25 | int fdarray__fprintf(struct fdarray *fda, FILE *fp); | ||
26 | |||
27 | static inline int fdarray__available_entries(struct fdarray *fda) | ||
28 | { | ||
29 | return fda->nr_alloc - fda->nr; | ||
30 | } | ||
31 | |||
32 | #endif /* __API_FD_ARRAY__ */ | ||