Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 269124
b: refs/heads/master
c: 29208e5
h: refs/heads/master
v: v3
  • Loading branch information
Jiri Olsa authored and Arnaldo Carvalho de Melo committed Oct 20, 2011
1 parent acd18d8 commit 1b17f71
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cc02c921a01794f85ad53b396133f11d4ddd17ff
refs/heads/master: 29208e573a9409ee56599cc0157f31b42c7a0235
27 changes: 23 additions & 4 deletions trunk/tools/perf/util/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -2218,23 +2218,42 @@ int perf_event__synthesize_tracing_data(int fd, struct perf_evlist *evlist,
struct perf_session *session __unused)
{
union perf_event ev;
struct tracing_data *tdata;
ssize_t size = 0, aligned_size = 0, padding;
int err __used = 0;

/*
* We are going to store the size of the data followed
* by the data contents. Since the fd descriptor is a pipe,
* we cannot seek back to store the size of the data once
* we know it. Instead we:
*
* - write the tracing data to the temp file
* - get/write the data size to pipe
* - write the tracing data from the temp file
* to the pipe
*/
tdata = tracing_data_get(&evlist->entries, fd, true);
if (!tdata)
return -1;

memset(&ev, 0, sizeof(ev));

ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
size = read_tracing_data_size(fd, &evlist->entries);
if (size <= 0)
return size;
size = tdata->size;
aligned_size = ALIGN(size, sizeof(u64));
padding = aligned_size - size;
ev.tracing_data.header.size = sizeof(ev.tracing_data);
ev.tracing_data.size = aligned_size;

process(&ev, NULL, session);

err = read_tracing_data(fd, &evlist->entries);
/*
* The put function will copy all the tracing data
* stored in temp file to the pipe.
*/
tracing_data_put(tdata);

write_padded(fd, NULL, 0, padding);

return aligned_size;
Expand Down
112 changes: 88 additions & 24 deletions trunk/tools/perf/util/trace-event-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ static void record_file(const char *file, size_t hdr_sz)
die("Can't read '%s'", file);

/* put in zeros for file size, then fill true size later */
write_or_die(&size, hdr_sz);
if (hdr_sz)
write_or_die(&size, hdr_sz);

do {
r = read(fd, buf, BUFSIZ);
Expand All @@ -212,7 +213,7 @@ static void record_file(const char *file, size_t hdr_sz)
if (bigendian())
sizep += sizeof(u64) - hdr_sz;

if (pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0)
if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0)
die("writing to %s", output_file);
}

Expand Down Expand Up @@ -428,6 +429,19 @@ get_tracepoints_path(struct list_head *pattrs)
return nr_tracepoints > 0 ? path.next : NULL;
}

static void
put_tracepoints_path(struct tracepoint_path *tps)
{
while (tps) {
struct tracepoint_path *t = tps;

tps = tps->next;
free(t->name);
free(t->system);
free(t);
}
}

bool have_tracepoints(struct list_head *pattrs)
{
struct perf_evsel *pos;
Expand All @@ -439,19 +453,11 @@ bool have_tracepoints(struct list_head *pattrs)
return false;
}

int read_tracing_data(int fd, struct list_head *pattrs)
static void tracing_data_header(void)
{
char buf[BUFSIZ];
struct tracepoint_path *tps = get_tracepoints_path(pattrs);

/*
* What? No tracepoints? No sense writing anything here, bail out.
*/
if (tps == NULL)
return -1;

output_fd = fd;
char buf[20];

/* just guessing this is someone's birthday.. ;) */
buf[0] = 23;
buf[1] = 8;
buf[2] = 68;
Expand All @@ -476,28 +482,86 @@ int read_tracing_data(int fd, struct list_head *pattrs)
/* save page_size */
page_size = sysconf(_SC_PAGESIZE);
write_or_die(&page_size, 4);
}

struct tracing_data *tracing_data_get(struct list_head *pattrs,
int fd, bool temp)
{
struct tracepoint_path *tps;
struct tracing_data *tdata;

output_fd = fd;

tps = get_tracepoints_path(pattrs);
if (!tps)
return NULL;

tdata = malloc_or_die(sizeof(*tdata));
tdata->temp = temp;
tdata->size = 0;

if (temp) {
int temp_fd;

snprintf(tdata->temp_file, sizeof(tdata->temp_file),
"/tmp/perf-XXXXXX");
if (!mkstemp(tdata->temp_file))
die("Can't make temp file");

temp_fd = open(tdata->temp_file, O_RDWR);
if (temp_fd < 0)
die("Can't read '%s'", tdata->temp_file);

/*
* Set the temp file the default output, so all the
* tracing data are stored into it.
*/
output_fd = temp_fd;
}

tracing_data_header();
read_header_files();
read_ftrace_files(tps);
read_event_files(tps);
read_proc_kallsyms();
read_ftrace_printk();

return 0;
/*
* All tracing data are stored by now, we can restore
* the default output file in case we used temp file.
*/
if (temp) {
tdata->size = lseek(output_fd, 0, SEEK_CUR);
close(output_fd);
output_fd = fd;
}

put_tracepoints_path(tps);
return tdata;
}

ssize_t read_tracing_data_size(int fd, struct list_head *pattrs)
void tracing_data_put(struct tracing_data *tdata)
{
ssize_t size;
int err = 0;
if (tdata->temp) {
record_file(tdata->temp_file, 0);
unlink(tdata->temp_file);
}

calc_data_size = 1;
err = read_tracing_data(fd, pattrs);
size = calc_data_size - 1;
calc_data_size = 0;
free(tdata);
}

if (err < 0)
return err;
int read_tracing_data(int fd, struct list_head *pattrs)
{
struct tracing_data *tdata;

return size;
/*
* We work over the real file, so we can write data
* directly, no temp file is needed.
*/
tdata = tracing_data_get(pattrs, fd, false);
if (!tdata)
return -ENOMEM;

tracing_data_put(tdata);
return 0;
}
13 changes: 12 additions & 1 deletion trunk/tools/perf/util/trace-event.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,18 @@ void *raw_field_ptr(struct event *event, const char *name, void *data);
unsigned long long eval_flag(const char *flag);

int read_tracing_data(int fd, struct list_head *pattrs);
ssize_t read_tracing_data_size(int fd, struct list_head *pattrs);

struct tracing_data {
/* size is only valid if temp is 'true' */
ssize_t size;
bool temp;
char temp_file[50];
};

struct tracing_data *tracing_data_get(struct list_head *pattrs,
int fd, bool temp);
void tracing_data_put(struct tracing_data *tdata);


/* taken from kernel/trace/trace.h */
enum trace_flag_type {
Expand Down

0 comments on commit 1b17f71

Please sign in to comment.