aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--trace-local.h2
-rw-r--r--trace-read.c353
2 files changed, 259 insertions, 96 deletions
diff --git a/trace-local.h b/trace-local.h
index 73c38d2..72f6450 100644
--- a/trace-local.h
+++ b/trace-local.h
@@ -33,7 +33,7 @@ void usage(char **argv);
33extern int silence_warnings; 33extern int silence_warnings;
34extern int show_status; 34extern int show_status;
35 35
36struct tracecmd_input *read_trace_header(void); 36struct tracecmd_input *read_trace_header(const char *file);
37int read_trace_files(void); 37int read_trace_files(void);
38 38
39void trace_report(int argc, char **argv); 39void trace_report(int argc, char **argv);
diff --git a/trace-read.c b/trace-read.c
index 326054e..0e9ced8 100644
--- a/trace-read.c
+++ b/trace-read.c
@@ -39,6 +39,7 @@
39 39
40#include "trace-local.h" 40#include "trace-local.h"
41#include "trace-hash-local.h" 41#include "trace-hash-local.h"
42#include "list.h"
42 43
43static struct filter { 44static struct filter {
44 struct filter *next; 45 struct filter *next;
@@ -47,13 +48,30 @@ static struct filter {
47} *filter_strings; 48} *filter_strings;
48static struct filter **filter_next = &filter_strings; 49static struct filter **filter_next = &filter_strings;
49 50
50static struct event_filter *event_filters; 51struct handle_list {
51static struct event_filter *event_filter_out; 52 struct list_head list;
53 struct tracecmd_input *handle;
54 const char *file;
55 int cpus;
56 int done;
57 struct record *record;
58 struct event_filter *event_filters;
59 struct event_filter *event_filter_out;
60};
61static struct list_head handle_list;
62
63struct input_files {
64 struct list_head list;
65 const char *file;
66};
67static struct list_head input_files;
52 68
53static unsigned int page_size; 69static unsigned int page_size;
54static int input_fd; 70static int input_fd;
55const char *default_input_file = "trace.dat"; 71static const char *default_input_file = "trace.dat";
56const char *input_file; 72static const char *input_file;
73static int multi_inputs;
74static int max_file_size;
57 75
58static int filter_cpu = -1; 76static int filter_cpu = -1;
59static int *filter_cpus; 77static int *filter_cpus;
@@ -231,6 +249,55 @@ static void test_save(struct record *record, int cpu)
231} 249}
232#endif 250#endif
233 251
252static void add_input(const char *file)
253{
254 struct input_files *item;
255
256 item = malloc_or_die(sizeof(*item));
257 item->file = file;
258 list_add_tail(&item->list, &input_files);
259}
260
261static void add_handle(struct tracecmd_input *handle, const char *file)
262{
263 struct handle_list *item;
264
265 item = malloc_or_die(sizeof(*item));
266 memset(item, 0, sizeof(*item));
267 item->handle = handle;
268 item->file = file + strlen(file);
269 /* we want just the base name */
270 while (*item->file != '/' && item->file >= file)
271 item->file--;
272 item->file++;
273 if (strlen(item->file) > max_file_size)
274 max_file_size = strlen(item->file);
275
276 list_add_tail(&item->list, &handle_list);
277}
278
279static void free_inputs(void)
280{
281 struct input_files *item;
282
283 while (!list_empty(&input_files)) {
284 item = container_of(input_files.next, struct input_files, list);
285 list_del(&item->list);
286 free(item);
287 }
288}
289
290static void free_handles(void)
291{
292 struct handle_list *item;
293
294 while (!list_empty(&handle_list)) {
295 item = container_of(handle_list.next, struct handle_list, list);
296 list_del(&item->list);
297 free(item);
298 }
299}
300
234static void add_filter(const char *filter, int neg) 301static void add_filter(const char *filter, int neg)
235{ 302{
236 struct filter *ftr; 303 struct filter *ftr;
@@ -245,7 +312,7 @@ static void add_filter(const char *filter, int neg)
245 filter_next = &ftr->next; 312 filter_next = &ftr->next;
246} 313}
247 314
248static void process_filters(struct tracecmd_input *handle) 315static void process_filters(struct handle_list *handles)
249{ 316{
250 struct event_filter *event_filter; 317 struct event_filter *event_filter;
251 struct pevent *pevent; 318 struct pevent *pevent;
@@ -253,17 +320,17 @@ static void process_filters(struct tracecmd_input *handle)
253 char *errstr; 320 char *errstr;
254 int ret; 321 int ret;
255 322
256 pevent = tracecmd_get_pevent(handle); 323 pevent = tracecmd_get_pevent(handles->handle);
257 event_filters = pevent_filter_alloc(pevent); 324 handles->event_filters = pevent_filter_alloc(pevent);
258 event_filter_out = pevent_filter_alloc(pevent); 325 handles->event_filter_out = pevent_filter_alloc(pevent);
259 326
260 while (filter_strings) { 327 while (filter_strings) {
261 filter = filter_strings; 328 filter = filter_strings;
262 filter_strings = filter->next; 329 filter_strings = filter->next;
263 if (filter->neg) 330 if (filter->neg)
264 event_filter = event_filter_out; 331 event_filter = handles->event_filter_out;
265 else 332 else
266 event_filter = event_filters; 333 event_filter = handles->event_filters;
267 334
268 ret = pevent_filter_add_filter_str(event_filter, 335 ret = pevent_filter_add_filter_str(event_filter,
269 filter->filter, 336 filter->filter,
@@ -515,30 +582,21 @@ static void read_rest(void)
515 } while (r > 0); 582 } while (r > 0);
516} 583}
517 584
518static void read_data_info(struct tracecmd_input *handle) 585static struct record *
586get_next_record(struct handle_list *handles, int *next_cpu)
519{ 587{
520 unsigned long long ts; 588 unsigned long long ts;
521 struct record *record; 589 struct record *record;
522 int cpus; 590 int found = 0;
523 int next; 591 int next;
524 int cpu; 592 int cpu;
525 int ret; 593 int ret;
526 594
527 ret = tracecmd_init_data(handle); 595 if (handles->record)
528 if (ret < 0) 596 return handles->record;
529 die("failed to init data");
530
531 cpus = tracecmd_cpus(handle);
532 printf("cpus=%d\n", cpus);
533
534 /* Latency trace is just all ASCII */
535 if (ret > 0) {
536 read_rest();
537 return;
538 }
539 597
540 init_wakeup(handle); 598 if (handles->done)
541 process_filters(handle); 599 return NULL;
542 600
543 do { 601 do {
544 next = -1; 602 next = -1;
@@ -550,7 +608,7 @@ static void read_data_info(struct tracecmd_input *handle)
550 int i; 608 int i;
551 609
552 for (i = 0; (cpu = filter_cpus[i]) >= 0; i++) { 610 for (i = 0; (cpu = filter_cpus[i]) >= 0; i++) {
553 precord = tracecmd_peek_data(handle, cpu); 611 precord = tracecmd_peek_data(handles->handle, cpu);
554 if (precord && 612 if (precord &&
555 (!last_stamp || precord->ts < last_stamp)) { 613 (!last_stamp || precord->ts < last_stamp)) {
556 next_cpu = cpu; 614 next_cpu = cpu;
@@ -558,41 +616,123 @@ static void read_data_info(struct tracecmd_input *handle)
558 } 616 }
559 } 617 }
560 if (last_stamp) 618 if (last_stamp)
561 record = tracecmd_read_data(handle, next_cpu); 619 record = tracecmd_read_data(handles->handle, next_cpu);
562 else 620 else
563 record = NULL; 621 record = NULL;
564 622
565 } else if (filter_cpu >= 0) { 623 } else if (filter_cpu >= 0) {
566 cpu = filter_cpu; 624 cpu = filter_cpu;
567 record = tracecmd_read_data(handle, cpu); 625 record = tracecmd_read_data(handles->handle, cpu);
568 } else 626 } else
569 record = tracecmd_read_next_data(handle, &cpu); 627 record = tracecmd_read_next_data(handles->handle, &cpu);
570 628
571 if (record) { 629 if (record) {
572 ret = pevent_filter_match(event_filters, record); 630 ret = pevent_filter_match(