Messages in this thread Patch in this message | | | From | David Carrillo-Cisneros <> | Subject | [PATCH v4 12/16] perf header: add a buffer to struct feat_fd | Date | Mon, 12 Jun 2017 21:29:28 -0700 |
| |
Extend struct feat_fd to use a temporal buffer in pipe-mode, instead of perf.data's file descriptor.
The header features build_id and aux_trace already have logic to print in file-mode that heavily rely on lseek the file. For now, leave such features inactive in pipe-mode and print a warning if their functions are called in pipe-mode.
Signed-off-by: David Carrillo-Cisneros <davidcc@google.com> --- tools/perf/util/header.c | 73 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 8 deletions(-)
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index deb02343fccf..282cb5899ae9 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -61,6 +61,7 @@ struct perf_file_attr { struct feat_fd { struct perf_header *ph; int fd; + void *buf; /* Either buf != NULL or fd >= 0 */ ssize_t offset; size_t size; }; @@ -80,18 +81,43 @@ bool perf_header__has_feat(const struct perf_header *header, int feat) return test_bit(feat, header->adds_features); } -/* Return: 0 if succeded, -ERR if failed. */ -int do_write(struct feat_fd *ff, const void *buf, size_t size) +static int __do_write_fd(struct feat_fd *ff, const void *buf, size_t size) { - ssize_t ret; + ssize_t ret = writen(ff->fd, buf, size); - ret = writen(ff->fd, buf, size); if (ret != (ssize_t)size) return ret < 0 ? (int)ret : -1; + return 0; +} + +static int __do_write_buf(struct feat_fd *ff, const void *buf, size_t size) +{ + void *addr; + +retry: + if (size > (ff->size - ff->offset)) { + addr = realloc(ff->buf, ff->size << 1); + if (!addr) + return -ENOSPC; + ff->buf = addr; + ff->size <<= 1; + goto retry; + } + + memcpy(ff->buf + ff->offset, buf, size); + ff->offset += size; return 0; } +/* Return: 0 if succeded, -ERR if failed. */ +int do_write(struct feat_fd *ff, const void *buf, size_t size) +{ + if (!ff->buf) + return __do_write_fd(ff, buf, size); + return __do_write_buf(ff, buf, size); +} + /* Return: 0 if succeded, -ERR if failed. */ int write_padded(struct feat_fd *ff, const void *bf, size_t count, size_t count_aligned) @@ -125,13 +151,32 @@ static int do_write_string(struct feat_fd *ff, const char *str) return write_padded(ff, str, olen, len); } -static int __do_read(struct feat_fd *ff, void *addr, ssize_t size) +static int __do_read_fd(struct feat_fd *ff, void *addr, ssize_t size) { - ssize_t ret = readn(ff->fd, addr, size); + ssize_t ret = readn(ff->fd, addr, size); + + if (ret != size) + return ret < 0 ? (int)ret : -1; + return 0; +} + +static int __do_read_buf(struct feat_fd *ff, void *addr, ssize_t size) +{ + if (size > (ssize_t)ff->size - ff->offset) + return -1; + + memcpy(addr, ff->buf + ff->offset, size); + ff->offset += size; - if (ret != size) - return ret < 0 ? (int)ret : -1; return 0; + +} + +static int __do_read(struct feat_fd *ff, void *addr, ssize_t size) +{ + if (!ff->buf) + return __do_read_fd(ff, addr, size); + return __do_read_buf(ff, addr, size); } static int do_read_u32(struct feat_fd *ff, u32 *addr) @@ -188,6 +233,9 @@ static char *do_read_string(struct feat_fd *ff) static int write_tracing_data(struct feat_fd *ff, struct perf_evlist *evlist) { + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; + return read_tracing_data(ff->fd, &evlist->entries); } @@ -202,6 +250,9 @@ static int write_build_id(struct feat_fd *ff, if (!perf_session__read_build_ids(session, true)) return -1; + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; + err = perf_session__write_buildid_table(session, ff); if (err < 0) { pr_debug("failed to write buildid table\n"); @@ -911,6 +962,9 @@ static int write_auxtrace(struct feat_fd *ff, struct perf_session *session; int err; + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; + session = container_of(ff->ph, struct perf_session, header); err = auxtrace_index__write(ff->fd, &session->auxtrace_index); @@ -2196,6 +2250,9 @@ static int do_write_feat(struct feat_fd *ff, int type, if (!feat_ops[type].write) return -1; + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; + (*p)->offset = lseek(ff->fd, 0, SEEK_CUR); err = feat_ops[type].write(ff, evlist); -- 2.13.1.508.gb3defc5cc-goog
| |