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/perf/util/evlist.c | |
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/perf/util/evlist.c')
-rw-r--r-- | tools/perf/util/evlist.c | 57 |
1 files changed, 9 insertions, 48 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 5ff3c667542f..398dab1a08cc 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -37,6 +37,7 @@ void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, | |||
37 | INIT_HLIST_HEAD(&evlist->heads[i]); | 37 | INIT_HLIST_HEAD(&evlist->heads[i]); |
38 | INIT_LIST_HEAD(&evlist->entries); | 38 | INIT_LIST_HEAD(&evlist->entries); |
39 | perf_evlist__set_maps(evlist, cpus, threads); | 39 | perf_evlist__set_maps(evlist, cpus, threads); |
40 | fdarray__init(&evlist->pollfd, 64); | ||
40 | evlist->workload.pid = -1; | 41 | evlist->workload.pid = -1; |
41 | } | 42 | } |
42 | 43 | ||
@@ -102,7 +103,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist) | |||
102 | void perf_evlist__exit(struct perf_evlist *evlist) | 103 | void perf_evlist__exit(struct perf_evlist *evlist) |
103 | { | 104 | { |
104 | zfree(&evlist->mmap); | 105 | zfree(&evlist->mmap); |
105 | zfree(&evlist->pollfd); | 106 | fdarray__exit(&evlist->pollfd); |
106 | } | 107 | } |
107 | 108 | ||
108 | void perf_evlist__delete(struct perf_evlist *evlist) | 109 | void perf_evlist__delete(struct perf_evlist *evlist) |
@@ -402,20 +403,6 @@ int perf_evlist__enable_event_idx(struct perf_evlist *evlist, | |||
402 | return perf_evlist__enable_event_thread(evlist, evsel, idx); | 403 | return perf_evlist__enable_event_thread(evlist, evsel, idx); |
403 | } | 404 | } |
404 | 405 | ||
405 | static int perf_evlist__grow_pollfd(struct perf_evlist *evlist, int hint) | ||
406 | { | ||
407 | int nr_fds_alloc = evlist->nr_fds_alloc + hint; | ||
408 | size_t size = sizeof(struct pollfd) * nr_fds_alloc; | ||
409 | struct pollfd *pollfd = realloc(evlist->pollfd, size); | ||
410 | |||
411 | if (pollfd == NULL) | ||
412 | return -ENOMEM; | ||
413 | |||
414 | evlist->nr_fds_alloc = nr_fds_alloc; | ||
415 | evlist->pollfd = pollfd; | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) | 406 | int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) |
420 | { | 407 | { |
421 | int nr_cpus = cpu_map__nr(evlist->cpus); | 408 | int nr_cpus = cpu_map__nr(evlist->cpus); |
@@ -430,8 +417,8 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) | |||
430 | nfds += nr_cpus * nr_threads; | 417 | nfds += nr_cpus * nr_threads; |
431 | } | 418 | } |
432 | 419 | ||
433 | if (evlist->nr_fds_alloc - evlist->nr_fds < nfds && | 420 | if (fdarray__available_entries(&evlist->pollfd) < nfds && |
434 | perf_evlist__grow_pollfd(evlist, nfds) < 0) | 421 | fdarray__grow(&evlist->pollfd, nfds) < 0) |
435 | return -ENOMEM; | 422 | return -ENOMEM; |
436 | 423 | ||
437 | return 0; | 424 | return 0; |
@@ -439,45 +426,19 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) | |||
439 | 426 | ||
440 | int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) | 427 | int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) |
441 | { | 428 | { |
442 | /* | ||
443 | * XXX: 64 is arbitrary, just not to call realloc at each fd. | ||
444 | * Find a better autogrowing heuristic | ||
445 | */ | ||
446 | if (evlist->nr_fds == evlist->nr_fds_alloc && | ||
447 | perf_evlist__grow_pollfd(evlist, 64) < 0) | ||
448 | return -ENOMEM; | ||
449 | |||
450 | fcntl(fd, F_SETFL, O_NONBLOCK); | 429 | fcntl(fd, F_SETFL, O_NONBLOCK); |
451 | evlist->pollfd[evlist->nr_fds].fd = fd; | 430 | |
452 | evlist->pollfd[evlist->nr_fds].events = POLLIN | POLLERR | POLLHUP; | 431 | return fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP); |
453 | evlist->nr_fds++; | ||
454 | return 0; | ||
455 | } | 432 | } |
456 | 433 | ||
457 | int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) | 434 | int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) |
458 | { | 435 | { |
459 | int fd, nr_fds = 0; | 436 | return fdarray__filter(&evlist->pollfd, revents_and_mask); |
460 | |||
461 | if (evlist->nr_fds == 0) | ||
462 | return 0; | ||
463 | |||
464 | for (fd = 0; fd < evlist->nr_fds; ++fd) { | ||
465 | if (evlist->pollfd[fd].revents & revents_and_mask) | ||
466 | continue; | ||
467 | |||
468 | if (fd != nr_fds) | ||
469 | evlist->pollfd[nr_fds] = evlist->pollfd[fd]; | ||
470 | |||
471 | ++nr_fds; | ||
472 | } | ||
473 | |||
474 | evlist->nr_fds = nr_fds; | ||
475 | return nr_fds; | ||
476 | } | 437 | } |
477 | 438 | ||
478 | int perf_evlist__poll(struct perf_evlist *evlist, int timeout) | 439 | int perf_evlist__poll(struct perf_evlist *evlist, int timeout) |
479 | { | 440 | { |
480 | return poll(evlist->pollfd, evlist->nr_fds, timeout); | 441 | return fdarray__poll(&evlist->pollfd, timeout); |
481 | } | 442 | } |
482 | 443 | ||
483 | static void perf_evlist__id_hash(struct perf_evlist *evlist, | 444 | static void perf_evlist__id_hash(struct perf_evlist *evlist, |
@@ -935,7 +896,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, | |||
935 | if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) | 896 | if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) |
936 | return -ENOMEM; | 897 | return -ENOMEM; |
937 | 898 | ||
938 | if (evlist->pollfd == NULL && perf_evlist__alloc_pollfd(evlist) < 0) | 899 | if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) |
939 | return -ENOMEM; | 900 | return -ENOMEM; |
940 | 901 | ||
941 | evlist->overwrite = overwrite; | 902 | evlist->overwrite = overwrite; |