diff options
Diffstat (limited to 'trace-plot-cpu.c')
-rw-r--r-- | trace-plot-cpu.c | 83 |
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 | ||
32 | static gint hash_pid(gint val) | 33 | static 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 | ||
48 | static int cpu_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot, | 49 | static 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 | |||
64 | static 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 | |||
206 | static 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 | ||
197 | static int cpu_plot_event(struct graph_info *ginfo, | 240 | static 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); |