aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2013-11-28 09:50:41 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-12-02 07:22:46 -0500
commit5e22f6d22bae494ffc23da4032c477c54fd7c2d9 (patch)
tree7eea81634c22e2c46cd03d3dece6e7b864a531b1 /tools
parent985b12e633246750b5424f0a28d5f8cea04de07a (diff)
perf timechart: Move all_data per_pid list to 'struct timechart'
Removing another global variable. This one tho would be better done by using the machine infrastructure, searching for the 'struct thread' with a pid, then using thread->priv, etc. TODO list material for now. Cc: Adrian Hunter <adrian.hunter@intel.com> 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@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stanislav Fomichev <stfomichev@yandex-team.ru> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-yyfpudgjvr6mev4bue9u72a2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-timechart.c113
1 files changed, 59 insertions, 54 deletions
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index e2d62f1a96e4..0c955acc08a2 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -41,8 +41,11 @@
41#define SUPPORT_OLD_POWER_EVENTS 1 41#define SUPPORT_OLD_POWER_EVENTS 1
42#define PWR_EVENT_EXIT -1 42#define PWR_EVENT_EXIT -1
43 43
44struct per_pid;
45
44struct timechart { 46struct timechart {
45 struct perf_tool tool; 47 struct perf_tool tool;
48 struct per_pid *all_data;
46 int proc_num; 49 int proc_num;
47 unsigned int numcpus; 50 unsigned int numcpus;
48 u64 min_freq, /* Lowest CPU frequency seen */ 51 u64 min_freq, /* Lowest CPU frequency seen */
@@ -123,8 +126,6 @@ struct cpu_sample {
123 const char *backtrace; 126 const char *backtrace;
124}; 127};
125 128
126static struct per_pid *all_data;
127
128#define CSTATE 1 129#define CSTATE 1
129#define PSTATE 2 130#define PSTATE 2
130 131
@@ -157,9 +158,9 @@ struct process_filter {
157static struct process_filter *process_filter; 158static struct process_filter *process_filter;
158 159
159 160
160static struct per_pid *find_create_pid(int pid) 161static struct per_pid *find_create_pid(struct timechart *tchart, int pid)
161{ 162{
162 struct per_pid *cursor = all_data; 163 struct per_pid *cursor = tchart->all_data;
163 164
164 while (cursor) { 165 while (cursor) {
165 if (cursor->pid == pid) 166 if (cursor->pid == pid)
@@ -169,16 +170,16 @@ static struct per_pid *find_create_pid(int pid)
169 cursor = zalloc(sizeof(*cursor)); 170 cursor = zalloc(sizeof(*cursor));
170 assert(cursor != NULL); 171 assert(cursor != NULL);
171 cursor->pid = pid; 172 cursor->pid = pid;
172 cursor->next = all_data; 173 cursor->next = tchart->all_data;
173 all_data = cursor; 174 tchart->all_data = cursor;
174 return cursor; 175 return cursor;
175} 176}
176 177
177static void pid_set_comm(int pid, char *comm) 178static void pid_set_comm(struct timechart *tchart, int pid, char *comm)
178{ 179{
179 struct per_pid *p; 180 struct per_pid *p;
180 struct per_pidcomm *c; 181 struct per_pidcomm *c;
181 p = find_create_pid(pid); 182 p = find_create_pid(tchart, pid);
182 c = p->all; 183 c = p->all;
183 while (c) { 184 while (c) {
184 if (c->comm && strcmp(c->comm, comm) == 0) { 185 if (c->comm && strcmp(c->comm, comm) == 0) {
@@ -200,14 +201,14 @@ static void pid_set_comm(int pid, char *comm)
200 p->all = c; 201 p->all = c;
201} 202}
202 203
203static void pid_fork(int pid, int ppid, u64 timestamp) 204static void pid_fork(struct timechart *tchart, int pid, int ppid, u64 timestamp)
204{ 205{
205 struct per_pid *p, *pp; 206 struct per_pid *p, *pp;
206 p = find_create_pid(pid); 207 p = find_create_pid(tchart, pid);
207 pp = find_create_pid(ppid); 208 pp = find_create_pid(tchart, ppid);
208 p->ppid = ppid; 209 p->ppid = ppid;
209 if (pp->current && pp->current->comm && !p->current) 210 if (pp->current && pp->current->comm && !p->current)
210 pid_set_comm(pid, pp->current->comm); 211 pid_set_comm(tchart, pid, pp->current->comm);
211 212
212 p->start_time = timestamp; 213 p->start_time = timestamp;
213 if (p->current) { 214 if (p->current) {
@@ -216,24 +217,24 @@ static void pid_fork(int pid, int ppid, u64 timestamp)
216 } 217 }
217} 218}
218 219
219static void pid_exit(int pid, u64 timestamp) 220static void pid_exit(struct timechart *tchart, int pid, u64 timestamp)
220{ 221{
221 struct per_pid *p; 222 struct per_pid *p;
222 p = find_create_pid(pid); 223 p = find_create_pid(tchart, pid);
223 p->end_time = timestamp; 224 p->end_time = timestamp;
224 if (p->current) 225 if (p->current)
225 p->current->end_time = timestamp; 226 p->current->end_time = timestamp;
226} 227}
227 228
228static void 229static void pid_put_sample(struct timechart *tchart, int pid, int type,
229pid_put_sample(int pid, int type, unsigned int cpu, u64 start, u64 end, 230 unsigned int cpu, u64 start, u64 end,
230 const char *backtrace) 231 const char *backtrace)
231{ 232{
232 struct per_pid *p; 233 struct per_pid *p;
233 struct per_pidcomm *c; 234 struct per_pidcomm *c;
234 struct cpu_sample *sample; 235 struct cpu_sample *sample;
235 236
236 p = find_create_pid(pid); 237 p = find_create_pid(tchart, pid);
237 c = p->current; 238 c = p->current;
238 if (!c) { 239 if (!c) {
239 c = zalloc(sizeof(*c)); 240 c = zalloc(sizeof(*c));
@@ -271,30 +272,33 @@ static int cpus_cstate_state[MAX_CPUS];
271static u64 cpus_pstate_start_times[MAX_CPUS]; 272static u64 cpus_pstate_start_times[MAX_CPUS];
272static u64 cpus_pstate_state[MAX_CPUS]; 273static u64 cpus_pstate_state[MAX_CPUS];
273 274
274static int process_comm_event(struct perf_tool *tool __maybe_unused, 275static int process_comm_event(struct perf_tool *tool,
275 union perf_event *event, 276 union perf_event *event,
276 struct perf_sample *sample __maybe_unused, 277 struct perf_sample *sample __maybe_unused,
277 struct machine *machine __maybe_unused) 278 struct machine *machine __maybe_unused)
278{ 279{
279 pid_set_comm(event->comm.tid, event->comm.comm); 280 struct timechart *tchart = container_of(tool, struct timechart, tool);
281 pid_set_comm(tchart, event->comm.tid, event->comm.comm);
280 return 0; 282 return 0;
281} 283}
282 284
283static int process_fork_event(struct perf_tool *tool __maybe_unused, 285static int process_fork_event(struct perf_tool *tool,
284 union perf_event *event, 286 union perf_event *event,
285 struct perf_sample *sample __maybe_unused, 287 struct perf_sample *sample __maybe_unused,
286 struct machine *machine __maybe_unused) 288 struct machine *machine __maybe_unused)
287{ 289{
288 pid_fork(event->fork.pid, event->fork.ppid, event->fork.time); 290 struct timechart *tchart = container_of(tool, struct timechart, tool);
291 pid_fork(tchart, event->fork.pid, event->fork.ppid, event->fork.time);
289 return 0; 292 return 0;
290} 293}
291 294
292static int process_exit_event(struct perf_tool *tool __maybe_unused, 295static int process_exit_event(struct perf_tool *tool,
293 union perf_event *event, 296 union perf_event *event,
294 struct perf_sample *sample __maybe_unused, 297 struct perf_sample *sample __maybe_unused,
295 struct machine *machine __maybe_unused) 298 struct machine *machine __maybe_unused)
296{ 299{
297 pid_exit(event->fork.pid, event->fork.time); 300 struct timechart *tchart = container_of(tool, struct timechart, tool);
301 pid_exit(tchart, event->fork.pid, event->fork.time);
298 return 0; 302 return 0;
299} 303}
300 304
@@ -361,8 +365,8 @@ static void p_state_change(struct timechart *tchart, int cpu, u64 timestamp, u64
361 tchart->turbo_frequency = tchart->max_freq; 365 tchart->turbo_frequency = tchart->max_freq;
362} 366}
363 367
364static void sched_wakeup(int cpu, u64 timestamp, int waker, int wakee, 368static void sched_wakeup(struct timechart *tchart, int cpu, u64 timestamp,
365 u8 flags, const char *backtrace) 369 int waker, int wakee, u8 flags, const char *backtrace)
366{ 370{
367 struct per_pid *p; 371 struct per_pid *p;
368 struct wake_event *we = zalloc(sizeof(*we)); 372 struct wake_event *we = zalloc(sizeof(*we));
@@ -380,36 +384,37 @@ static void sched_wakeup(int cpu, u64 timestamp, int waker, int wakee,
380 we->wakee = wakee; 384 we->wakee = wakee;
381 we->next = wake_events; 385 we->next = wake_events;
382 wake_events = we; 386 wake_events = we;
383 p = find_create_pid(we->wakee); 387 p = find_create_pid(tchart, we->wakee);
384 388
385 if (p && p->current && p->current->state == TYPE_NONE) { 389 if (p && p->current && p->current->state == TYPE_NONE) {
386 p->current->state_since = timestamp; 390 p->current->state_since = timestamp;
387 p->current->state = TYPE_WAITING; 391 p->current->state = TYPE_WAITING;
388 } 392 }
389 if (p && p->current && p->current->state == TYPE_BLOCKED) { 393 if (p && p->current && p->current->state == TYPE_BLOCKED) {
390 pid_put_sample(p->pid, p->current->state, cpu, 394 pid_put_sample(tchart, p->pid, p->current->state, cpu,
391 p->current->state_since, timestamp, NULL); 395 p->current->state_since, timestamp, NULL);
392 p->current->state_since = timestamp; 396 p->current->state_since = timestamp;
393 p->current->state = TYPE_WAITING; 397 p->current->state = TYPE_WAITING;
394 } 398 }
395} 399}
396 400
397static void sched_switch(int cpu, u64 timestamp, int prev_pid, int next_pid, 401static void sched_switch(struct timechart *tchart, int cpu, u64 timestamp,
398 u64 prev_state, const char *backtrace) 402 int prev_pid, int next_pid, u64 prev_state,
403 const char *backtrace)
399{ 404{
400 struct per_pid *p = NULL, *prev_p; 405 struct per_pid *p = NULL, *prev_p;
401 406
402 prev_p = find_create_pid(prev_pid); 407 prev_p = find_create_pid(tchart, prev_pid);
403 408
404 p = find_create_pid(next_pid); 409 p = find_create_pid(tchart, next_pid);
405 410
406 if (prev_p->current && prev_p->current->state != TYPE_NONE) 411 if (prev_p->current && prev_p->current->state != TYPE_NONE)
407 pid_put_sample(prev_pid, TYPE_RUNNING, cpu, 412 pid_put_sample(tchart, prev_pid, TYPE_RUNNING, cpu,
408 prev_p->current->state_since, timestamp, 413 prev_p->current->state_since, timestamp,
409 backtrace); 414 backtrace);
410 if (p && p->current) { 415 if (p && p->current) {
411 if (p->current->state != TYPE_NONE) 416 if (p->current->state != TYPE_NONE)
412 pid_put_sample(next_pid, p->current->state, cpu, 417 pid_put_sample(tchart, next_pid, p->current->state, cpu,
413 p->current->state_since, timestamp, 418 p->current->state_since, timestamp,
414 backtrace); 419 backtrace);
415 420
@@ -566,7 +571,7 @@ process_sample_cpu_frequency(struct timechart *tchart,
566} 571}
567 572
568static int 573static int
569process_sample_sched_wakeup(struct timechart *tchart __maybe_unused, 574process_sample_sched_wakeup(struct timechart *tchart,
570 struct perf_evsel *evsel, 575 struct perf_evsel *evsel,
571 struct perf_sample *sample, 576 struct perf_sample *sample,
572 const char *backtrace) 577 const char *backtrace)
@@ -575,12 +580,12 @@ process_sample_sched_wakeup(struct timechart *tchart __maybe_unused,
575 int waker = perf_evsel__intval(evsel, sample, "common_pid"); 580 int waker = perf_evsel__intval(evsel, sample, "common_pid");
576 int wakee = perf_evsel__intval(evsel, sample, "pid"); 581 int wakee = perf_evsel__intval(evsel, sample, "pid");
577 582
578 sched_wakeup(sample->cpu, sample->time, waker, wakee, flags, backtrace); 583 sched_wakeup(tchart, sample->cpu, sample->time, waker, wakee, flags, backtrace);
579 return 0; 584 return 0;
580} 585}
581 586
582static int 587static int
583process_sample_sched_switch(struct timechart *tchart __maybe_unused, 588process_sample_sched_switch(struct timechart *tchart,
584 struct perf_evsel *evsel, 589 struct perf_evsel *evsel,
585 struct perf_sample *sample, 590 struct perf_sample *sample,
586 const char *backtrace) 591 const char *backtrace)
@@ -589,8 +594,8 @@ process_sample_sched_switch(struct timechart *tchart __maybe_unused,
589 int next_pid = perf_evsel__intval(evsel, sample, "next_pid"); 594 int next_pid = perf_evsel__intval(evsel, sample, "next_pid");
590 u64 prev_state = perf_evsel__intval(evsel, sample, "prev_state"); 595 u64 prev_state = perf_evsel__intval(evsel, sample, "prev_state");
591 596
592 sched_switch(sample->cpu, sample->time, prev_pid, next_pid, prev_state, 597 sched_switch(tchart, sample->cpu, sample->time, prev_pid, next_pid,
593 backtrace); 598 prev_state, backtrace);
594 return 0; 599 return 0;
595} 600}
596 601
@@ -681,16 +686,16 @@ static void end_sample_processing(struct timechart *tchart)
681/* 686/*
682 * Sort the pid datastructure 687 * Sort the pid datastructure
683 */ 688 */
684static void sort_pids(void) 689static void sort_pids(struct timechart *tchart)
685{ 690{
686 struct per_pid *new_list, *p, *cursor, *prev; 691 struct per_pid *new_list, *p, *cursor, *prev;
687 /* sort by ppid first, then by pid, lowest to highest */ 692 /* sort by ppid first, then by pid, lowest to highest */
688 693
689 new_list = NULL; 694 new_list = NULL;
690 695
691 while (all_data) { 696 while (tchart->all_data) {
692 p = all_data; 697 p = tchart->all_data;
693 all_data = p->next; 698 tchart->all_data = p->next;
694 p->next = NULL; 699 p->next = NULL;
695 700
696 if (new_list == NULL) { 701 if (new_list == NULL) {
@@ -723,7 +728,7 @@ static void sort_pids(void)
723 prev->next = p; 728 prev->next = p;
724 } 729 }
725 } 730 }
726 all_data = new_list; 731 tchart->all_data = new_list;
727} 732}
728 733
729 734
@@ -752,7 +757,7 @@ static void draw_c_p_states(struct timechart *tchart)
752 } 757 }
753} 758}
754 759
755static void draw_wakeups(void) 760static void draw_wakeups(struct timechart *tchart)
756{ 761{
757 struct wake_event *we; 762 struct wake_event *we;
758 struct per_pid *p; 763 struct per_pid *p;
@@ -764,7 +769,7 @@ static void draw_wakeups(void)
764 char *task_from = NULL, *task_to = NULL; 769 char *task_from = NULL, *task_to = NULL;
765 770
766 /* locate the column of the waker and wakee */ 771 /* locate the column of the waker and wakee */
767 p = all_data; 772 p = tchart->all_data;
768 while (p) { 773 while (p) {
769 if (p->pid == we->waker || p->pid == we->wakee) { 774 if (p->pid == we->waker || p->pid == we->wakee) {
770 c = p->all; 775 c = p->all;
@@ -820,12 +825,12 @@ static void draw_wakeups(void)
820 } 825 }
821} 826}
822 827
823static void draw_cpu_usage(void) 828static void draw_cpu_usage(struct timechart *tchart)
824{ 829{
825 struct per_pid *p; 830 struct per_pid *p;
826 struct per_pidcomm *c; 831 struct per_pidcomm *c;
827 struct cpu_sample *sample; 832 struct cpu_sample *sample;
828 p = all_data; 833 p = tchart->all_data;
829 while (p) { 834 while (p) {
830 c = p->all; 835 c = p->all;
831 while (c) { 836 while (c) {
@@ -851,7 +856,7 @@ static void draw_process_bars(struct timechart *tchart)
851 856
852 Y = 2 * tchart->numcpus + 2; 857 Y = 2 * tchart->numcpus + 2;
853 858
854 p = all_data; 859 p = tchart->all_data;
855 while (p) { 860 while (p) {
856 c = p->all; 861 c = p->all;
857 while (c) { 862 while (c) {
@@ -937,7 +942,7 @@ static int determine_display_tasks_filtered(struct timechart *tchart)
937 struct per_pidcomm *c; 942 struct per_pidcomm *c;
938 int count = 0; 943 int count = 0;
939 944
940 p = all_data; 945 p = tchart->all_data;
941 while (p) { 946 while (p) {
942 p->display = 0; 947 p->display = 0;
943 if (p->start_time == 1) 948 if (p->start_time == 1)
@@ -980,7 +985,7 @@ static int determine_display_tasks(struct timechart *tchart, u64 threshold)
980 if (process_filter) 985 if (process_filter)
981 return determine_display_tasks_filtered(tchart); 986 return determine_display_tasks_filtered(tchart);
982 987
983 p = all_data; 988 p = tchart->all_data;
984 while (p) { 989 while (p) {
985 p->display = 0; 990 p->display = 0;
986 if (p->start_time == 1) 991 if (p->start_time == 1)
@@ -1045,13 +1050,13 @@ static void write_svg_file(struct timechart *tchart, const char *filename)
1045 for (i = 0; i < tchart->numcpus; i++) 1050 for (i = 0; i < tchart->numcpus; i++)
1046 svg_cpu_box(i, tchart->max_freq, tchart->turbo_frequency); 1051 svg_cpu_box(i, tchart->max_freq, tchart->turbo_frequency);
1047 1052
1048 draw_cpu_usage(); 1053 draw_cpu_usage(tchart);
1049 if (tchart->proc_num) 1054 if (tchart->proc_num)
1050 draw_process_bars(tchart); 1055 draw_process_bars(tchart);
1051 if (!tchart->tasks_only) 1056 if (!tchart->tasks_only)
1052 draw_c_p_states(tchart); 1057 draw_c_p_states(tchart);
1053 if (tchart->proc_num) 1058 if (tchart->proc_num)
1054 draw_wakeups(); 1059 draw_wakeups(tchart);
1055 1060
1056 svg_close(); 1061 svg_close();
1057} 1062}
@@ -1096,7 +1101,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)
1096 1101
1097 end_sample_processing(tchart); 1102 end_sample_processing(tchart);
1098 1103
1099 sort_pids(); 1104 sort_pids(tchart);
1100 1105
1101 write_svg_file(tchart, output_name); 1106 write_svg_file(tchart, output_name);
1102 1107