aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-record.c39
-rw-r--r--tools/perf/builtin-stat.c41
-rw-r--r--tools/perf/builtin-top.c35
-rw-r--r--tools/perf/util/thread.c43
-rw-r--r--tools/perf/util/thread.h15
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;
54static bool system_wide = false; 54static bool system_wide = false;
55static pid_t target_pid = -1; 55static pid_t target_pid = -1;
56static pid_t target_tid = -1; 56static pid_t target_tid = -1;
57static pid_t *all_tids = NULL; 57static struct thread_map *threads;
58static int thread_num = 0;
59static pid_t child_pid = -1; 58static pid_t child_pid = -1;
60static bool no_inherit = false; 59static bool no_inherit = false;
61static enum write_mode_t write_mode = WRITE_FORCE; 60static enum write_mode_t write_mode = WRITE_FORCE;
@@ -318,9 +317,9 @@ static void create_counter(struct perf_evsel *evsel, int cpu)
318retry_sample_id: 317retry_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++) {
322try_again: 321try_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)
965out_free_event_array: 956out_free_event_array:
966 free(event_array); 957 free(event_array);
967out_free_fd: 958out_free_fd:
968 free(all_tids); 959 thread_map__delete(threads);
969 all_tids = NULL; 960 threads = NULL;
970out_symbol_exit: 961out_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;
81static bool no_aggr = false; 81static bool no_aggr = false;
82static pid_t target_pid = -1; 82static pid_t target_pid = -1;
83static pid_t target_tid = -1; 83static pid_t target_tid = -1;
84static pid_t *all_tids = NULL; 84static struct thread_map *threads;
85static int thread_num = 0;
86static pid_t child_pid = -1; 85static pid_t child_pid = -1;
87static bool null_run = false; 86static bool null_run = false;
88static bool big_num = true; 87static 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);
754out: 745out:
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
69static int target_pid = -1; 69static int target_pid = -1;
70static int target_tid = -1; 70static int target_tid = -1;
71static pid_t *all_tids = NULL; 71static struct thread_map *threads;
72static int thread_num = 0;
73static bool inherit = false; 72static bool inherit = false;
74static struct cpu_map *cpus; 73static struct cpu_map *cpus;
75static int realtime_prio = 0; 74static 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++) {
1240try_again: 1239try_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
19int find_all_tid(int pid, pid_t ** all_tid) 19struct 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
42failure:
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
46struct 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
58struct 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
50static struct thread *thread__new(pid_t pid) 65static 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
21struct thread_map {
22 int nr;
23 int map[];
24};
25
21struct perf_session; 26struct perf_session;
22 27
23void thread__delete(struct thread *self); 28void thread__delete(struct thread *self);
24 29
25int find_all_tid(int pid, pid_t ** all_tid); 30struct thread_map *thread_map__new_by_pid(pid_t pid);
31struct thread_map *thread_map__new_by_tid(pid_t tid);
32struct thread_map *thread_map__new(pid_t pid, pid_t tid);
33
34static inline void thread_map__delete(struct thread_map *threads)
35{
36 free(threads);
37}
38
26int thread__set_comm(struct thread *self, const char *comm); 39int thread__set_comm(struct thread *self, const char *comm);
27int thread__comm_len(struct thread *self); 40int thread__comm_len(struct thread *self);
28struct thread *perf_session__findnew(struct perf_session *self, pid_t pid); 41struct thread *perf_session__findnew(struct perf_session *self, pid_t pid);