diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-09-03 18:02:59 -0300 | 
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-09-25 16:46:55 -0300 | 
| commit | 1b85337d0685d1dc5a6f9061434ba4316d69f3b8 (patch) | |
| tree | 2aae4189996ae07c65c8aaa2fc205ceba58cc7fb /tools/lib/api/fd/array.c | |
| parent | f66a889dbc96dd342c87232d74f0956076707746 (diff) | |
| download | talos-op-linux-1b85337d0685d1dc5a6f9061434ba4316d69f3b8.tar.gz talos-op-linux-1b85337d0685d1dc5a6f9061434ba4316d69f3b8.zip | |
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/fd/array.c')
| -rw-r--r-- | tools/lib/api/fd/array.c | 107 | 
1 files changed, 107 insertions, 0 deletions
| 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 @@ +/* + * Copyright (C) 2014, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> + * + * Released under the GPL v2. (and only v2, not any later version) + */ +#include "array.h" +#include <errno.h> +#include <fcntl.h> +#include <poll.h> +#include <stdlib.h> +#include <unistd.h> + +void fdarray__init(struct fdarray *fda, int nr_autogrow) +{ +	fda->entries	 = NULL; +	fda->nr		 = fda->nr_alloc = 0; +	fda->nr_autogrow = nr_autogrow; +} + +int fdarray__grow(struct fdarray *fda, int nr) +{ +	int nr_alloc = fda->nr_alloc + nr; +	size_t size  = sizeof(struct pollfd) * nr_alloc; +	struct pollfd *entries = realloc(fda->entries, size); + +	if (entries == NULL) +		return -ENOMEM; + +	fda->nr_alloc = nr_alloc; +	fda->entries  = entries; +	return 0; +} + +struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow) +{ +	struct fdarray *fda = calloc(1, sizeof(*fda)); + +	if (fda != NULL) { +		if (fdarray__grow(fda, nr_alloc)) { +			free(fda); +			fda = NULL; +		} else { +			fda->nr_autogrow = nr_autogrow; +		} +	} + +	return fda; +} + +void fdarray__exit(struct fdarray *fda) +{ +	free(fda->entries); +	fdarray__init(fda, 0); +} + +void fdarray__delete(struct fdarray *fda) +{ +	fdarray__exit(fda); +	free(fda); +} + +int fdarray__add(struct fdarray *fda, int fd, short revents) +{ +	if (fda->nr == fda->nr_alloc && +	    fdarray__grow(fda, fda->nr_autogrow) < 0) +		return -ENOMEM; + +	fda->entries[fda->nr].fd     = fd; +	fda->entries[fda->nr].events = revents; +	fda->nr++; +	return 0; +} + +int fdarray__filter(struct fdarray *fda, short revents) +{ +	int fd, nr = 0; + +	if (fda->nr == 0) +		return 0; + +	for (fd = 0; fd < fda->nr; ++fd) { +		if (fda->entries[fd].revents & revents) +			continue; + +		if (fd != nr) +			fda->entries[nr] = fda->entries[fd]; + +		++nr; +	} + +	return fda->nr = nr; +} + +int fdarray__poll(struct fdarray *fda, int timeout) +{ +	return poll(fda->entries, fda->nr, timeout); +} + +int fdarray__fprintf(struct fdarray *fda, FILE *fp) +{ +	int fd, printed = fprintf(fp, "%d [ ", fda->nr); + +	for (fd = 0; fd < fda->nr; ++fd) +		printed += fprintf(fp, "%s%d", fd ? ", " : "", fda->entries[fd].fd); + +	return printed + fprintf(fp, " ]"); +} | 

