aboutsummaryrefslogtreecommitdiffstats
path: root/trace-plot-cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'trace-plot-cpu.c')
-rw-r--r--trace-plot-cpu.c83
1 files changed, 73 insertions, 10 deletions
diff --git a/trace-plot-cpu.c b/trace-plot-cpu.c
index 1c86df8..0e7f5e8 100644
--- a/trace-plot-cpu.c
+++ b/trace-plot-cpu.c
@@ -27,6 +27,7 @@ struct cpu_plot_info {
27 int cpu; 27 int cpu;
28 unsigned long long last_time; 28 unsigned long long last_time;
29 int last_pid; 29 int last_pid;
30 struct record *last_record;
30}; 31};
31 32
32static gint hash_pid(gint val) 33static gint hash_pid(gint val)
@@ -45,15 +46,10 @@ static void convert_nano(unsigned long long time, unsigned long *sec,
45 *usec = (time / 1000) % 1000000; 46 *usec = (time / 1000) % 1000000;
46} 47}
47 48
48static int cpu_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot, 49static struct record *get_record_from_time(struct graph_info *ginfo, int cpu,
49 unsigned long long time) 50 unsigned long long time)
50{ 51{
51 struct cpu_plot_info *cpu_info = plot->private;
52 struct record *record; 52 struct record *record;
53 long cpu;
54 int ret = 0;
55
56 cpu = cpu_info->cpu;
57 53
58 tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time); 54 tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time);
59 record = tracecmd_read_data(ginfo->handle, cpu); 55 record = tracecmd_read_data(ginfo->handle, cpu);
@@ -61,6 +57,18 @@ static int cpu_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot
61 free_record(record); 57 free_record(record);
62 record = tracecmd_read_data(ginfo->handle, cpu); 58 record = tracecmd_read_data(ginfo->handle, cpu);
63 } 59 }
60
61 return record;
62}
63
64static int cpu_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot,
65 unsigned long long time)
66{
67 struct cpu_plot_info *cpu_info = plot->private;
68 struct record *record;
69 int ret = 0;
70
71 record = get_record_from_time(ginfo, cpu_info->cpu, time);
64 if (record && record->ts == time) 72 if (record && record->ts == time)
65 ret = 1; 73 ret = 1;
66 free_record(record); 74 free_record(record);
@@ -192,6 +200,41 @@ static void cpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot,
192 cpu = cpu_info->cpu; 200 cpu = cpu_info->cpu;
193 cpu_info->last_time = 0ULL; 201 cpu_info->last_time = 0ULL;
194 cpu_info->last_pid = -1; 202 cpu_info->last_pid = -1;
203 cpu_info->last_record = NULL;
204}
205
206static void update_last_record(struct graph_info *ginfo,
207 struct cpu_plot_info *cpu_info,
208 struct record *record)
209{
210 struct tracecmd_input *handle = ginfo->handle;
211 struct record *trecord;
212 int filter;
213 int sched_pid;
214 int orig_pid;
215 int is_sched_switch;
216
217 if (record)
218 tracecmd_record_ref(record);
219 else
220 record = get_record_from_time(ginfo, cpu_info->cpu,
221 ginfo->view_end_time);
222
223 trecord = tracecmd_read_prev(handle, record);
224 free_record(record);
225
226 if (!trecord)
227 return;
228
229 filter = filter_record(ginfo, trecord,
230 &orig_pid, &sched_pid,
231 &is_sched_switch);
232 cpu_info->last_pid = is_sched_switch ? sched_pid : orig_pid;
233 cpu_info->last_record = trecord;
234 cpu_info->last_time = trecord->ts;
235 /* We moved the cursor, put it back */
236 trecord = tracecmd_read_data(handle, cpu_info->cpu);
237 free_record(trecord);
195} 238}
196 239
197static int cpu_plot_event(struct graph_info *ginfo, 240static int cpu_plot_event(struct graph_info *ginfo,
@@ -212,6 +255,9 @@ static int cpu_plot_event(struct graph_info *ginfo,
212 cpu = cpu_info->cpu; 255 cpu = cpu_info->cpu;
213 256
214 if (!record) { 257 if (!record) {
258 if (!cpu_info->last_record)
259 update_last_record(ginfo, cpu_info, record);
260
215 /* Finish a box if the last record was not idle */ 261 /* Finish a box if the last record was not idle */
216 if (cpu_info->last_pid > 0) { 262 if (cpu_info->last_pid > 0) {
217 info->box = TRUE; 263 info->box = TRUE;
@@ -219,9 +265,24 @@ static int cpu_plot_event(struct graph_info *ginfo,
219 info->bend = ginfo->view_end_time; 265 info->bend = ginfo->view_end_time;
220 info->bcolor = hash_pid(cpu_info->last_pid); 266 info->bcolor = hash_pid(cpu_info->last_pid);
221 } 267 }
268 if (cpu_info->last_record) {
269 free_record(cpu_info->last_record);
270 cpu_info->last_record = NULL;
271 }
222 return 0; 272 return 0;
223 } 273 }
224 274
275 /*
276 * If last record is NULL, then it may exist off the
277 * viewable range. Search to see if one exists.
278 */
279 if (!cpu_info->last_record)
280 update_last_record(ginfo, cpu_info, record);
281
282 free_record(cpu_info->last_record);
283 cpu_info->last_record = record;
284 tracecmd_record_ref(record);
285
225 cpu = cpu_info->cpu; 286 cpu = cpu_info->cpu;
226 287
227 filter = filter_record(ginfo, record, &orig_pid, &sched_pid, &is_sched_switch); 288 filter = filter_record(ginfo, record, &orig_pid, &sched_pid, &is_sched_switch);
@@ -237,10 +298,12 @@ static int cpu_plot_event(struct graph_info *ginfo,
237 cpu_info->last_pid = orig_pid; 298 cpu_info->last_pid = orig_pid;
238 else 299 else
239 cpu_info->last_pid = pid; 300 cpu_info->last_pid = pid;
240 }
241 301
242 /* Box should always use the original pid (prev in sched_switch) */ 302 /* Box should always use the original pid (prev in sched_switch) */
243 box_filter = trace_graph_filter_on_task(ginfo, orig_pid); 303 box_filter = trace_graph_filter_on_task(ginfo, orig_pid);
304 } else
305 box_filter = trace_graph_filter_on_task(ginfo, cpu_info->last_pid);
306
244 307
245 if (!box_filter && cpu_info->last_pid) { 308 if (!box_filter && cpu_info->last_pid) {
246 info->bcolor = hash_pid(cpu_info->last_pid); 309 info->bcolor = hash_pid(cpu_info->last_pid);