aboutsummaryrefslogtreecommitdiffstats
path: root/trace-input.c
diff options
context:
space:
mode:
Diffstat (limited to 'trace-input.c')
-rw-r--r--trace-input.c144
1 files changed, 79 insertions, 65 deletions
diff --git a/trace-input.c b/trace-input.c
index 7e9d4c6..99d24e4 100644
--- a/trace-input.c
+++ b/trace-input.c
@@ -18,15 +18,6 @@
18 18
19#include "trace-cmd.h" 19#include "trace-cmd.h"
20 20
21struct tracecmd_handle {
22 int fd;
23 int long_size;
24 int page_size;
25 int print_events;
26 int read_page;
27 int cpus;
28};
29
30struct cpu_data { 21struct cpu_data {
31 unsigned long long offset; 22 unsigned long long offset;
32 unsigned long long size; 23 unsigned long long size;
@@ -38,7 +29,16 @@ struct cpu_data {
38 int page_size; 29 int page_size;
39}; 30};
40 31
41static struct cpu_data *cpu_data; 32struct tracecmd_handle {
33 int fd;
34 int long_size;
35 int page_size;
36 int print_events;
37 int read_page;
38 int cpus;
39 struct cpu_data *cpu_data;
40};
41
42 42
43static int do_read(struct tracecmd_handle *handle, void *data, int size) 43static int do_read(struct tracecmd_handle *handle, void *data, int size)
44{ 44{
@@ -437,17 +437,18 @@ static unsigned int ts4host(unsigned int type_len_ts)
437 return type_len_ts >> 5; 437 return type_len_ts >> 5;
438} 438}
439 439
440static int calc_index(void *ptr, int cpu) 440static int calc_index(struct tracecmd_handle *handle,
441 void *ptr, int cpu)
441{ 442{
442 return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page; 443 return (unsigned long)ptr - (unsigned long)handle->cpu_data[cpu].page;
443} 444}
444 445
445static void 446static void
446update_cpu_data_index(struct tracecmd_handle *handle, int cpu) 447update_cpu_data_index(struct tracecmd_handle *handle, int cpu)
447{ 448{
448 cpu_data[cpu].offset += handle->page_size; 449 handle->cpu_data[cpu].offset += handle->page_size;
449 cpu_data[cpu].size -= handle->page_size; 450 handle->cpu_data[cpu].size -= handle->page_size;
450 cpu_data[cpu].index = 0; 451 handle->cpu_data[cpu].index = 0;
451} 452}
452 453
453static void get_next_page(struct tracecmd_handle *handle, int cpu) 454static void get_next_page(struct tracecmd_handle *handle, int cpu)
@@ -455,13 +456,13 @@ static void get_next_page(struct tracecmd_handle *handle, int cpu)
455 off64_t save_seek; 456 off64_t save_seek;
456 off64_t ret; 457 off64_t ret;
457 458
458 if (!cpu_data[cpu].page) 459 if (!handle->cpu_data[cpu].page)
459 return; 460 return;
460 461
461 if (handle->read_page) { 462 if (handle->read_page) {
462 if (cpu_data[cpu].size <= handle->page_size) { 463 if (handle->cpu_data[cpu].size <= handle->page_size) {
463 free(cpu_data[cpu].page); 464 free(handle->cpu_data[cpu].page);
464 cpu_data[cpu].page = NULL; 465 handle->cpu_data[cpu].page = NULL;
465 return; 466 return;
466 } 467 }
467 468
@@ -470,10 +471,10 @@ static void get_next_page(struct tracecmd_handle *handle, int cpu)
470 /* other parts of the code may expect the pointer to not move */ 471 /* other parts of the code may expect the pointer to not move */
471 save_seek = lseek64(input_fd, 0, SEEK_CUR); 472 save_seek = lseek64(input_fd, 0, SEEK_CUR);
472 473
473 ret = lseek64(handle->fd, cpu_data[cpu].offset, SEEK_SET); 474 ret = lseek64(handle->fd, handle->cpu_data[cpu].offset, SEEK_SET);
474 if (ret < 0) 475 if (ret < 0)
475 die("failed to lseek"); 476 die("failed to lseek");
476 ret = read(handle->fd, cpu_data[cpu].page, handle->page_size); 477 ret = read(handle->fd, handle->cpu_data[cpu].page, handle->page_size);
477 if (ret < 0) 478 if (ret < 0)
478 die("failed to read page"); 479 die("failed to read page");
479 480
@@ -483,19 +484,19 @@ static void get_next_page(struct tracecmd_handle *handle, int cpu)
483 return; 484 return;
484 } 485 }
485 486
486 munmap(cpu_data[cpu].page, handle->page_size); 487 munmap(handle->cpu_data[cpu].page, handle->page_size);
487 cpu_data[cpu].page = NULL; 488 handle->cpu_data[cpu].page = NULL;
488 489
489 if (cpu_data[cpu].size <= handle->page_size) 490 if (handle->cpu_data[cpu].size <= handle->page_size)
490 return; 491 return;
491 492
492 update_cpu_data_index(handle, cpu); 493 update_cpu_data_index(handle, cpu);
493 494
494 cpu_data[cpu].page = mmap(NULL, handle->page_size, PROT_READ, MAP_PRIVATE, 495 handle->cpu_data[cpu].page = mmap(NULL, handle->page_size, PROT_READ, MAP_PRIVATE,
495 input_fd, cpu_data[cpu].offset); 496 input_fd, handle->cpu_data[cpu].offset);
496 if (cpu_data[cpu].page == MAP_FAILED) 497 if (handle->cpu_data[cpu].page == MAP_FAILED)
497 die("failed to mmap cpu %d at offset 0x%llx", 498 die("failed to mmap cpu %d at offset 0x%llx",
498 cpu, cpu_data[cpu].offset); 499 cpu, handle->cpu_data[cpu].offset);
499} 500}
500 501
501enum old_ring_buffer_type { 502enum old_ring_buffer_type {
@@ -533,7 +534,7 @@ read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu)
533 extend = data2host4(ptr); 534 extend = data2host4(ptr);
534 extend <<= TS_SHIFT; 535 extend <<= TS_SHIFT;
535 extend += delta; 536 extend += delta;
536 cpu_data[cpu].timestamp += extend; 537 handle->cpu_data[cpu].timestamp += extend;
537 *ptr += 4; 538 *ptr += 4;
538 return NULL; 539 return NULL;
539 540
@@ -551,19 +552,19 @@ read_old_format(struct tracecmd_handle *handle, void **ptr, int cpu)
551 break; 552 break;
552 } 553 }
553 554
554 cpu_data[cpu].timestamp += delta; 555 handle->cpu_data[cpu].timestamp += delta;
555 556
556 data = malloc_or_die(sizeof(*data)); 557 data = malloc_or_die(sizeof(*data));
557 memset(data, 0, sizeof(*data)); 558 memset(data, 0, sizeof(*data));
558 559
559 data->ts = cpu_data[cpu].timestamp; 560 data->ts = handle->cpu_data[cpu].timestamp;
560 data->size = length; 561 data->size = length;
561 data->data = *ptr; 562 data->data = *ptr;
562 563
563 *ptr += ((length+3)/4) * 4; 564 *ptr += ((length+3)/4) * 4;
564 565
565 cpu_data[cpu].index = calc_index(*ptr, cpu); 566 handle->cpu_data[cpu].index = calc_index(handle, *ptr, cpu);
566 cpu_data[cpu].next = data; 567 handle->cpu_data[cpu].next = data;
567 568
568 return data; 569 return data;
569} 570}
@@ -572,8 +573,8 @@ struct record *
572tracecmd_peek_data(struct tracecmd_handle *handle, int cpu) 573tracecmd_peek_data(struct tracecmd_handle *handle, int cpu)
573{ 574{
574 struct record *data; 575 struct record *data;
575 void *page = cpu_data[cpu].page; 576 void *page = handle->cpu_data[cpu].page;
576 int index = cpu_data[cpu].index; 577 int index = handle->cpu_data[cpu].index;
577 void *ptr = page + index; 578 void *ptr = page + index;
578 unsigned long long extend; 579 unsigned long long extend;
579 unsigned int type_len_ts; 580 unsigned int type_len_ts;
@@ -581,8 +582,8 @@ tracecmd_peek_data(struct tracecmd_handle *handle, int cpu)
581 unsigned int delta; 582 unsigned int delta;
582 unsigned int length; 583 unsigned int length;
583 584
584 if (cpu_data[cpu].next) 585 if (handle->cpu_data[cpu].next)
585 return cpu_data[cpu].next; 586 return handle->cpu_data[cpu].next;
586 587
587 if (!page) 588 if (!page)
588 return NULL; 589 return NULL;
@@ -591,27 +592,27 @@ tracecmd_peek_data(struct tracecmd_handle *handle, int cpu)
591 /* FIXME: handle header page */ 592 /* FIXME: handle header page */
592 if (header_page_ts_size != 8) 593 if (header_page_ts_size != 8)
593 die("expected a long long type for timestamp"); 594 die("expected a long long type for timestamp");
594 cpu_data[cpu].timestamp = data2host8(ptr); 595 handle->cpu_data[cpu].timestamp = data2host8(ptr);
595 ptr += 8; 596 ptr += 8;
596 switch (header_page_size_size) { 597 switch (header_page_size_size) {
597 case 4: 598 case 4:
598 cpu_data[cpu].page_size = data2host4(ptr); 599 handle->cpu_data[cpu].page_size = data2host4(ptr);
599 ptr += 4; 600 ptr += 4;
600 break; 601 break;
601 case 8: 602 case 8:
602 cpu_data[cpu].page_size = data2host8(ptr); 603 handle->cpu_data[cpu].page_size = data2host8(ptr);
603 ptr += 8; 604 ptr += 8;
604 break; 605 break;
605 default: 606 default:
606 die("bad long size"); 607 die("bad long size");
607 } 608 }
608 ptr = cpu_data[cpu].page + header_page_data_offset; 609 ptr = handle->cpu_data[cpu].page + header_page_data_offset;
609 } 610 }
610 611
611read_again: 612read_again:
612 index = calc_index(ptr, cpu); 613 index = calc_index(handle, ptr, cpu);
613 614
614 if (index >= cpu_data[cpu].page_size) { 615 if (index >= handle->cpu_data[cpu].page_size) {
615 get_next_page(handle, cpu); 616 get_next_page(handle, cpu);
616 return trace_peek_data(cpu); 617 return trace_peek_data(cpu);
617 } 618 }
@@ -648,7 +649,7 @@ read_again:
648 ptr += 4; 649 ptr += 4;
649 extend <<= TS_SHIFT; 650 extend <<= TS_SHIFT;
650 extend += delta; 651 extend += delta;
651 cpu_data[cpu].timestamp += extend; 652 handle->cpu_data[cpu].timestamp += extend;
652 goto read_again; 653 goto read_again;
653 654
654 case RINGBUF_TYPE_TIME_STAMP: 655 case RINGBUF_TYPE_TIME_STAMP:
@@ -664,28 +665,29 @@ read_again:
664 break; 665 break;
665 } 666 }
666 667
667 cpu_data[cpu].timestamp += delta; 668 handle->cpu_data[cpu].timestamp += delta;
668 669
669 data = malloc_or_die(sizeof(*data)); 670 data = malloc_or_die(sizeof(*data));
670 memset(data, 0, sizeof(*data)); 671 memset(data, 0, sizeof(*data));
671 672
672 data->ts = cpu_data[cpu].timestamp; 673 data->ts = handle->cpu_data[cpu].timestamp;
673 data->size = length; 674 data->size = length;
674 data->data = ptr; 675 data->data = ptr;
675 ptr += length; 676 ptr += length;
676 677
677 cpu_data[cpu].index = calc_index(ptr, cpu); 678 handle->cpu_data[cpu].index = calc_index(handle, ptr, cpu);
678 cpu_data[cpu].next = data; 679 handle->cpu_data[cpu].next = data;
679 680
680 return data; 681 return data;
681} 682}
682 683
683struct record *trace_read_data(int cpu) 684struct record *
685tracecmd_read_data(struct tracecmd_handle *handle, int cpu)
684{ 686{
685 struct record *data; 687 struct record *data;
686 688
687 data = trace_peek_data(cpu); 689 data = trace_peek_data(cpu);
688 cpu_data[cpu].next = NULL; 690 handle->cpu_data[cpu].next = NULL;
689 691
690 return data; 692 return data;
691} 693}
@@ -695,15 +697,15 @@ static void init_read(struct tracecmd_handle *handle, int cpu)
695 off64_t ret; 697 off64_t ret;
696 off64_t save_seek; 698 off64_t save_seek;
697 699
698 cpu_data[cpu].page = malloc_or_die(handle->page_size); 700 handle->cpu_data[cpu].page = malloc_or_die(handle->page_size);
699 701
700 /* other parts of the code may expect the pointer to not move */ 702 /* other parts of the code may expect the pointer to not move */
701 save_seek = lseek64(input_fd, 0, SEEK_CUR); 703 save_seek = lseek64(input_fd, 0, SEEK_CUR);
702 704
703 ret = lseek64(input_fd, (off64_t)cpu_data[cpu].offset, SEEK_SET); 705 ret = lseek64(input_fd, (off64_t)handle->cpu_data[cpu].offset, SEEK_SET);
704 if (ret < 0) 706 if (ret < 0)
705 die("failed to lseek"); 707 die("failed to lseek");
706 ret = read(input_fd, cpu_data[cpu].page, handle->page_size); 708 ret = read(input_fd, handle->cpu_data[cpu].page, handle->page_size);
707 if (ret < 0) 709 if (ret < 0)
708 die("failed to read page"); 710 die("failed to read page");
709 711
@@ -713,7 +715,7 @@ static void init_read(struct tracecmd_handle *handle, int cpu)
713 715
714static void init_cpu(struct tracecmd_handle *handle, int cpu) 716static void init_cpu(struct tracecmd_handle *handle, int cpu)
715{ 717{
716 if (!cpu_data[cpu].size) { 718 if (!handle->cpu_data[cpu].size) {
717 printf("CPU %d is empty\n", cpu); 719 printf("CPU %d is empty\n", cpu);
718 return; 720 return;
719 } 721 }
@@ -723,9 +725,9 @@ static void init_cpu(struct tracecmd_handle *handle, int cpu)
723 return; 725 return;
724 } 726 }
725 727
726 cpu_data[cpu].page = mmap(NULL, handle->page_size, PROT_READ, 728 handle->cpu_data[cpu].page = mmap(NULL, handle->page_size, PROT_READ,
727 MAP_PRIVATE, input_fd, cpu_data[cpu].offset); 729 MAP_PRIVATE, input_fd, handle->cpu_data[cpu].offset);
728 if (cpu_data[cpu].page == MAP_FAILED) { 730 if (handle->cpu_data[cpu].page == MAP_FAILED) {
729 /* fall back to just reading pages */ 731 /* fall back to just reading pages */
730 fprintf(stderr, "Can not mmap file, will read instead\n"); 732 fprintf(stderr, "Can not mmap file, will read instead\n");
731 handle->read_page = 1; 733 handle->read_page = 1;
@@ -742,29 +744,41 @@ int tracecmd_init_data(struct tracecmd_handle *handle)
742 int cpu; 744 int cpu;
743 745
744 size = read8(handle); 746 size = read8(handle);
745 cmdlines = malloc_or_die(size); 747 if (size < 0)
746 do_read_check(handle, cmdlines, size); 748 return -1;
749 cmdlines = malloc(size);
750 if (!cmdlines)
751 return -1;
752 if (do_read_check(handle, cmdlines, size)) {
753 free(cmdlines);
754 return -1;
755 }
747 parse_cmdlines(cmdlines, size); 756 parse_cmdlines(cmdlines, size);
748 free(cmdlines); 757 free(cmdlines);
749 758
750 handle->cpus = read4(handle); 759 handle->cpus = read4(handle);
760 if (handle->cpus < 0)
761 return -1;
751 762
752 parse_set_info(handle->cpus, handle->long_size); 763 parse_set_info(handle->cpus, handle->long_size);
753 764
754 /* 765 /*
755 * Check if this is a latency report or not. 766 * Check if this is a latency report or not.
756 */ 767 */
757 do_read_check(handle, buf, 10); 768 if (do_read_check(handle, buf, 10))
769 return -1;
758 if (strncmp(buf, "latency", 7) == 0) 770 if (strncmp(buf, "latency", 7) == 0)
759 return 1; 771 return 1;
760 772
761 cpu_data = malloc_or_die(sizeof(*cpu_data) * handle->cpus); 773 handle->cpu_data = malloc(sizeof(*handle->cpu_data) * handle->cpus);
762 memset(cpu_data, 0, sizeof(*cpu_data) * handle->cpus); 774 if (!handle->cpu_data)
775 return -1;
776 memset(handle->cpu_data, 0, sizeof(*handle->cpu_data) * handle->cpus);
763 777
764 for (cpu = 0; cpu < handle->cpus; cpu++) { 778 for (cpu = 0; cpu < handle->cpus; cpu++) {
765 cpu_data[cpu].cpu = cpu; 779 handle->cpu_data[cpu].cpu = cpu;
766 cpu_data[cpu].offset = read8(handle); 780 handle->cpu_data[cpu].offset = read8(handle);
767 cpu_data[cpu].size = read8(handle); 781 handle->cpu_data[cpu].size = read8(handle);
768 782
769 init_cpu(handle, cpu); 783 init_cpu(handle, cpu);
770 } 784 }