diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-record.c | 39 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 41 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 35 | ||||
-rw-r--r-- | tools/perf/util/thread.c | 43 | ||||
-rw-r--r-- | tools/perf/util/thread.h | 15 |
5 files changed, 88 insertions, 85 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 220e6e7f0b97..7bc049035484 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -54,8 +54,7 @@ static bool sample_id_all_avail = true; | |||
54 | static bool system_wide = false; | 54 | static bool system_wide = false; |
55 | static pid_t target_pid = -1; | 55 | static pid_t target_pid = -1; |
56 | static pid_t target_tid = -1; | 56 | static pid_t target_tid = -1; |
57 | static pid_t *all_tids = NULL; | 57 | static struct thread_map *threads; |
58 | static int thread_num = 0; | ||
59 | static pid_t child_pid = -1; | 58 | static pid_t child_pid = -1; |
60 | static bool no_inherit = false; | 59 | static bool no_inherit = false; |
61 | static enum write_mode_t write_mode = WRITE_FORCE; | 60 | static enum write_mode_t write_mode = WRITE_FORCE; |
@@ -318,9 +317,9 @@ static void create_counter(struct perf_evsel *evsel, int cpu) | |||
318 | retry_sample_id: | 317 | retry_sample_id: |
319 | attr->sample_id_all = sample_id_all_avail ? 1 : 0; | 318 | attr->sample_id_all = sample_id_all_avail ? 1 : 0; |
320 | 319 | ||
321 | for (thread_index = 0; thread_index < thread_num; thread_index++) { | 320 | for (thread_index = 0; thread_index < threads->nr; thread_index++) { |
322 | try_again: | 321 | try_again: |
323 | FD(evsel, nr_cpu, thread_index) = sys_perf_event_open(attr, all_tids[thread_index], cpu, group_fd, 0); | 322 | FD(evsel, nr_cpu, thread_index) = sys_perf_event_open(attr, threads->map[thread_index], cpu, group_fd, 0); |
324 | 323 | ||
325 | if (FD(evsel, nr_cpu, thread_index) < 0) { | 324 | if (FD(evsel, nr_cpu, thread_index) < 0) { |
326 | int err = errno; | 325 | int err = errno; |
@@ -653,7 +652,7 @@ static int __cmd_record(int argc, const char **argv) | |||
653 | } | 652 | } |
654 | 653 | ||
655 | if (!system_wide && target_tid == -1 && target_pid == -1) | 654 | if (!system_wide && target_tid == -1 && target_pid == -1) |
656 | all_tids[0] = child_pid; | 655 | threads->map[0] = child_pid; |
657 | 656 | ||
658 | close(child_ready_pipe[1]); | 657 | close(child_ready_pipe[1]); |
659 | close(go_pipe[0]); | 658 | close(go_pipe[0]); |
@@ -793,7 +792,7 @@ static int __cmd_record(int argc, const char **argv) | |||
793 | 792 | ||
794 | list_for_each_entry(pos, &evsel_list, node) { | 793 | list_for_each_entry(pos, &evsel_list, node) { |
795 | for (thread = 0; | 794 | for (thread = 0; |
796 | thread < thread_num; | 795 | thread < threads->nr; |
797 | thread++) | 796 | thread++) |
798 | ioctl(FD(pos, i, thread), | 797 | ioctl(FD(pos, i, thread), |
799 | PERF_EVENT_IOC_DISABLE); | 798 | PERF_EVENT_IOC_DISABLE); |
@@ -910,21 +909,13 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
910 | goto out_symbol_exit; | 909 | goto out_symbol_exit; |
911 | } | 910 | } |
912 | 911 | ||
913 | if (target_pid != -1) { | 912 | if (target_pid != -1) |
914 | target_tid = target_pid; | 913 | target_tid = target_pid; |
915 | thread_num = find_all_tid(target_pid, &all_tids); | ||
916 | if (thread_num <= 0) { | ||
917 | fprintf(stderr, "Can't find all threads of pid %d\n", | ||
918 | target_pid); | ||
919 | usage_with_options(record_usage, record_options); | ||
920 | } | ||
921 | } else { | ||
922 | all_tids=malloc(sizeof(pid_t)); | ||
923 | if (!all_tids) | ||
924 | goto out_symbol_exit; | ||
925 | 914 | ||
926 | all_tids[0] = target_tid; | 915 | threads = thread_map__new(target_pid, target_tid); |
927 | thread_num = 1; | 916 | if (threads == NULL) { |
917 | pr_err("Problems finding threads of monitor\n"); | ||
918 | usage_with_options(record_usage, record_options); | ||
928 | } | 919 | } |
929 | 920 | ||
930 | cpus = cpu_map__new(cpu_list); | 921 | cpus = cpu_map__new(cpu_list); |
@@ -934,11 +925,11 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
934 | } | 925 | } |
935 | 926 | ||
936 | list_for_each_entry(pos, &evsel_list, node) { | 927 | list_for_each_entry(pos, &evsel_list, node) { |
937 | if (perf_evsel__alloc_fd(pos, cpus->nr, thread_num) < 0) | 928 | if (perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) |
938 | goto out_free_fd; | 929 | goto out_free_fd; |
939 | } | 930 | } |
940 | event_array = malloc( | 931 | event_array = malloc((sizeof(struct pollfd) * MAX_NR_CPUS * |
941 | sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num); | 932 | MAX_COUNTERS * threads->nr)); |
942 | if (!event_array) | 933 | if (!event_array) |
943 | goto out_free_fd; | 934 | goto out_free_fd; |
944 | 935 | ||
@@ -965,8 +956,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
965 | out_free_event_array: | 956 | out_free_event_array: |
966 | free(event_array); | 957 | free(event_array); |
967 | out_free_fd: | 958 | out_free_fd: |
968 | free(all_tids); | 959 | thread_map__delete(threads); |
969 | all_tids = NULL; | 960 | threads = NULL; |
970 | out_symbol_exit: | 961 | out_symbol_exit: |
971 | symbol__exit(); | 962 | symbol__exit(); |
972 | return err; | 963 | return err; |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 3f4a431fb5a4..6b9146cd1ea9 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -81,8 +81,7 @@ static bool scale = true; | |||
81 | static bool no_aggr = false; | 81 | static bool no_aggr = false; |
82 | static pid_t target_pid = -1; | 82 | static pid_t target_pid = -1; |
83 | static pid_t target_tid = -1; | 83 | static pid_t target_tid = -1; |
84 | static pid_t *all_tids = NULL; | 84 | static struct thread_map *threads; |
85 | static int thread_num = 0; | ||
86 | static pid_t child_pid = -1; | 85 | static pid_t child_pid = -1; |
87 | static bool null_run = false; | 86 | static bool null_run = false; |
88 | static bool big_num = true; | 87 | static bool big_num = true; |
@@ -175,7 +174,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) | |||
175 | attr->enable_on_exec = 1; | 174 | attr->enable_on_exec = 1; |
176 | } | 175 | } |
177 | 176 | ||
178 | return perf_evsel__open_per_thread(evsel, thread_num, all_tids); | 177 | return perf_evsel__open_per_thread(evsel, threads->nr, threads->map); |
179 | } | 178 | } |
180 | 179 | ||
181 | /* | 180 | /* |
@@ -200,7 +199,7 @@ static int read_counter_aggr(struct perf_evsel *counter) | |||
200 | u64 *count = counter->counts->aggr.values; | 199 | u64 *count = counter->counts->aggr.values; |
201 | int i; | 200 | int i; |
202 | 201 | ||
203 | if (__perf_evsel__read(counter, cpus->nr, thread_num, scale) < 0) | 202 | if (__perf_evsel__read(counter, cpus->nr, threads->nr, scale) < 0) |
204 | return -1; | 203 | return -1; |
205 | 204 | ||
206 | for (i = 0; i < 3; i++) | 205 | for (i = 0; i < 3; i++) |
@@ -298,7 +297,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
298 | } | 297 | } |
299 | 298 | ||
300 | if (target_tid == -1 && target_pid == -1 && !system_wide) | 299 | if (target_tid == -1 && target_pid == -1 && !system_wide) |
301 | all_tids[0] = child_pid; | 300 | threads->map[0] = child_pid; |
302 | 301 | ||
303 | /* | 302 | /* |
304 | * Wait for the child to be ready to exec. | 303 | * Wait for the child to be ready to exec. |
@@ -353,7 +352,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
353 | } else { | 352 | } else { |
354 | list_for_each_entry(counter, &evsel_list, node) { | 353 | list_for_each_entry(counter, &evsel_list, node) { |
355 | read_counter_aggr(counter); | 354 | read_counter_aggr(counter); |
356 | perf_evsel__close_fd(counter, cpus->nr, thread_num); | 355 | perf_evsel__close_fd(counter, cpus->nr, threads->nr); |
357 | } | 356 | } |
358 | } | 357 | } |
359 | 358 | ||
@@ -693,6 +692,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
693 | } | 692 | } |
694 | } | 693 | } |
695 | 694 | ||
695 | if (target_pid != -1) | ||
696 | target_tid = target_pid; | ||
697 | |||
698 | threads = thread_map__new(target_pid, target_tid); | ||
699 | if (threads == NULL) { | ||
700 | pr_err("Problems finding threads of monitor\n"); | ||
701 | usage_with_options(stat_usage, options); | ||
702 | } | ||
703 | |||
696 | if (system_wide) | 704 | if (system_wide) |
697 | cpus = cpu_map__new(cpu_list); | 705 | cpus = cpu_map__new(cpu_list); |
698 | else | 706 | else |
@@ -704,27 +712,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
704 | return -1; | 712 | return -1; |
705 | } | 713 | } |
706 | 714 | ||
707 | if (target_pid != -1) { | ||
708 | target_tid = target_pid; | ||
709 | thread_num = find_all_tid(target_pid, &all_tids); | ||
710 | if (thread_num <= 0) { | ||
711 | fprintf(stderr, "Can't find all threads of pid %d\n", | ||
712 | target_pid); | ||
713 | usage_with_options(stat_usage, options); | ||
714 | } | ||
715 | } else { | ||
716 | all_tids=malloc(sizeof(pid_t)); | ||
717 | if (!all_tids) | ||
718 | return -ENOMEM; | ||
719 | |||
720 | all_tids[0] = target_tid; | ||
721 | thread_num = 1; | ||
722 | } | ||
723 | |||
724 | list_for_each_entry(pos, &evsel_list, node) { | 715 | list_for_each_entry(pos, &evsel_list, node) { |
725 | if (perf_evsel__alloc_stat_priv(pos) < 0 || | 716 | if (perf_evsel__alloc_stat_priv(pos) < 0 || |
726 | perf_evsel__alloc_counts(pos, cpus->nr) < 0 || | 717 | perf_evsel__alloc_counts(pos, cpus->nr) < 0 || |
727 | perf_evsel__alloc_fd(pos, cpus->nr, thread_num) < 0) | 718 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) |
728 | goto out_free_fd; | 719 | goto out_free_fd; |
729 | } | 720 | } |
730 | 721 | ||
@@ -752,5 +743,7 @@ out_free_fd: | |||
752 | list_for_each_entry(pos, &evsel_list, node) | 743 | list_for_each_entry(pos, &evsel_list, node) |
753 | perf_evsel__free_stat_priv(pos); | 744 | perf_evsel__free_stat_priv(pos); |
754 | out: | 745 | out: |
746 | thread_map__delete(threads); | ||
747 | threads = NULL; | ||
755 | return status; | 748 | return status; |
756 | } | 749 | } |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0e426665716d..1e67ab9c7ebc 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -68,8 +68,7 @@ static int print_entries; | |||
68 | 68 | ||
69 | static int target_pid = -1; | 69 | static int target_pid = -1; |
70 | static int target_tid = -1; | 70 | static int target_tid = -1; |
71 | static pid_t *all_tids = NULL; | 71 | static struct thread_map *threads; |
72 | static int thread_num = 0; | ||
73 | static bool inherit = false; | 72 | static bool inherit = false; |
74 | static struct cpu_map *cpus; | 73 | static struct cpu_map *cpus; |
75 | static int realtime_prio = 0; | 74 | static int realtime_prio = 0; |
@@ -1200,7 +1199,7 @@ static void perf_session__mmap_read(struct perf_session *self) | |||
1200 | for (i = 0; i < cpus->nr; i++) { | 1199 | for (i = 0; i < cpus->nr; i++) { |
1201 | list_for_each_entry(counter, &evsel_list, node) { | 1200 | list_for_each_entry(counter, &evsel_list, node) { |
1202 | for (thread_index = 0; | 1201 | for (thread_index = 0; |
1203 | thread_index < thread_num; | 1202 | thread_index < threads->nr; |
1204 | thread_index++) { | 1203 | thread_index++) { |
1205 | perf_session__mmap_read_counter(self, | 1204 | perf_session__mmap_read_counter(self, |
1206 | counter, i, thread_index); | 1205 | counter, i, thread_index); |
@@ -1236,10 +1235,10 @@ static void start_counter(int i, struct perf_evsel *evsel) | |||
1236 | attr->inherit = (cpu < 0) && inherit; | 1235 | attr->inherit = (cpu < 0) && inherit; |
1237 | attr->mmap = 1; | 1236 | attr->mmap = 1; |
1238 | 1237 | ||
1239 | for (thread_index = 0; thread_index < thread_num; thread_index++) { | 1238 | for (thread_index = 0; thread_index < threads->nr; thread_index++) { |
1240 | try_again: | 1239 | try_again: |
1241 | FD(evsel, i, thread_index) = sys_perf_event_open(attr, | 1240 | FD(evsel, i, thread_index) = sys_perf_event_open(attr, |
1242 | all_tids[thread_index], cpu, group_fd, 0); | 1241 | threads->map[thread_index], cpu, group_fd, 0); |
1243 | 1242 | ||
1244 | if (FD(evsel, i, thread_index) < 0) { | 1243 | if (FD(evsel, i, thread_index) < 0) { |
1245 | int err = errno; | 1244 | int err = errno; |
@@ -1410,25 +1409,17 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1410 | if (argc) | 1409 | if (argc) |
1411 | usage_with_options(top_usage, options); | 1410 | usage_with_options(top_usage, options); |
1412 | 1411 | ||
1413 | if (target_pid != -1) { | 1412 | if (target_pid != -1) |
1414 | target_tid = target_pid; | 1413 | target_tid = target_pid; |
1415 | thread_num = find_all_tid(target_pid, &all_tids); | ||
1416 | if (thread_num <= 0) { | ||
1417 | fprintf(stderr, "Can't find all threads of pid %d\n", | ||
1418 | target_pid); | ||
1419 | usage_with_options(top_usage, options); | ||
1420 | } | ||
1421 | } else { | ||
1422 | all_tids=malloc(sizeof(pid_t)); | ||
1423 | if (!all_tids) | ||
1424 | return -ENOMEM; | ||
1425 | 1414 | ||
1426 | all_tids[0] = target_tid; | 1415 | threads = thread_map__new(target_pid, target_tid); |
1427 | thread_num = 1; | 1416 | if (threads == NULL) { |
1417 | pr_err("Problems finding threads of monitor\n"); | ||
1418 | usage_with_options(top_usage, options); | ||
1428 | } | 1419 | } |
1429 | 1420 | ||
1430 | event_array = malloc( | 1421 | event_array = malloc((sizeof(struct pollfd) * |
1431 | sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num); | 1422 | MAX_NR_CPUS * MAX_COUNTERS * threads->nr)); |
1432 | if (!event_array) | 1423 | if (!event_array) |
1433 | return -ENOMEM; | 1424 | return -ENOMEM; |
1434 | 1425 | ||
@@ -1468,8 +1459,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1468 | usage_with_options(top_usage, options); | 1459 | usage_with_options(top_usage, options); |
1469 | 1460 | ||
1470 | list_for_each_entry(pos, &evsel_list, node) { | 1461 | list_for_each_entry(pos, &evsel_list, node) { |
1471 | if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, thread_num) < 0 || | 1462 | if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, threads->nr) < 0 || |
1472 | perf_evsel__alloc_fd(pos, cpus->nr, thread_num) < 0) | 1463 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) |
1473 | goto out_free_fd; | 1464 | goto out_free_fd; |
1474 | /* | 1465 | /* |
1475 | * Fill in the ones not specifically initialized via -c: | 1466 | * Fill in the ones not specifically initialized via -c: |
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 8c72d888e449..00f4eade2e3e 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -16,35 +16,50 @@ static int filter(const struct dirent *dir) | |||
16 | return 1; | 16 | return 1; |
17 | } | 17 | } |
18 | 18 | ||
19 | int find_all_tid(int pid, pid_t ** all_tid) | 19 | struct thread_map *thread_map__new_by_pid(pid_t pid) |
20 | { | 20 | { |
21 | struct thread_map *threads; | ||
21 | char name[256]; | 22 | char name[256]; |
22 | int items; | 23 | int items; |
23 | struct dirent **namelist = NULL; | 24 | struct dirent **namelist = NULL; |
24 | int ret = 0; | ||
25 | int i; | 25 | int i; |
26 | 26 | ||
27 | sprintf(name, "/proc/%d/task", pid); | 27 | sprintf(name, "/proc/%d/task", pid); |
28 | items = scandir(name, &namelist, filter, NULL); | 28 | items = scandir(name, &namelist, filter, NULL); |
29 | if (items <= 0) | 29 | if (items <= 0) |
30 | return -ENOENT; | 30 | return NULL; |
31 | *all_tid = malloc(sizeof(pid_t) * items); | ||
32 | if (!*all_tid) { | ||
33 | ret = -ENOMEM; | ||
34 | goto failure; | ||
35 | } | ||
36 | |||
37 | for (i = 0; i < items; i++) | ||
38 | (*all_tid)[i] = atoi(namelist[i]->d_name); | ||
39 | 31 | ||
40 | ret = items; | 32 | threads = malloc(sizeof(*threads) + sizeof(pid_t) * items); |
33 | if (threads != NULL) { | ||
34 | for (i = 0; i < items; i++) | ||
35 | threads->map[i] = atoi(namelist[i]->d_name); | ||
36 | threads->nr = items; | ||
37 | } | ||
41 | 38 | ||
42 | failure: | ||
43 | for (i=0; i<items; i++) | 39 | for (i=0; i<items; i++) |
44 | free(namelist[i]); | 40 | free(namelist[i]); |
45 | free(namelist); | 41 | free(namelist); |
46 | 42 | ||
47 | return ret; | 43 | return threads; |
44 | } | ||
45 | |||
46 | struct thread_map *thread_map__new_by_tid(pid_t tid) | ||
47 | { | ||
48 | struct thread_map *threads = malloc(sizeof(*threads) + sizeof(pid_t)); | ||
49 | |||
50 | if (threads != NULL) { | ||
51 | threads->map[0] = tid; | ||
52 | threads->nr = 1; | ||
53 | } | ||
54 | |||
55 | return threads; | ||
56 | } | ||
57 | |||
58 | struct thread_map *thread_map__new(pid_t pid, pid_t tid) | ||
59 | { | ||
60 | if (pid != -1) | ||
61 | return thread_map__new_by_pid(pid); | ||
62 | return thread_map__new_by_tid(tid); | ||
48 | } | 63 | } |
49 | 64 | ||
50 | static struct thread *thread__new(pid_t pid) | 65 | static struct thread *thread__new(pid_t pid) |
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 688500ff826f..d7574101054a 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h | |||
@@ -18,11 +18,24 @@ struct thread { | |||
18 | int comm_len; | 18 | int comm_len; |
19 | }; | 19 | }; |
20 | 20 | ||
21 | struct thread_map { | ||
22 | int nr; | ||
23 | int map[]; | ||
24 | }; | ||
25 | |||
21 | struct perf_session; | 26 | struct perf_session; |
22 | 27 | ||
23 | void thread__delete(struct thread *self); | 28 | void thread__delete(struct thread *self); |
24 | 29 | ||
25 | int find_all_tid(int pid, pid_t ** all_tid); | 30 | struct thread_map *thread_map__new_by_pid(pid_t pid); |
31 | struct thread_map *thread_map__new_by_tid(pid_t tid); | ||
32 | struct thread_map *thread_map__new(pid_t pid, pid_t tid); | ||
33 | |||
34 | static inline void thread_map__delete(struct thread_map *threads) | ||
35 | { | ||
36 | free(threads); | ||
37 | } | ||
38 | |||
26 | int thread__set_comm(struct thread *self, const char *comm); | 39 | int thread__set_comm(struct thread *self, const char *comm); |
27 | int thread__comm_len(struct thread *self); | 40 | int thread__comm_len(struct thread *self); |
28 | struct thread *perf_session__findnew(struct perf_session *self, pid_t pid); | 41 | struct thread *perf_session__findnew(struct perf_session *self, pid_t pid); |