aboutsummaryrefslogtreecommitdiffstats
path: root/trace-plot-task.c
diff options
context:
space:
mode:
Diffstat (limited to 'trace-plot-task.c')
-rw-r--r--trace-plot-task.c148
1 files changed, 72 insertions, 76 deletions
diff --git a/trace-plot-task.c b/trace-plot-task.c
index 9ca97a3..e4ac13a 100644
--- a/trace-plot-task.c
+++ b/trace-plot-task.c
@@ -26,41 +26,7 @@
26#define RED 0xff 26#define RED 0xff
27#define GREEN (0xff<<16) 27#define GREEN (0xff<<16)
28 28
29struct task_plot_info { 29gboolean is_running(struct graph_info *ginfo, struct record *record)
30 int pid;
31 struct cpu_data *cpu_data;
32 struct record **last_records;
33 unsigned long long last_time;
34 unsigned long long wake_time;
35 unsigned long long display_wake_time;
36 int wake_color;
37 int last_cpu;
38};
39
40static void convert_nano(unsigned long long time, unsigned long *sec,
41 unsigned long *usec)
42{
43 *sec = time / 1000000000ULL;
44 *usec = (time / 1000) % 1000000;
45}
46
47static gint hash_pid(gint val)
48{
49 /* idle always gets black */
50 if (!val)
51 return 0;
52
53 return trace_hash(val);
54}
55
56static int hash_cpu(int cpu)
57{
58 cpu = (cpu << 3) + cpu * 21;
59
60 return trace_hash(cpu);
61}
62
63static gboolean is_running(struct graph_info *ginfo, struct record *record)
64{ 30{
65 unsigned long long val; 31 unsigned long long val;
66 int id; 32 int id;
@@ -73,7 +39,7 @@ static gboolean is_running(struct graph_info *ginfo, struct record *record)
73 return val ? FALSE : TRUE; 39 return val ? FALSE : TRUE;
74} 40}
75 41
76static gboolean record_matches_pid(struct graph_info *ginfo, 42gboolean record_matches_pid(struct graph_info *ginfo,
77 struct record *record, int match_pid, 43 struct record *record, int match_pid,
78 int *pid, int *sched_pid, 44 int *pid, int *sched_pid,
79 gboolean *is_sched, 45 gboolean *is_sched,
@@ -107,7 +73,7 @@ static gboolean record_matches_pid(struct graph_info *ginfo,
107 return FALSE; 73 return FALSE;
108} 74}
109 75
110static void set_cpu_to_time(int cpu, struct graph_info *ginfo, unsigned long long time) 76void set_cpu_to_time(int cpu, struct graph_info *ginfo, unsigned long long time)
111{ 77{
112 struct record *record; 78 struct record *record;
113 79
@@ -126,7 +92,7 @@ static void set_cpu_to_time(int cpu, struct graph_info *ginfo, unsigned long lon
126 tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time); 92 tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time);
127} 93}
128 94
129static void set_cpus_to_time(struct graph_info *ginfo, unsigned long long time) 95void set_cpus_to_time(struct graph_info *ginfo, unsigned long long time)
130{ 96{
131 int cpu; 97 int cpu;
132 98
@@ -134,7 +100,7 @@ static void set_cpus_to_time(struct graph_info *ginfo, unsigned long long time)
134 set_cpu_to_time(cpu, ginfo, time); 100 set_cpu_to_time(cpu, ginfo, time);
135} 101}
136 102
137static int task_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot, 103int task_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot,
138 unsigned long long time) 104 unsigned long long time)
139{ 105{
140 struct task_plot_info *task_info = plot->private; 106 struct task_plot_info *task_info = plot->private;
@@ -173,11 +139,7 @@ static int task_plot_match_time(struct graph_info *ginfo, struct graph_plot *plo
173 return ret; 139 return ret;
174} 140}
175 141
176struct offset_cache { 142struct offset_cache *save_offsets(struct graph_info *ginfo)
177 guint64 *offsets;
178};
179
180static struct offset_cache *save_offsets(struct graph_info *ginfo)
181{ 143{
182 struct offset_cache *offsets; 144 struct offset_cache *offsets;
183 struct record *record; 145 struct record *record;
@@ -196,7 +158,7 @@ static struct offset_cache *save_offsets(struct graph_info *ginfo)
196 return offsets; 158 return offsets;
197} 159}
198 160
199static void restore_offsets(struct graph_info *ginfo, struct offset_cache *offsets) 161void restore_offsets(struct graph_info *ginfo, struct offset_cache *offsets)
200{ 162{
201 struct record *record; 163 struct record *record;
202 int cpu; 164 int cpu;
@@ -215,7 +177,7 @@ static void restore_offsets(struct graph_info *ginfo, struct offset_cache *offse
215 free(offsets); 177 free(offsets);
216} 178}
217 179
218static struct record * 180struct record *
219find_record(struct graph_info *ginfo, gint pid, guint64 time) 181find_record(struct graph_info *ginfo, gint pid, guint64 time)
220{ 182{
221 struct record *record = NULL; 183 struct record *record = NULL;
@@ -245,7 +207,7 @@ find_record(struct graph_info *ginfo, gint pid, guint64 time)
245 return record; 207 return record;
246} 208}
247 209
248static int task_plot_display_last_event(struct graph_info *ginfo, 210int task_plot_display_last_event(struct graph_info *ginfo,
249 struct graph_plot *plot, 211 struct graph_plot *plot,
250 struct trace_seq *s, 212 struct trace_seq *s,
251 unsigned long long time) 213 unsigned long long time)
@@ -318,7 +280,7 @@ static int task_plot_display_last_event(struct graph_info *ginfo,
318 return 1; 280 return 1;
319} 281}
320 282
321static void task_plot_start(struct graph_info *ginfo, struct graph_plot *plot, 283void task_plot_start(struct graph_info *ginfo, struct graph_plot *plot,
322 unsigned long long time) 284 unsigned long long time)
323{ 285{
324 struct task_plot_info *task_info = plot->private; 286 struct task_plot_info *task_info = plot->private;
@@ -331,7 +293,7 @@ static void task_plot_start(struct graph_info *ginfo, struct graph_plot *plot,
331 task_info->display_wake_time = 0ULL; 293 task_info->display_wake_time = 0ULL;
332} 294}
333 295
334static void update_last_record(struct graph_info *ginfo, 296void update_last_task_record(struct graph_info *ginfo,
335 struct task_plot_info *task_info, 297 struct task_plot_info *task_info,
336 struct record *record) 298 struct record *record)
337{ 299{
@@ -363,7 +325,7 @@ static void update_last_record(struct graph_info *ginfo,
363 continue; 325 continue;
364 326
365 if (cpu == this_cpu) { 327 if (cpu == this_cpu) {
366 static int once; 328 int once;
367 329
368 trecord = tracecmd_read_prev(handle, record); 330 trecord = tracecmd_read_prev(handle, record);
369 /* Set cpu cursor back to what it was */ 331 /* Set cpu cursor back to what it was */
@@ -374,7 +336,7 @@ static void update_last_record(struct graph_info *ginfo,
374 } 336 }
375 free_record(saved); 337 free_record(saved);
376 } else { 338 } else {
377 static int once; 339 int once;
378 340
379 saved = tracecmd_read_data(handle, cpu); 341 saved = tracecmd_read_data(handle, cpu);
380 set_cpu_to_time(cpu, ginfo, ts); 342 set_cpu_to_time(cpu, ginfo, ts);
@@ -412,7 +374,7 @@ static void update_last_record(struct graph_info *ginfo,
412 } 374 }
413} 375}
414 376
415static int task_plot_event(struct graph_info *ginfo, 377int task_plot_event(struct graph_info *ginfo,
416 struct graph_plot *plot, 378 struct graph_plot *plot,
417 struct record *record, 379 struct record *record,
418 struct plot_info *info) 380 struct plot_info *info)
@@ -429,7 +391,7 @@ static int task_plot_event(struct graph_info *ginfo,
429 pid = task_info->pid; 391 pid = task_info->pid;
430 392
431 if (!record) { 393 if (!record) {
432 update_last_record(ginfo, task_info, record); 394 update_last_task_record(ginfo, task_info, record);
433 /* no more records, finish a box if one was started */ 395 /* no more records, finish a box if one was started */
434 if (task_info->last_cpu >= 0) { 396 if (task_info->last_cpu >= 0) {
435 info->box = TRUE; 397 info->box = TRUE;
@@ -468,7 +430,7 @@ static int task_plot_event(struct graph_info *ginfo,
468 * viewable range. Search to see if one exists, and if 430 * viewable range. Search to see if one exists, and if
469 * it is the record we want to match. 431 * it is the record we want to match.
470 */ 432 */
471 update_last_record(ginfo, task_info, record); 433 update_last_task_record(ginfo, task_info, record);
472 434
473 if (is_wakeup) { 435 if (is_wakeup) {
474 /* Wake up but not task */ 436 /* Wake up but not task */
@@ -555,7 +517,7 @@ static int task_plot_event(struct graph_info *ginfo,
555} 517}
556 518
557 519
558static struct record * 520struct record *
559task_plot_find_record(struct graph_info *ginfo, struct graph_plot *plot, 521task_plot_find_record(struct graph_info *ginfo, struct graph_plot *plot,
560 unsigned long long time) 522 unsigned long long time)
561{ 523{
@@ -569,7 +531,7 @@ task_plot_find_record(struct graph_info *ginfo, struct graph_plot *plot,
569 531
570#define MAX_SEARCH 20 532#define MAX_SEARCH 20
571 533
572static struct record * 534struct record *
573find_previous_record(struct graph_info *ginfo, struct record *start_record, 535find_previous_record(struct graph_info *ginfo, struct record *start_record,
574 int pid, int cpu) 536 int pid, int cpu)
575{ 537{
@@ -609,7 +571,7 @@ find_previous_record(struct graph_info *ginfo, struct record *start_record,
609 return record; 571 return record;
610} 572}
611 573
612static struct record * 574struct record *
613get_display_record(struct graph_info *ginfo, int pid, unsigned long long time) 575get_display_record(struct graph_info *ginfo, int pid, unsigned long long time)
614{ 576{
615 struct record *record; 577 struct record *record;
@@ -752,16 +714,10 @@ static const struct plot_callbacks task_plot_cb = {
752 .destroy = task_plot_destroy 714 .destroy = task_plot_destroy
753}; 715};
754 716
755/** 717
756 * graph_plot_task_plotted - return what tasks are plotted 718void graph_tasks_plotted(struct graph_info *ginfo,
757 * @ginfo: the graph info structure 719 enum task_plot_type type,
758 * @plotted: returns an allocated array of gints holding the pids. 720 gint **plotted)
759 * the last pid is -1, NULL, if none are.
760 *
761 * @plotted must be freed with free() after this is called.
762 */
763void graph_plot_task_plotted(struct graph_info *ginfo,
764 gint **plotted)
765{ 721{
766 struct task_plot_info *task_info; 722 struct task_plot_info *task_info;
767 struct graph_plot *plot; 723 struct graph_plot *plot;
@@ -778,10 +734,26 @@ void graph_plot_task_plotted(struct graph_info *ginfo,
778 } 734 }
779} 735}
780 736
781void graph_plot_task_update_callback(gboolean accept, 737/**
782 gint *selected, 738 * graph_plot_task_plotted - return what tasks are plotted
783 gint *non_select, 739 * @ginfo: the graph info structure
784 gpointer data) 740 * @plotted: returns an allocated array of gints holding the pids.
741 * the last pid is -1, NULL, if none are.
742 *
743 * @plotted must be freed with free() after this is called.
744 */
745void graph_plot_task_plotted(struct graph_info *ginfo,
746 gint **plotted)
747{
748 graph_tasks_plotted(ginfo, TASK_PLOT_LINUX, plotted);
749}
750
751void graph_tasks_update_callback(enum task_plot_type type,
752 plot_task_cb plot_cb,
753 gboolean accept,
754 gint *selected,
755 gint *non_select,
756 gpointer data)
785{ 757{
786 struct graph_info *ginfo = data; 758 struct graph_info *ginfo = data;
787 struct task_plot_info *task_info; 759 struct task_plot_info *task_info;
@@ -809,12 +781,16 @@ void graph_plot_task_update_callback(gboolean accept,
809 plot = ginfo->plot_array[i]; 781 plot = ginfo->plot_array[i];
810 if (plot->type != PLOT_TYPE_TASK) 782 if (plot->type != PLOT_TYPE_TASK)
811 continue; 783 continue;
784
785 task_info = plot->private;
786 if (task_info->type != type)
787 continue;
788
812 /* If non are selected, then remove all */ 789 /* If non are selected, then remove all */
813 if (!select_size) { 790 if (!select_size) {
814 trace_graph_plot_remove(ginfo, plot); 791 trace_graph_plot_remove(ginfo, plot);
815 continue; 792 continue;
816 } 793 }
817 task_info = plot->private;
818 ptr = bsearch(&task_info->pid, selected, select_size, 794 ptr = bsearch(&task_info->pid, selected, select_size,
819 sizeof(gint), id_cmp); 795 sizeof(gint), id_cmp);
820 if (ptr) { 796 if (ptr) {
@@ -834,11 +810,20 @@ void graph_plot_task_update_callback(gboolean accept,
834 810
835 /* Now add any plots that need to be added */ 811 /* Now add any plots that need to be added */
836 for (i = 0; i < select_size; i++) 812 for (i = 0; i < select_size; i++)
837 graph_plot_task(ginfo, selected[i], ginfo->plots); 813 plot_cb(ginfo, selected[i], ginfo->plots);
838 814
839 trace_graph_refresh(ginfo); 815 trace_graph_refresh(ginfo);
840} 816}
841 817
818void graph_plot_task_update_callback(gboolean accept,
819 gint *selected,
820 gint *non_select,
821 gpointer data)
822{
823 graph_tasks_update_callback(TASK_PLOT_LINUX, graph_plot_task,
824 accept, selected, non_select, data);
825}
826
842void graph_plot_init_tasks(struct graph_info *ginfo) 827void graph_plot_init_tasks(struct graph_info *ginfo)
843{ 828{
844 struct task_plot_info *task_info; 829 struct task_plot_info *task_info;
@@ -866,6 +851,17 @@ void graph_plot_init_tasks(struct graph_info *ginfo)
866 &task_plot_cb, task_info); 851 &task_plot_cb, task_info);
867} 852}
868 853
854void init_task_plot_info(struct graph_info *ginfo,
855 struct task_plot_info *task_info,
856 enum task_plot_type type,
857 int pid)
858{
859 task_info->last_records =
860 malloc_or_die(sizeof(struct record *) * ginfo->cpus);
861 task_info->pid = pid;
862 task_info->type = type;
863}
864
869void graph_plot_task(struct graph_info *ginfo, int pid, int pos) 865void graph_plot_task(struct graph_info *ginfo, int pid, int pos)
870{ 866{
871 struct task_plot_info *task_info; 867 struct task_plot_info *task_info;
@@ -875,9 +871,9 @@ void graph_plot_task(struct graph_info *ginfo, int pid, int pos)
875 int len; 871 int len;
876 872
877 task_info = malloc_or_die(sizeof(*task_info)); 873 task_info = malloc_or_die(sizeof(*task_info));
878 task_info->last_records = 874
879 malloc_or_die(sizeof(struct record *) * ginfo->cpus); 875 init_task_plot_info(ginfo, task_info, TASK_PLOT_LINUX, pid);
880 task_info->pid = pid; 876
881 comm = pevent_data_comm_from_pid(ginfo->pevent, pid); 877 comm = pevent_data_comm_from_pid(ginfo->pevent, pid);
882 878
883 len = strlen(comm) + 100; 879 len = strlen(comm) + 100;