diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-10-06 15:26:02 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-10-06 15:34:13 -0400 |
commit | b0a7d1a0cd2e228dc06d099db2e1bb02f1b7d591 (patch) | |
tree | e943d42d36229261829b7c51978ecd1ee649a59a | |
parent | 0439539f72ea222fbfe511b47318b9c1815a7108 (diff) |
perf machine: Carve up event processing specific from perf_tool
The perf_tool vtable expects methods that receive perf_tool and
perf_sample entries, but for tools not interested in doing any special
processing on non PERF_RECORD_SAMPLE events, like 'perf top', and for
those not using perf_session, like 'perf trace', they were using
perf_event__process passing tool and sample paramenters that were just
not used.
Provide 'machine' methods for this purpose and make the perf_event
ones use them.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-ot9cc6mt025o8kbngzckcrx9@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/builtin-top.c | 3 | ||||
-rw-r--r-- | tools/perf/util/event.c | 211 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 220 | ||||
-rw-r--r-- | tools/perf/util/machine.h | 8 |
4 files changed, 242 insertions, 200 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index ff6db8086805..fb9da71eba1f 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "util/color.h" | 26 | #include "util/color.h" |
27 | #include "util/evlist.h" | 27 | #include "util/evlist.h" |
28 | #include "util/evsel.h" | 28 | #include "util/evsel.h" |
29 | #include "util/machine.h" | ||
29 | #include "util/session.h" | 30 | #include "util/session.h" |
30 | #include "util/symbol.h" | 31 | #include "util/symbol.h" |
31 | #include "util/thread.h" | 32 | #include "util/thread.h" |
@@ -871,7 +872,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | |||
871 | &sample, machine); | 872 | &sample, machine); |
872 | } else if (event->header.type < PERF_RECORD_MAX) { | 873 | } else if (event->header.type < PERF_RECORD_MAX) { |
873 | hists__inc_nr_events(&evsel->hists, event->header.type); | 874 | hists__inc_nr_events(&evsel->hists, event->header.type); |
874 | perf_event__process(&top->tool, event, &sample, machine); | 875 | machine__process_event(machine, event); |
875 | } else | 876 | } else |
876 | ++session->hists.stats.nr_unknown_events; | 877 | ++session->hists.stats.nr_unknown_events; |
877 | } | 878 | } |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index eaaee22628ea..0ae444ef1429 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -520,134 +520,15 @@ int perf_event__process_comm(struct perf_tool *tool __maybe_unused, | |||
520 | struct perf_sample *sample __maybe_unused, | 520 | struct perf_sample *sample __maybe_unused, |
521 | struct machine *machine) | 521 | struct machine *machine) |
522 | { | 522 | { |
523 | struct thread *thread = machine__findnew_thread(machine, event->comm.tid); | 523 | return machine__process_comm_event(machine, event); |
524 | |||
525 | if (dump_trace) | ||
526 | perf_event__fprintf_comm(event, stdout); | ||
527 | |||
528 | if (thread == NULL || thread__set_comm(thread, event->comm.comm)) { | ||
529 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); | ||
530 | return -1; | ||
531 | } | ||
532 | |||
533 | return 0; | ||
534 | } | 524 | } |
535 | 525 | ||
536 | int perf_event__process_lost(struct perf_tool *tool __maybe_unused, | 526 | int perf_event__process_lost(struct perf_tool *tool __maybe_unused, |
537 | union perf_event *event, | 527 | union perf_event *event, |
538 | struct perf_sample *sample __maybe_unused, | 528 | struct perf_sample *sample __maybe_unused, |
539 | struct machine *machine __maybe_unused) | 529 | struct machine *machine) |
540 | { | ||
541 | dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", | ||
542 | event->lost.id, event->lost.lost); | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static void perf_event__set_kernel_mmap_len(union perf_event *event, | ||
547 | struct map **maps) | ||
548 | { | ||
549 | maps[MAP__FUNCTION]->start = event->mmap.start; | ||
550 | maps[MAP__FUNCTION]->end = event->mmap.start + event->mmap.len; | ||
551 | /* | ||
552 | * Be a bit paranoid here, some perf.data file came with | ||
553 | * a zero sized synthesized MMAP event for the kernel. | ||
554 | */ | ||
555 | if (maps[MAP__FUNCTION]->end == 0) | ||
556 | maps[MAP__FUNCTION]->end = ~0ULL; | ||
557 | } | ||
558 | |||
559 | static int perf_event__process_kernel_mmap(struct perf_tool *tool | ||
560 | __maybe_unused, | ||
561 | union perf_event *event, | ||
562 | struct machine *machine) | ||
563 | { | 530 | { |
564 | struct map *map; | 531 | return machine__process_lost_event(machine, event); |
565 | char kmmap_prefix[PATH_MAX]; | ||
566 | enum dso_kernel_type kernel_type; | ||
567 | bool is_kernel_mmap; | ||
568 | |||
569 | machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix)); | ||
570 | if (machine__is_host(machine)) | ||
571 | kernel_type = DSO_TYPE_KERNEL; | ||
572 | else | ||
573 | kernel_type = DSO_TYPE_GUEST_KERNEL; | ||
574 | |||
575 | is_kernel_mmap = memcmp(event->mmap.filename, | ||
576 | kmmap_prefix, | ||
577 | strlen(kmmap_prefix) - 1) == 0; | ||
578 | if (event->mmap.filename[0] == '/' || | ||
579 | (!is_kernel_mmap && event->mmap.filename[0] == '[')) { | ||
580 | |||
581 | char short_module_name[1024]; | ||
582 | char *name, *dot; | ||
583 | |||
584 | if (event->mmap.filename[0] == '/') { | ||
585 | name = strrchr(event->mmap.filename, '/'); | ||
586 | if (name == NULL) | ||
587 | goto out_problem; | ||
588 | |||
589 | ++name; /* skip / */ | ||
590 | dot = strrchr(name, '.'); | ||
591 | if (dot == NULL) | ||
592 | goto out_problem; | ||
593 | snprintf(short_module_name, sizeof(short_module_name), | ||
594 | "[%.*s]", (int)(dot - name), name); | ||
595 | strxfrchar(short_module_name, '-', '_'); | ||
596 | } else | ||
597 | strcpy(short_module_name, event->mmap.filename); | ||
598 | |||
599 | map = machine__new_module(machine, event->mmap.start, | ||
600 | event->mmap.filename); | ||
601 | if (map == NULL) | ||
602 | goto out_problem; | ||
603 | |||
604 | name = strdup(short_module_name); | ||
605 | if (name == NULL) | ||
606 | goto out_problem; | ||
607 | |||
608 | map->dso->short_name = name; | ||
609 | map->dso->sname_alloc = 1; | ||
610 | map->end = map->start + event->mmap.len; | ||
611 | } else if (is_kernel_mmap) { | ||
612 | const char *symbol_name = (event->mmap.filename + | ||
613 | strlen(kmmap_prefix)); | ||
614 | /* | ||
615 | * Should be there already, from the build-id table in | ||
616 | * the header. | ||
617 | */ | ||
618 | struct dso *kernel = __dsos__findnew(&machine->kernel_dsos, | ||
619 | kmmap_prefix); | ||
620 | if (kernel == NULL) | ||
621 | goto out_problem; | ||
622 | |||
623 | kernel->kernel = kernel_type; | ||
624 | if (__machine__create_kernel_maps(machine, kernel) < 0) | ||
625 | goto out_problem; | ||
626 | |||
627 | perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); | ||
628 | |||
629 | /* | ||
630 | * Avoid using a zero address (kptr_restrict) for the ref reloc | ||
631 | * symbol. Effectively having zero here means that at record | ||
632 | * time /proc/sys/kernel/kptr_restrict was non zero. | ||
633 | */ | ||
634 | if (event->mmap.pgoff != 0) { | ||
635 | maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, | ||
636 | symbol_name, | ||
637 | event->mmap.pgoff); | ||
638 | } | ||
639 | |||
640 | if (machine__is_default_guest(machine)) { | ||
641 | /* | ||
642 | * preload dso of guest kernel and modules | ||
643 | */ | ||
644 | dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION], | ||
645 | NULL); | ||
646 | } | ||
647 | } | ||
648 | return 0; | ||
649 | out_problem: | ||
650 | return -1; | ||
651 | } | 532 | } |
652 | 533 | ||
653 | size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) | 534 | size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) |
@@ -657,43 +538,12 @@ size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) | |||
657 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); | 538 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); |
658 | } | 539 | } |
659 | 540 | ||
660 | int perf_event__process_mmap(struct perf_tool *tool, | 541 | int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, |
661 | union perf_event *event, | 542 | union perf_event *event, |
662 | struct perf_sample *sample __maybe_unused, | 543 | struct perf_sample *sample __maybe_unused, |
663 | struct machine *machine) | 544 | struct machine *machine) |
664 | { | 545 | { |
665 | struct thread *thread; | 546 | return machine__process_mmap_event(machine, event); |
666 | struct map *map; | ||
667 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | ||
668 | int ret = 0; | ||
669 | |||
670 | if (dump_trace) | ||
671 | perf_event__fprintf_mmap(event, stdout); | ||
672 | |||
673 | if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || | ||
674 | cpumode == PERF_RECORD_MISC_KERNEL) { | ||
675 | ret = perf_event__process_kernel_mmap(tool, event, machine); | ||
676 | if (ret < 0) | ||
677 | goto out_problem; | ||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | thread = machine__findnew_thread(machine, event->mmap.pid); | ||
682 | if (thread == NULL) | ||
683 | goto out_problem; | ||
684 | map = map__new(&machine->user_dsos, event->mmap.start, | ||
685 | event->mmap.len, event->mmap.pgoff, | ||
686 | event->mmap.pid, event->mmap.filename, | ||
687 | MAP__FUNCTION); | ||
688 | if (map == NULL) | ||
689 | goto out_problem; | ||
690 | |||
691 | thread__insert_map(thread, map); | ||
692 | return 0; | ||
693 | |||
694 | out_problem: | ||
695 | dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); | ||
696 | return 0; | ||
697 | } | 547 | } |
698 | 548 | ||
699 | size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) | 549 | size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) |
@@ -708,19 +558,7 @@ int perf_event__process_fork(struct perf_tool *tool __maybe_unused, | |||
708 | struct perf_sample *sample __maybe_unused, | 558 | struct perf_sample *sample __maybe_unused, |
709 | struct machine *machine) | 559 | struct machine *machine) |
710 | { | 560 | { |
711 | struct thread *thread = machine__findnew_thread(machine, event->fork.tid); | 561 | return machine__process_fork_event(machine, event); |
712 | struct thread *parent = machine__findnew_thread(machine, event->fork.ptid); | ||
713 | |||
714 | if (dump_trace) | ||
715 | perf_event__fprintf_task(event, stdout); | ||
716 | |||
717 | if (thread == NULL || parent == NULL || | ||
718 | thread__fork(thread, parent) < 0) { | ||
719 | dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n"); | ||
720 | return -1; | ||
721 | } | ||
722 | |||
723 | return 0; | ||
724 | } | 562 | } |
725 | 563 | ||
726 | int perf_event__process_exit(struct perf_tool *tool __maybe_unused, | 564 | int perf_event__process_exit(struct perf_tool *tool __maybe_unused, |
@@ -728,15 +566,7 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused, | |||
728 | struct perf_sample *sample __maybe_unused, | 566 | struct perf_sample *sample __maybe_unused, |
729 | struct machine *machine) | 567 | struct machine *machine) |
730 | { | 568 | { |
731 | struct thread *thread = machine__find_thread(machine, event->fork.tid); | 569 | return machine__process_exit_event(machine, event); |
732 | |||
733 | if (dump_trace) | ||
734 | perf_event__fprintf_task(event, stdout); | ||
735 | |||
736 | if (thread != NULL) | ||
737 | machine__remove_thread(machine, thread); | ||
738 | |||
739 | return 0; | ||
740 | } | 570 | } |
741 | 571 | ||
742 | size_t perf_event__fprintf(union perf_event *event, FILE *fp) | 572 | size_t perf_event__fprintf(union perf_event *event, FILE *fp) |
@@ -762,29 +592,12 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp) | |||
762 | return ret; | 592 | return ret; |
763 | } | 593 | } |
764 | 594 | ||
765 | int perf_event__process(struct perf_tool *tool, union perf_event *event, | 595 | int perf_event__process(struct perf_tool *tool __maybe_unused, |
766 | struct perf_sample *sample, struct machine *machine) | 596 | union perf_event *event, |
597 | struct perf_sample *sample __maybe_unused, | ||
598 | struct machine *machine) | ||
767 | { | 599 | { |
768 | switch (event->header.type) { | 600 | return machine__process_event(machine, event); |
769 | case PERF_RECORD_COMM: | ||
770 | perf_event__process_comm(tool, event, sample, machine); | ||
771 | break; | ||
772 | case PERF_RECORD_MMAP: | ||
773 | perf_event__process_mmap(tool, event, sample, machine); | ||
774 | break; | ||
775 | case PERF_RECORD_FORK: | ||
776 | perf_event__process_fork(tool, event, sample, machine); | ||
777 | break; | ||
778 | case PERF_RECORD_EXIT: | ||
779 | perf_event__process_exit(tool, event, sample, machine); | ||
780 | break; | ||
781 | case PERF_RECORD_LOST: | ||
782 | perf_event__process_lost(tool, event, sample, machine); | ||
783 | default: | ||
784 | break; | ||
785 | } | ||
786 | |||
787 | return 0; | ||
788 | } | 601 | } |
789 | 602 | ||
790 | void thread__find_addr_map(struct thread *self, | 603 | void thread__find_addr_map(struct thread *self, |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 9d36d7eeda92..502eec0d4773 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -1,3 +1,5 @@ | |||
1 | #include "debug.h" | ||
2 | #include "event.h" | ||
1 | #include "machine.h" | 3 | #include "machine.h" |
2 | #include "map.h" | 4 | #include "map.h" |
3 | #include "thread.h" | 5 | #include "thread.h" |
@@ -55,3 +57,221 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid) | |||
55 | { | 57 | { |
56 | return __machine__findnew_thread(machine, pid, false); | 58 | return __machine__findnew_thread(machine, pid, false); |
57 | } | 59 | } |
60 | |||
61 | int machine__process_comm_event(struct machine *machine, union perf_event *event) | ||
62 | { | ||
63 | struct thread *thread = machine__findnew_thread(machine, event->comm.tid); | ||
64 | |||
65 | if (dump_trace) | ||
66 | perf_event__fprintf_comm(event, stdout); | ||
67 | |||
68 | if (thread == NULL || thread__set_comm(thread, event->comm.comm)) { | ||
69 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); | ||
70 | return -1; | ||
71 | } | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | int machine__process_lost_event(struct machine *machine __maybe_unused, | ||
77 | union perf_event *event) | ||
78 | { | ||
79 | dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", | ||
80 | event->lost.id, event->lost.lost); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static void machine__set_kernel_mmap_len(struct machine *machine, | ||
85 | union perf_event *event) | ||
86 | { | ||
87 | machine->vmlinux_maps[MAP__FUNCTION]->start = event->mmap.start; | ||
88 | machine->vmlinux_maps[MAP__FUNCTION]->end = (event->mmap.start + | ||
89 | event->mmap.len); | ||
90 | /* | ||
91 | * Be a bit paranoid here, some perf.data file came with | ||
92 | * a zero sized synthesized MMAP event for the kernel. | ||
93 | */ | ||
94 | if (machine->vmlinux_maps[MAP__FUNCTION]->end == 0) | ||
95 | machine->vmlinux_maps[MAP__FUNCTION]->end = ~0ULL; | ||
96 | } | ||
97 | |||
98 | static int machine__process_kernel_mmap_event(struct machine *machine, | ||
99 | union perf_event *event) | ||
100 | { | ||
101 | struct map *map; | ||
102 | char kmmap_prefix[PATH_MAX]; | ||
103 | enum dso_kernel_type kernel_type; | ||
104 | bool is_kernel_mmap; | ||
105 | |||
106 | machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix)); | ||
107 | if (machine__is_host(machine)) | ||
108 | kernel_type = DSO_TYPE_KERNEL; | ||
109 | else | ||
110 | kernel_type = DSO_TYPE_GUEST_KERNEL; | ||
111 | |||
112 | is_kernel_mmap = memcmp(event->mmap.filename, | ||
113 | kmmap_prefix, | ||
114 | strlen(kmmap_prefix) - 1) == 0; | ||
115 | if (event->mmap.filename[0] == '/' || | ||
116 | (!is_kernel_mmap && event->mmap.filename[0] == '[')) { | ||
117 | |||
118 | char short_module_name[1024]; | ||
119 | char *name, *dot; | ||
120 | |||
121 | if (event->mmap.filename[0] == '/') { | ||
122 | name = strrchr(event->mmap.filename, '/'); | ||
123 | if (name == NULL) | ||
124 | goto out_problem; | ||
125 | |||
126 | ++name; /* skip / */ | ||
127 | dot = strrchr(name, '.'); | ||
128 | if (dot == NULL) | ||
129 | goto out_problem; | ||
130 | snprintf(short_module_name, sizeof(short_module_name), | ||
131 | "[%.*s]", (int)(dot - name), name); | ||
132 | strxfrchar(short_module_name, '-', '_'); | ||
133 | } else | ||
134 | strcpy(short_module_name, event->mmap.filename); | ||
135 | |||
136 | map = machine__new_module(machine, event->mmap.start, | ||
137 | event->mmap.filename); | ||
138 | if (map == NULL) | ||
139 | goto out_problem; | ||
140 | |||
141 | name = strdup(short_module_name); | ||
142 | if (name == NULL) | ||
143 | goto out_problem; | ||
144 | |||
145 | map->dso->short_name = name; | ||
146 | map->dso->sname_alloc = 1; | ||
147 | map->end = map->start + event->mmap.len; | ||
148 | } else if (is_kernel_mmap) { | ||
149 | const char *symbol_name = (event->mmap.filename + | ||
150 | strlen(kmmap_prefix)); | ||
151 | /* | ||
152 | * Should be there already, from the build-id table in | ||
153 | * the header. | ||
154 | */ | ||
155 | struct dso *kernel = __dsos__findnew(&machine->kernel_dsos, | ||
156 | kmmap_prefix); | ||
157 | if (kernel == NULL) | ||
158 | goto out_problem; | ||
159 | |||
160 | kernel->kernel = kernel_type; | ||
161 | if (__machine__create_kernel_maps(machine, kernel) < 0) | ||
162 | goto out_problem; | ||
163 | |||
164 | machine__set_kernel_mmap_len(machine, event); | ||
165 | |||
166 | /* | ||
167 | * Avoid using a zero address (kptr_restrict) for the ref reloc | ||
168 | * symbol. Effectively having zero here means that at record | ||
169 | * time /proc/sys/kernel/kptr_restrict was non zero. | ||
170 | */ | ||
171 | if (event->mmap.pgoff != 0) { | ||
172 | maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, | ||
173 | symbol_name, | ||
174 | event->mmap.pgoff); | ||
175 | } | ||
176 | |||
177 | if (machine__is_default_guest(machine)) { | ||
178 | /* | ||
179 | * preload dso of guest kernel and modules | ||
180 | */ | ||
181 | dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION], | ||
182 | NULL); | ||
183 | } | ||
184 | } | ||
185 | return 0; | ||
186 | out_problem: | ||
187 | return -1; | ||
188 | } | ||
189 | |||
190 | int machine__process_mmap_event(struct machine *machine, union perf_event *event) | ||
191 | { | ||
192 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | ||
193 | struct thread *thread; | ||
194 | struct map *map; | ||
195 | int ret = 0; | ||
196 | |||
197 | if (dump_trace) | ||
198 | perf_event__fprintf_mmap(event, stdout); | ||
199 | |||
200 | if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || | ||
201 | cpumode == PERF_RECORD_MISC_KERNEL) { | ||
202 | ret = machine__process_kernel_mmap_event(machine, event); | ||
203 | if (ret < 0) | ||
204 | goto out_problem; | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | thread = machine__findnew_thread(machine, event->mmap.pid); | ||
209 | if (thread == NULL) | ||
210 | goto out_problem; | ||
211 | map = map__new(&machine->user_dsos, event->mmap.start, | ||
212 | event->mmap.len, event->mmap.pgoff, | ||
213 | event->mmap.pid, event->mmap.filename, | ||
214 | MAP__FUNCTION); | ||
215 | if (map == NULL) | ||
216 | goto out_problem; | ||
217 | |||
218 | thread__insert_map(thread, map); | ||
219 | return 0; | ||
220 | |||
221 | out_problem: | ||
222 | dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | int machine__process_fork_event(struct machine *machine, union perf_event *event) | ||
227 | { | ||
228 | struct thread *thread = machine__findnew_thread(machine, event->fork.tid); | ||
229 | struct thread *parent = machine__findnew_thread(machine, event->fork.ptid); | ||
230 | |||
231 | if (dump_trace) | ||
232 | perf_event__fprintf_task(event, stdout); | ||
233 | |||
234 | if (thread == NULL || parent == NULL || | ||
235 | thread__fork(thread, parent) < 0) { | ||
236 | dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n"); | ||
237 | return -1; | ||
238 | } | ||
239 | |||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | int machine__process_exit_event(struct machine *machine, union perf_event *event) | ||
244 | { | ||
245 | struct thread *thread = machine__find_thread(machine, event->fork.tid); | ||
246 | |||
247 | if (dump_trace) | ||
248 | perf_event__fprintf_task(event, stdout); | ||
249 | |||
250 | if (thread != NULL) | ||
251 | machine__remove_thread(machine, thread); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | int machine__process_event(struct machine *machine, union perf_event *event) | ||
257 | { | ||
258 | int ret; | ||
259 | |||
260 | switch (event->header.type) { | ||
261 | case PERF_RECORD_COMM: | ||
262 | ret = machine__process_comm_event(machine, event); break; | ||
263 | case PERF_RECORD_MMAP: | ||
264 | ret = machine__process_mmap_event(machine, event); break; | ||
265 | case PERF_RECORD_FORK: | ||
266 | ret = machine__process_fork_event(machine, event); break; | ||
267 | case PERF_RECORD_EXIT: | ||
268 | ret = machine__process_exit_event(machine, event); break; | ||
269 | case PERF_RECORD_LOST: | ||
270 | ret = machine__process_lost_event(machine, event); break; | ||
271 | default: | ||
272 | ret = -1; | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | return ret; | ||
277 | } | ||
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 54df0cdd3000..df152f1768be 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h | |||
@@ -5,7 +5,15 @@ | |||
5 | 5 | ||
6 | struct thread; | 6 | struct thread; |
7 | struct machine; | 7 | struct machine; |
8 | union perf_event; | ||
8 | 9 | ||
9 | struct thread *machine__find_thread(struct machine *machine, pid_t pid); | 10 | struct thread *machine__find_thread(struct machine *machine, pid_t pid); |
10 | 11 | ||
12 | int machine__process_comm_event(struct machine *machine, union perf_event *event); | ||
13 | int machine__process_exit_event(struct machine *machine, union perf_event *event); | ||
14 | int machine__process_fork_event(struct machine *machine, union perf_event *event); | ||
15 | int machine__process_lost_event(struct machine *machine, union perf_event *event); | ||
16 | int machine__process_mmap_event(struct machine *machine, union perf_event *event); | ||
17 | int machine__process_event(struct machine *machine, union perf_event *event); | ||
18 | |||
11 | #endif /* __PERF_MACHINE_H */ | 19 | #endif /* __PERF_MACHINE_H */ |