aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-06-18 17:22:55 -0400
committerIngo Molnar <mingo@elte.hu>2009-06-19 07:42:36 -0400
commitf5970550d5ccf90453cbd7d260370ea99d1f6513 (patch)
treef09c265d9c44bf0cb74d5e998626c6dede5e14c9 /tools/perf/builtin-record.c
parent2a0a50fe9def21835d65035cc8109c0b6dd6099d (diff)
perf_counter tools: Add a data file header
Add a data file header so we can transfer data between record and report. LKML-Reference: <new-submission> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c94
1 files changed, 52 insertions, 42 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 06fdfb8b4828..28304677c73e 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -51,6 +51,9 @@ static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
51static int nr_poll; 51static int nr_poll;
52static int nr_cpu; 52static int nr_cpu;
53 53
54static int file_new = 1;
55static struct perf_file_header file_header;
56
54struct mmap_event { 57struct mmap_event {
55 struct perf_event_header header; 58 struct perf_event_header header;
56 __u32 pid; 59 __u32 pid;
@@ -100,6 +103,21 @@ static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
100 pc->data_tail = tail; 103 pc->data_tail = tail;
101} 104}
102 105
106static void write_output(void *buf, size_t size)
107{
108 while (size) {
109 int ret = write(output, buf, size);
110
111 if (ret < 0)
112 die("failed to write");
113
114 size -= ret;
115 buf += ret;
116
117 bytes_written += ret;
118 }
119}
120
103static void mmap_read(struct mmap_data *md) 121static void mmap_read(struct mmap_data *md)
104{ 122{
105 unsigned int head = mmap_read_head(md); 123 unsigned int head = mmap_read_head(md);
@@ -148,34 +166,14 @@ static void mmap_read(struct mmap_data *md)
148 size = md->mask + 1 - (old & md->mask); 166 size = md->mask + 1 - (old & md->mask);
149 old += size; 167 old += size;
150 168
151 while (size) { 169 write_output(buf, size);
152 int ret = write(output, buf, size);
153
154 if (ret < 0)
155 die("failed to write");
156
157 size -= ret;
158 buf += ret;
159
160 bytes_written += ret;
161 }
162 } 170 }
163 171
164 buf = &data[old & md->mask]; 172 buf = &data[old & md->mask];
165 size = head - old; 173 size = head - old;
166 old += size; 174 old += size;
167 175
168 while (size) { 176 write_output(buf, size);
169 int ret = write(output, buf, size);
170
171 if (ret < 0)
172 die("failed to write");
173
174 size -= ret;
175 buf += ret;
176
177 bytes_written += ret;
178 }
179 177
180 md->prev = old; 178 md->prev = old;
181 mmap_write_tail(md, old); 179 mmap_write_tail(md, old);
@@ -204,7 +202,7 @@ static void pid_synthesize_comm_event(pid_t pid, int full)
204 struct comm_event comm_ev; 202 struct comm_event comm_ev;
205 char filename[PATH_MAX]; 203 char filename[PATH_MAX];
206 char bf[BUFSIZ]; 204 char bf[BUFSIZ];
207 int fd, ret; 205 int fd;
208 size_t size; 206 size_t size;
209 char *field, *sep; 207 char *field, *sep;
210 DIR *tasks; 208 DIR *tasks;
@@ -246,11 +244,7 @@ static void pid_synthesize_comm_event(pid_t pid, int full)
246 if (!full) { 244 if (!full) {
247 comm_ev.tid = pid; 245 comm_ev.tid = pid;
248 246
249 ret = write(output, &comm_ev, comm_ev.header.size); 247 write_output(&comm_ev, comm_ev.header.size);
250 if (ret < 0) {
251 perror("failed to write");
252 exit(-1);
253 }
254 return; 248 return;
255 } 249 }
256 250
@@ -265,11 +259,7 @@ static void pid_synthesize_comm_event(pid_t pid, int full)
265 259
266 comm_ev.tid = pid; 260 comm_ev.tid = pid;
267 261
268 ret = write(output, &comm_ev, comm_ev.header.size); 262 write_output(&comm_ev, comm_ev.header.size);
269 if (ret < 0) {
270 perror("failed to write");
271 exit(-1);
272 }
273 } 263 }
274 closedir(tasks); 264 closedir(tasks);
275 return; 265 return;
@@ -332,10 +322,7 @@ static void pid_synthesize_mmap_samples(pid_t pid)
332 mmap_ev.pid = pid; 322 mmap_ev.pid = pid;
333 mmap_ev.tid = pid; 323 mmap_ev.tid = pid;
334 324
335 if (write(output, &mmap_ev, mmap_ev.header.size) < 0) { 325 write_output(&mmap_ev, mmap_ev.header.size);
336 perror("failed to write");
337 exit(-1);
338 }
339 } 326 }
340 } 327 }
341 328
@@ -382,6 +369,15 @@ static void create_counter(int counter, int cpu, pid_t pid)
382 if (call_graph) 369 if (call_graph)
383 attr->sample_type |= PERF_SAMPLE_CALLCHAIN; 370 attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
384 371
372 if (file_new) {
373 file_header.sample_type = attr->sample_type;
374 } else {
375 if (file_header.sample_type != attr->sample_type) {
376 fprintf(stderr, "incompatible append\n");
377 exit(-1);
378 }
379 }
380
385 attr->mmap = track; 381 attr->mmap = track;
386 attr->comm = track; 382 attr->comm = track;
387 attr->inherit = (cpu < 0) && inherit; 383 attr->inherit = (cpu < 0) && inherit;
@@ -461,6 +457,13 @@ static void open_counters(int cpu, pid_t pid)
461 nr_cpu++; 457 nr_cpu++;
462} 458}
463 459
460static void atexit_header(void)
461{
462 file_header.data_size += bytes_written;
463
464 pwrite(output, &file_header, sizeof(file_header), 0);
465}
466
464static int __cmd_record(int argc, const char **argv) 467static int __cmd_record(int argc, const char **argv)
465{ 468{
466 int i, counter; 469 int i, counter;
@@ -474,6 +477,10 @@ static int __cmd_record(int argc, const char **argv)
474 assert(nr_cpus <= MAX_NR_CPUS); 477 assert(nr_cpus <= MAX_NR_CPUS);
475 assert(nr_cpus >= 0); 478 assert(nr_cpus >= 0);
476 479
480 atexit(sig_atexit);
481 signal(SIGCHLD, sig_handler);
482 signal(SIGINT, sig_handler);
483
477 if (!stat(output_name, &st) && !force && !append_file) { 484 if (!stat(output_name, &st) && !force && !append_file) {
478 fprintf(stderr, "Error, output file %s exists, use -A to append or -f to overwrite.\n", 485 fprintf(stderr, "Error, output file %s exists, use -A to append or -f to overwrite.\n",
479 output_name); 486 output_name);
@@ -482,7 +489,7 @@ static int __cmd_record(int argc, const char **argv)
482 489
483 flags = O_CREAT|O_RDWR; 490 flags = O_CREAT|O_RDWR;
484 if (append_file) 491 if (append_file)
485 flags |= O_APPEND; 492 file_new = 0;
486 else 493 else
487 flags |= O_TRUNC; 494 flags |= O_TRUNC;
488 495
@@ -492,15 +499,18 @@ static int __cmd_record(int argc, const char **argv)
492 exit(-1); 499 exit(-1);
493 } 500 }
494 501
502 if (!file_new) {
503 read(output, &file_header, sizeof(file_header));
504 lseek(output, file_header.data_size, SEEK_CUR);
505 }
506
507 atexit(atexit_header);
508
495 if (!system_wide) { 509 if (!system_wide) {
496 open_counters(-1, target_pid != -1 ? target_pid : getpid()); 510 open_counters(-1, target_pid != -1 ? target_pid : getpid());
497 } else for (i = 0; i < nr_cpus; i++) 511 } else for (i = 0; i < nr_cpus; i++)
498 open_counters(i, target_pid); 512 open_counters(i, target_pid);
499 513
500 atexit(sig_atexit);
501 signal(SIGCHLD, sig_handler);
502 signal(SIGINT, sig_handler);
503
504 if (target_pid == -1 && argc) { 514 if (target_pid == -1 && argc) {
505 pid = fork(); 515 pid = fork();
506 if (pid < 0) 516 if (pid < 0)