diff options
| author | Steven Rostedt <srostedt@redhat.com> | 2010-09-17 14:44:08 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2010-09-17 14:44:08 -0400 |
| commit | a12a227df2a7a93a7f037d3b33183eadc7254591 (patch) | |
| tree | 09fd24c6083e2da63fced20da47cfea00d3c92f1 | |
| parent | e34749ef3e83e155e4e6ed4cc6034c81305c3896 (diff) | |
trace-graph: Fix plots to show start bars in zoomed views.
Currently, if a zoomed view has events before the start of the view,
those events are not examined to determine if the bar of a graph should
be shown at the start.
This patch adds code to the cpu and task plots to look for events
that happened before the view to determine if a bar should be shown
or not.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
| -rw-r--r-- | trace-plot-cpu.c | 32 | ||||
| -rw-r--r-- | trace-plot-task.c | 126 |
2 files changed, 143 insertions, 15 deletions
diff --git a/trace-plot-cpu.c b/trace-plot-cpu.c index 09b1690..d6800ef 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) |
| @@ -192,6 +193,7 @@ static void cpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot, | |||
| 192 | cpu = cpu_info->cpu; | 193 | cpu = cpu_info->cpu; |
| 193 | cpu_info->last_time = 0ULL; | 194 | cpu_info->last_time = 0ULL; |
| 194 | cpu_info->last_pid = -1; | 195 | cpu_info->last_pid = -1; |
| 196 | cpu_info->last_record = NULL; | ||
| 195 | } | 197 | } |
| 196 | 198 | ||
| 197 | static int cpu_plot_event(struct graph_info *ginfo, | 199 | static int cpu_plot_event(struct graph_info *ginfo, |
| @@ -200,6 +202,7 @@ static int cpu_plot_event(struct graph_info *ginfo, | |||
| 200 | struct plot_info *info) | 202 | struct plot_info *info) |
| 201 | { | 203 | { |
| 202 | struct cpu_plot_info *cpu_info = plot->private; | 204 | struct cpu_plot_info *cpu_info = plot->private; |
| 205 | struct tracecmd_input *handle = ginfo->handle; | ||
| 203 | int sched_pid; | 206 | int sched_pid; |
| 204 | int orig_pid; | 207 | int orig_pid; |
| 205 | int is_sched_switch; | 208 | int is_sched_switch; |
| @@ -212,6 +215,11 @@ static int cpu_plot_event(struct graph_info *ginfo, | |||
| 212 | cpu = cpu_info->cpu; | 215 | cpu = cpu_info->cpu; |
| 213 | 216 | ||
| 214 | if (!record) { | 217 | if (!record) { |
| 218 | if (cpu_info->last_record) { | ||
| 219 | free_record(cpu_info->last_record); | ||
| 220 | cpu_info->last_record = NULL; | ||
| 221 | } | ||
| 222 | |||
| 215 | /* Finish a box if the last record was not idle */ | 223 | /* Finish a box if the last record was not idle */ |
| 216 | if (cpu_info->last_pid > 0) { | 224 | if (cpu_info->last_pid > 0) { |
| 217 | info->box = TRUE; | 225 | info->box = TRUE; |
| @@ -222,6 +230,30 @@ static int cpu_plot_event(struct graph_info *ginfo, | |||
| 222 | return 0; | 230 | return 0; |
| 223 | } | 231 | } |
| 224 | 232 | ||
| 233 | /* | ||
| 234 | * If last record is NULL, then it may exist off the | ||
| 235 | * viewable range. Search to see if one exists. | ||
| 236 | */ | ||
| 237 | if (!cpu_info->last_record) { | ||
| 238 | struct record *trecord; | ||
| 239 | |||
| 240 | trecord = tracecmd_read_prev(handle, record); | ||
| 241 | if (trecord) { | ||
| 242 | filter = filter_record(ginfo, trecord, | ||
| 243 | &orig_pid, &sched_pid, | ||
| 244 | &is_sched_switch); | ||
| 245 | cpu_info->last_pid = is_sched_switch ? sched_pid : orig_pid; | ||
| 246 | } | ||
| 247 | cpu_info->last_record = trecord; | ||
| 248 | /* We moved the cursor, put it back */ | ||
| 249 | trecord = tracecmd_read_data(handle, record->cpu); | ||
| 250 | free_record(trecord); | ||
| 251 | } | ||
| 252 | |||
| 253 | free_record(cpu_info->last_record); | ||
| 254 | cpu_info->last_record = record; | ||
| 255 | tracecmd_record_ref(record); | ||
| 256 | |||
| 225 | cpu = cpu_info->cpu; | 257 | cpu = cpu_info->cpu; |
| 226 | 258 | ||
| 227 | filter = filter_record(ginfo, record, &orig_pid, &sched_pid, &is_sched_switch); | 259 | filter = filter_record(ginfo, record, &orig_pid, &sched_pid, &is_sched_switch); |
diff --git a/trace-plot-task.c b/trace-plot-task.c index c8d0905..aac771e 100644 --- a/trace-plot-task.c +++ b/trace-plot-task.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | struct task_plot_info { | 29 | struct task_plot_info { |
| 30 | int pid; | 30 | int pid; |
| 31 | struct cpu_data *cpu_data; | 31 | struct cpu_data *cpu_data; |
| 32 | struct record **last_records; | ||
| 32 | unsigned long long last_time; | 33 | unsigned long long last_time; |
| 33 | unsigned long long wake_time; | 34 | unsigned long long wake_time; |
| 34 | unsigned long long display_wake_time; | 35 | unsigned long long display_wake_time; |
| @@ -104,26 +105,31 @@ static gboolean record_matches_pid(struct graph_info *ginfo, | |||
| 104 | return FALSE; | 105 | return FALSE; |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | static void set_cpus_to_time(struct graph_info *ginfo, unsigned long long time) | 108 | static void set_cpu_to_time(int cpu, struct graph_info *ginfo, unsigned long long time) |
| 108 | { | 109 | { |
| 109 | struct record *record; | 110 | struct record *record; |
| 110 | int cpu; | ||
| 111 | 111 | ||
| 112 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | 112 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time); |
| 113 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time); | ||
| 114 | 113 | ||
| 115 | while ((record = tracecmd_read_data(ginfo->handle, cpu))) { | 114 | while ((record = tracecmd_read_data(ginfo->handle, cpu))) { |
| 116 | if (record->ts >= time) | 115 | if (record->ts >= time) |
| 117 | break; | 116 | break; |
| 118 | 117 | ||
| 119 | free_record(record); | 118 | free_record(record); |
| 120 | } | ||
| 121 | if (record) { | ||
| 122 | tracecmd_set_cursor(ginfo->handle, cpu, record->offset); | ||
| 123 | free_record(record); | ||
| 124 | } else | ||
| 125 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time); | ||
| 126 | } | 119 | } |
| 120 | if (record) { | ||
| 121 | tracecmd_set_cursor(ginfo->handle, cpu, record->offset); | ||
| 122 | free_record(record); | ||
| 123 | } else | ||
| 124 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time); | ||
| 125 | } | ||
| 126 | |||
| 127 | static void set_cpus_to_time(struct graph_info *ginfo, unsigned long long time) | ||
| 128 | { | ||
| 129 | int cpu; | ||
| 130 | |||
| 131 | for (cpu = 0; cpu < ginfo->cpus; cpu++) | ||
| 132 | set_cpu_to_time(cpu, ginfo, time); | ||
| 127 | } | 133 | } |
| 128 | 134 | ||
| 129 | static int task_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot, | 135 | static int task_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot, |
| @@ -315,6 +321,8 @@ static void task_plot_start(struct graph_info *ginfo, struct graph_plot *plot, | |||
| 315 | { | 321 | { |
| 316 | struct task_plot_info *task_info = plot->private; | 322 | struct task_plot_info *task_info = plot->private; |
| 317 | 323 | ||
| 324 | memset(task_info->last_records, 0, sizeof(struct record *) * ginfo->cpus); | ||
| 325 | |||
| 318 | task_info->last_time = 0ULL; | 326 | task_info->last_time = 0ULL; |
| 319 | task_info->last_cpu = -1; | 327 | task_info->last_cpu = -1; |
| 320 | task_info->wake_time = 0ULL; | 328 | task_info->wake_time = 0ULL; |
| @@ -327,16 +335,22 @@ static int task_plot_event(struct graph_info *ginfo, | |||
| 327 | struct plot_info *info) | 335 | struct plot_info *info) |
| 328 | { | 336 | { |
| 329 | struct task_plot_info *task_info = plot->private; | 337 | struct task_plot_info *task_info = plot->private; |
| 338 | struct tracecmd_input *handle = ginfo->handle; | ||
| 330 | gboolean match; | 339 | gboolean match; |
| 331 | int sched_pid; | 340 | int sched_pid; |
| 332 | int rec_pid; | 341 | int rec_pid; |
| 333 | int is_wakeup; | 342 | int is_wakeup; |
| 334 | int is_sched; | 343 | int is_sched; |
| 335 | int pid; | 344 | int pid; |
| 345 | int cpu; | ||
| 336 | 346 | ||
| 337 | pid = task_info->pid; | 347 | pid = task_info->pid; |
| 338 | 348 | ||
| 339 | if (!record) { | 349 | if (!record) { |
| 350 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | ||
| 351 | free_record(task_info->last_records[cpu]); | ||
| 352 | task_info->last_records[cpu] = NULL; | ||
| 353 | } | ||
| 340 | /* no more records, finish a box if one was started */ | 354 | /* no more records, finish a box if one was started */ |
| 341 | if (task_info->last_cpu >= 0) { | 355 | if (task_info->last_cpu >= 0) { |
| 342 | info->box = TRUE; | 356 | info->box = TRUE; |
| @@ -350,14 +364,85 @@ static int task_plot_event(struct graph_info *ginfo, | |||
| 350 | match = record_matches_pid(ginfo, record, pid, &rec_pid, | 364 | match = record_matches_pid(ginfo, record, pid, &rec_pid, |
| 351 | &sched_pid, &is_sched, &is_wakeup); | 365 | &sched_pid, &is_sched, &is_wakeup); |
| 352 | 366 | ||
| 353 | if (!match && record->cpu != task_info->last_cpu) | 367 | |
| 368 | if (!match && record->cpu != task_info->last_cpu) { | ||
| 369 | if (!task_info->last_records[record->cpu]) { | ||
| 370 | task_info->last_records[record->cpu] = record; | ||
| 371 | tracecmd_record_ref(record); | ||
| 372 | } | ||
| 354 | return 0; | 373 | return 0; |
| 374 | } | ||
| 355 | 375 | ||
| 356 | if (match) { | 376 | if (match) { |
| 357 | info->line = TRUE; | 377 | info->line = TRUE; |
| 358 | info->lcolor = hash_pid(rec_pid); | 378 | info->lcolor = hash_pid(rec_pid); |
| 359 | info->ltime = record->ts; | 379 | info->ltime = record->ts; |
| 360 | 380 | ||
| 381 | /* | ||
| 382 | * Is this our first match? | ||
| 383 | * | ||
| 384 | * If last record is NULL, then it may exist off the | ||
| 385 | * viewable range. Search to see if one exists, and if | ||
| 386 | * it is the record we want to match. | ||
| 387 | */ | ||
| 388 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | ||
| 389 | struct record *trecord, *t2record; | ||
| 390 | struct record *saved; | ||
| 391 | int this_cpu = record->cpu; | ||
| 392 | int tsched_pid; | ||
| 393 | int tpid; | ||
| 394 | int tis_wakeup; | ||
| 395 | int tis_sched; | ||
| 396 | |||
| 397 | if (task_info->last_records[cpu]) | ||
| 398 | continue; | ||
| 399 | |||
| 400 | if (cpu == this_cpu) { | ||
| 401 | static int once; | ||
| 402 | |||
| 403 | trecord = tracecmd_read_prev(handle, record); | ||
| 404 | /* Set cpu cursor back to what it was */ | ||
| 405 | saved = tracecmd_read_data(handle, cpu); | ||
| 406 | if (!once && saved->offset != record->offset) { | ||
| 407 | once++; | ||
| 408 | warning("failed to reset cursor!"); | ||
| 409 | } | ||
| 410 | free_record(saved); | ||
| 411 | } else { | ||
| 412 | static int once; | ||
| 413 | |||
| 414 | saved = tracecmd_peek_data(handle, cpu); | ||
| 415 | set_cpu_to_time(cpu, ginfo, record->ts); | ||
| 416 | t2record = tracecmd_read_data(handle, cpu); | ||
| 417 | trecord = tracecmd_read_prev(handle, t2record); | ||
| 418 | free_record(t2record); | ||
| 419 | /* reset cursor back to what it was */ | ||
| 420 | if (saved) | ||
| 421 | tracecmd_set_cursor(handle, cpu, saved->offset); | ||
| 422 | else { | ||
| 423 | saved = tracecmd_read_data(handle, cpu); | ||
| 424 | if (!once && saved) { | ||
| 425 | once++; | ||
| 426 | warning("failed to reset cursor to end!"); | ||
| 427 | } | ||
| 428 | } | ||
| 429 | } | ||
| 430 | if (!trecord) | ||
| 431 | continue; | ||
| 432 | |||
| 433 | if (record_matches_pid(ginfo, trecord, pid, &tpid, | ||
| 434 | &tsched_pid, &tis_sched, &tis_wakeup) && | ||
| 435 | !tis_wakeup && | ||
| 436 | (!is_sched || (is_sched && sched_pid == pid))) { | ||
| 437 | task_info->last_records[cpu] = trecord; | ||
| 438 | task_info->last_cpu = trecord->cpu; | ||
| 439 | task_info->last_time = trecord->ts; | ||
| 440 | break; | ||
| 441 | } | ||
| 442 | |||
| 443 | free_record(trecord); | ||
| 444 | } | ||
| 445 | |||
| 361 | if (is_wakeup) { | 446 | if (is_wakeup) { |
| 362 | /* Wake up but not task */ | 447 | /* Wake up but not task */ |
| 363 | info->ltime = hash_pid(rec_pid); | 448 | info->ltime = hash_pid(rec_pid); |
| @@ -424,6 +509,12 @@ static int task_plot_event(struct graph_info *ginfo, | |||
| 424 | return 1; | 509 | return 1; |
| 425 | } | 510 | } |
| 426 | 511 | ||
| 512 | cpu = record->cpu; | ||
| 513 | |||
| 514 | if (!task_info->last_records[cpu]) { | ||
| 515 | free_record(task_info->last_records[cpu]); | ||
| 516 | task_info->last_records[cpu] = record; | ||
| 517 | } | ||
| 427 | /* not a match, and on the last CPU, scheduled out? */ | 518 | /* not a match, and on the last CPU, scheduled out? */ |
| 428 | if (task_info->last_cpu >= 0) { | 519 | if (task_info->last_cpu >= 0) { |
| 429 | info->box = TRUE; | 520 | info->box = TRUE; |
| @@ -622,6 +713,7 @@ void task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) | |||
| 622 | 713 | ||
| 623 | trace_graph_plot_remove_all_recs(ginfo, plot); | 714 | trace_graph_plot_remove_all_recs(ginfo, plot); |
| 624 | 715 | ||
| 716 | free(task_info->last_records); | ||
| 625 | free(task_info); | 717 | free(task_info); |
| 626 | } | 718 | } |
| 627 | 719 | ||
| @@ -740,6 +832,8 @@ void graph_plot_init_tasks(struct graph_info *ginfo) | |||
| 740 | } | 832 | } |
| 741 | 833 | ||
| 742 | task_info = malloc_or_die(sizeof(*task_info)); | 834 | task_info = malloc_or_die(sizeof(*task_info)); |
| 835 | task_info->last_records = | ||
| 836 | malloc_or_die(sizeof(struct record *) * ginfo->cpus); | ||
| 743 | task_info->pid = pid; | 837 | task_info->pid = pid; |
| 744 | 838 | ||
| 745 | snprintf(label, 100, "TASK %d", pid); | 839 | snprintf(label, 100, "TASK %d", pid); |
| @@ -756,6 +850,8 @@ void graph_plot_task(struct graph_info *ginfo, int pid, int pos) | |||
| 756 | int len; | 850 | int len; |
| 757 | 851 | ||
| 758 | task_info = malloc_or_die(sizeof(*task_info)); | 852 | task_info = malloc_or_die(sizeof(*task_info)); |
| 853 | task_info->last_records = | ||
| 854 | malloc_or_die(sizeof(struct record *) * ginfo->cpus); | ||
| 759 | task_info->pid = pid; | 855 | task_info->pid = pid; |
| 760 | comm = pevent_data_comm_from_pid(ginfo->pevent, pid); | 856 | comm = pevent_data_comm_from_pid(ginfo->pevent, pid); |
| 761 | 857 | ||
