aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/event.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r--tools/perf/util/event.c163
1 files changed, 132 insertions, 31 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 10366b87d0b5..47eff4767edb 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -678,23 +678,21 @@ out:
678 return err; 678 return err;
679} 679}
680 680
681int perf_event__synthesize_threads(struct perf_tool *tool, 681static int __perf_event__synthesize_threads(struct perf_tool *tool,
682 perf_event__handler_t process, 682 perf_event__handler_t process,
683 struct machine *machine, 683 struct machine *machine,
684 bool mmap_data, 684 bool mmap_data,
685 unsigned int proc_map_timeout) 685 unsigned int proc_map_timeout,
686 struct dirent **dirent,
687 int start,
688 int num)
686{ 689{
687 union perf_event *comm_event, *mmap_event, *fork_event; 690 union perf_event *comm_event, *mmap_event, *fork_event;
688 union perf_event *namespaces_event; 691 union perf_event *namespaces_event;
689 char proc_path[PATH_MAX];
690 struct dirent **dirent;
691 int err = -1; 692 int err = -1;
692 char *end; 693 char *end;
693 pid_t pid; 694 pid_t pid;
694 int n, i; 695 int i;
695
696 if (machine__is_default_guest(machine))
697 return 0;
698 696
699 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); 697 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
700 if (comm_event == NULL) 698 if (comm_event == NULL)
@@ -714,34 +712,25 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
714 if (namespaces_event == NULL) 712 if (namespaces_event == NULL)
715 goto out_free_fork; 713 goto out_free_fork;
716 714
717 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); 715 for (i = start; i < start + num; i++) {
718 n = scandir(proc_path, &dirent, 0, alphasort);
719
720 if (n < 0)
721 goto out_free_namespaces;
722
723 for (i = 0; i < n; i++) {
724 if (!isdigit(dirent[i]->d_name[0])) 716 if (!isdigit(dirent[i]->d_name[0]))
725 continue; 717 continue;
726 718
727 pid = (pid_t)strtol(dirent[i]->d_name, &end, 10); 719 pid = (pid_t)strtol(dirent[i]->d_name, &end, 10);
728 /* only interested in proper numerical dirents */ 720 /* only interested in proper numerical dirents */
729 if (!*end) { 721 if (*end)
730 /* 722 continue;
731 * We may race with exiting thread, so don't stop just because 723 /*
732 * one thread couldn't be synthesized. 724 * We may race with exiting thread, so don't stop just because
733 */ 725 * one thread couldn't be synthesized.
734 __event__synthesize_thread(comm_event, mmap_event, fork_event, 726 */
735 namespaces_event, pid, 1, process, 727 __event__synthesize_thread(comm_event, mmap_event, fork_event,
736 tool, machine, mmap_data, 728 namespaces_event, pid, 1, process,
737 proc_map_timeout); 729 tool, machine, mmap_data,
738 } 730 proc_map_timeout);
739 free(dirent[i]);
740 } 731 }
741 free(dirent);
742 err = 0; 732 err = 0;
743 733
744out_free_namespaces:
745 free(namespaces_event); 734 free(namespaces_event);
746out_free_fork: 735out_free_fork:
747 free(fork_event); 736 free(fork_event);
@@ -753,6 +742,118 @@ out:
753 return err; 742 return err;
754} 743}
755 744
745struct synthesize_threads_arg {
746 struct perf_tool *tool;
747 perf_event__handler_t process;
748 struct machine *machine;
749 bool mmap_data;
750 unsigned int proc_map_timeout;
751 struct dirent **dirent;
752 int num;
753 int start;
754};
755
756static void *synthesize_threads_worker(void *arg)
757{
758 struct synthesize_threads_arg *args = arg;
759
760 __perf_event__synthesize_threads(args->tool, args->process,
761 args->machine, args->mmap_data,
762 args->proc_map_timeout, args->dirent,
763 args->start, args->num);
764 return NULL;
765}
766
767int perf_event__synthesize_threads(struct perf_tool *tool,
768 perf_event__handler_t process,
769 struct machine *machine,
770 bool mmap_data,
771 unsigned int proc_map_timeout,
772 unsigned int nr_threads_synthesize)
773{
774 struct synthesize_threads_arg *args = NULL;
775 pthread_t *synthesize_threads = NULL;
776 char proc_path[PATH_MAX];
777 struct dirent **dirent;
778 int num_per_thread;
779 int m, n, i, j;
780 int thread_nr;
781 int base = 0;
782 int err = -1;
783
784
785 if (machine__is_default_guest(machine))
786 return 0;
787
788 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
789 n = scandir(proc_path, &dirent, 0, alphasort);
790 if (n < 0)
791 return err;
792
793 if (nr_threads_synthesize == UINT_MAX)
794 thread_nr = sysconf(_SC_NPROCESSORS_ONLN);
795 else
796 thread_nr = nr_threads_synthesize;
797
798 if (thread_nr <= 1) {
799 err = __perf_event__synthesize_threads(tool, process,
800 machine, mmap_data,
801 proc_map_timeout,
802 dirent, base, n);
803 goto free_dirent;
804 }
805 if (thread_nr > n)
806 thread_nr = n;
807
808 synthesize_threads = calloc(sizeof(pthread_t), thread_nr);
809 if (synthesize_threads == NULL)
810 goto free_dirent;
811
812 args = calloc(sizeof(*args), thread_nr);
813 if (args == NULL)
814 goto free_threads;
815
816 num_per_thread = n / thread_nr;
817 m = n % thread_nr;
818 for (i = 0; i < thread_nr; i++) {
819 args[i].tool = tool;
820 args[i].process = process;
821 args[i].machine = machine;
822 args[i].mmap_data = mmap_data;
823 args[i].proc_map_timeout = proc_map_timeout;
824 args[i].dirent = dirent;
825 }
826 for (i = 0; i < m; i++) {
827 args[i].num = num_per_thread + 1;
828 args[i].start = i * args[i].num;
829 }
830 if (i != 0)
831 base = args[i-1].start + args[i-1].num;
832 for (j = i; j < thread_nr; j++) {
833 args[j].num = num_per_thread;
834 args[j].start = base + (j - i) * args[i].num;
835 }
836
837 for (i = 0; i < thread_nr; i++) {
838 if (pthread_create(&synthesize_threads[i], NULL,
839 synthesize_threads_worker, &args[i]))
840 goto out_join;
841 }
842 err = 0;
843out_join:
844 for (i = 0; i < thread_nr; i++)
845 pthread_join(synthesize_threads[i], NULL);
846 free(args);
847free_threads:
848 free(synthesize_threads);
849free_dirent:
850 for (i = 0; i < n; i++)
851 free(dirent[i]);
852 free(dirent);
853
854 return err;
855}
856
756struct process_symbol_args { 857struct process_symbol_args {
757 const char *name; 858 const char *name;
758 u64 start; 859 u64 start;