diff options
-rw-r--r-- | trace-plot-task.c | 146 |
1 files changed, 84 insertions, 62 deletions
diff --git a/trace-plot-task.c b/trace-plot-task.c index aac771e..f341493 100644 --- a/trace-plot-task.c +++ b/trace-plot-task.c | |||
@@ -329,13 +329,90 @@ static void task_plot_start(struct graph_info *ginfo, struct graph_plot *plot, | |||
329 | task_info->display_wake_time = 0ULL; | 329 | task_info->display_wake_time = 0ULL; |
330 | } | 330 | } |
331 | 331 | ||
332 | static void update_last_record(struct graph_info *ginfo, | ||
333 | struct task_plot_info *task_info, | ||
334 | struct record *record) | ||
335 | { | ||
336 | struct tracecmd_input *handle = ginfo->handle; | ||
337 | struct record *trecord, *t2record; | ||
338 | struct record *saved; | ||
339 | unsigned long long ts; | ||
340 | int sched_pid; | ||
341 | int pid; | ||
342 | int rec_pid; | ||
343 | int is_wakeup; | ||
344 | int is_sched; | ||
345 | int this_cpu; | ||
346 | int cpu; | ||
347 | |||
348 | pid = task_info->pid; | ||
349 | |||
350 | if (record) { | ||
351 | ts = record->ts; | ||
352 | this_cpu = record->cpu; | ||
353 | } else { | ||
354 | ts = ginfo->view_end_time; | ||
355 | this_cpu = -1; | ||
356 | } | ||
357 | |||
358 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | ||
359 | |||
360 | if (task_info->last_records[cpu]) | ||
361 | continue; | ||
362 | |||
363 | if (cpu == this_cpu) { | ||
364 | static int once; | ||
365 | |||
366 | trecord = tracecmd_read_prev(handle, record); | ||
367 | /* Set cpu cursor back to what it was */ | ||
368 | saved = tracecmd_read_data(handle, cpu); | ||
369 | if (!once && saved->offset != record->offset) { | ||
370 | once++; | ||
371 | warning("failed to reset cursor!"); | ||
372 | } | ||
373 | free_record(saved); | ||
374 | } else { | ||
375 | static int once; | ||
376 | |||
377 | saved = tracecmd_peek_data(handle, cpu); | ||
378 | set_cpu_to_time(cpu, ginfo, ts); | ||
379 | t2record = tracecmd_read_data(handle, cpu); | ||
380 | trecord = tracecmd_read_prev(handle, t2record); | ||
381 | free_record(t2record); | ||
382 | /* reset cursor back to what it was */ | ||
383 | if (saved) | ||
384 | tracecmd_set_cursor(handle, cpu, saved->offset); | ||
385 | else { | ||
386 | saved = tracecmd_read_data(handle, cpu); | ||
387 | if (!once && saved) { | ||
388 | once++; | ||
389 | warning("failed to reset cursor to end!"); | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | if (!trecord) | ||
394 | continue; | ||
395 | |||
396 | if (record_matches_pid(ginfo, trecord, pid, &rec_pid, | ||
397 | &sched_pid, &is_sched, &is_wakeup) && | ||
398 | !is_wakeup && | ||
399 | (!is_sched || (is_sched && sched_pid == pid))) { | ||
400 | task_info->last_records[cpu] = trecord; | ||
401 | task_info->last_cpu = trecord->cpu; | ||
402 | task_info->last_time = trecord->ts; | ||
403 | break; | ||
404 | } | ||
405 | |||
406 | free_record(trecord); | ||
407 | } | ||
408 | } | ||
409 | |||
332 | static int task_plot_event(struct graph_info *ginfo, | 410 | static int task_plot_event(struct graph_info *ginfo, |
333 | struct graph_plot *plot, | 411 | struct graph_plot *plot, |
334 | struct record *record, | 412 | struct record *record, |
335 | struct plot_info *info) | 413 | struct plot_info *info) |
336 | { | 414 | { |
337 | struct task_plot_info *task_info = plot->private; | 415 | struct task_plot_info *task_info = plot->private; |
338 | struct tracecmd_input *handle = ginfo->handle; | ||
339 | gboolean match; | 416 | gboolean match; |
340 | int sched_pid; | 417 | int sched_pid; |
341 | int rec_pid; | 418 | int rec_pid; |
@@ -347,10 +424,7 @@ static int task_plot_event(struct graph_info *ginfo, | |||
347 | pid = task_info->pid; | 424 | pid = task_info->pid; |
348 | 425 | ||
349 | if (!record) { | 426 | if (!record) { |
350 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | 427 | update_last_record(ginfo, task_info, record); |
351 | free_record(task_info->last_records[cpu]); | ||
352 | task_info->last_records[cpu] = NULL; | ||
353 | } | ||
354 | /* no more records, finish a box if one was started */ | 428 | /* no more records, finish a box if one was started */ |
355 | if (task_info->last_cpu >= 0) { | 429 | if (task_info->last_cpu >= 0) { |
356 | info->box = TRUE; | 430 | info->box = TRUE; |
@@ -358,6 +432,10 @@ static int task_plot_event(struct graph_info *ginfo, | |||
358 | info->bend = ginfo->view_end_time; | 432 | info->bend = ginfo->view_end_time; |
359 | info->bcolor = hash_cpu(task_info->last_cpu); | 433 | info->bcolor = hash_cpu(task_info->last_cpu); |
360 | } | 434 | } |
435 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | ||
436 | free_record(task_info->last_records[cpu]); | ||
437 | task_info->last_records[cpu] = NULL; | ||
438 | } | ||
361 | return 0; | 439 | return 0; |
362 | } | 440 | } |
363 | 441 | ||
@@ -385,63 +463,7 @@ static int task_plot_event(struct graph_info *ginfo, | |||
385 | * viewable range. Search to see if one exists, and if | 463 | * viewable range. Search to see if one exists, and if |
386 | * it is the record we want to match. | 464 | * it is the record we want to match. |
387 | */ | 465 | */ |
388 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | 466 | update_last_record(ginfo, task_info, record); |
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 | 467 | ||
446 | if (is_wakeup) { | 468 | if (is_wakeup) { |
447 | /* Wake up but not task */ | 469 | /* Wake up but not task */ |