diff options
| -rw-r--r-- | trace-graph.c | 103 | ||||
| -rw-r--r-- | trace-graph.h | 16 |
2 files changed, 74 insertions, 45 deletions
diff --git a/trace-graph.c b/trace-graph.c index 6e67bd7..6971ec5 100644 --- a/trace-graph.c +++ b/trace-graph.c | |||
| @@ -57,11 +57,6 @@ | |||
| 57 | #define CPU_LABEL(cpu) (CPU_TOP(cpu)) | 57 | #define CPU_LABEL(cpu) (CPU_TOP(cpu)) |
| 58 | #define CPU_X 5 | 58 | #define CPU_X 5 |
| 59 | 59 | ||
| 60 | static gint ftrace_sched_switch_id = -1; | ||
| 61 | static gint event_sched_switch_id = -1; | ||
| 62 | static gint event_wakeup_id = -1; | ||
| 63 | static gint event_wakeup_new_id = -1; | ||
| 64 | |||
| 65 | static gint largest_cpu_label = 0; | 60 | static gint largest_cpu_label = 0; |
| 66 | 61 | ||
| 67 | static void redraw_pixmap_backend(struct graph_info *ginfo); | 62 | static void redraw_pixmap_backend(struct graph_info *ginfo); |
| @@ -87,6 +82,31 @@ static void print_time(unsigned long long time) | |||
| 87 | printf("%lu.%06lu", sec, usec); | 82 | printf("%lu.%06lu", sec, usec); |
| 88 | } | 83 | } |
| 89 | 84 | ||
| 85 | static void init_event_cache(struct graph_info *ginfo) | ||
| 86 | { | ||
| 87 | ginfo->ftrace_sched_switch_id = -1; | ||
| 88 | ginfo->event_sched_switch_id = -1; | ||
| 89 | ginfo->event_wakeup_id = -1; | ||
| 90 | ginfo->event_wakeup_new_id = -1; | ||
| 91 | |||
| 92 | ginfo->event_pid_field = NULL; | ||
| 93 | ginfo->event_comm_field = NULL; | ||
| 94 | ginfo->ftrace_pid_field = NULL; | ||
| 95 | ginfo->ftrace_comm_field = NULL; | ||
| 96 | |||
| 97 | ginfo->wakeup_pid_field = NULL; | ||
| 98 | ginfo->wakeup_success_field = NULL; | ||
| 99 | ginfo->wakeup_new_pid_field = NULL; | ||
| 100 | ginfo->wakeup_new_success_field = NULL; | ||
| 101 | |||
| 102 | /* | ||
| 103 | * The first time reading the through the list | ||
| 104 | * test the sched_switch for comms that did not make | ||
| 105 | * it into the pevent command line list. | ||
| 106 | */ | ||
| 107 | ginfo->read_comms = TRUE; | ||
| 108 | } | ||
| 109 | |||
| 90 | struct filter_task_item * | 110 | struct filter_task_item * |
| 91 | trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid) | 111 | trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid) |
| 92 | { | 112 | { |
| @@ -721,16 +741,12 @@ static int check_sched_wakeup(struct graph_info *ginfo, | |||
| 721 | struct record *record, | 741 | struct record *record, |
| 722 | gint *pid) | 742 | gint *pid) |
| 723 | { | 743 | { |
| 724 | static struct format_field *wakeup_pid_field; | ||
| 725 | static struct format_field *wakeup_success_field; | ||
| 726 | static struct format_field *wakeup_new_pid_field; | ||
| 727 | static struct format_field *wakeup_new_success_field; | ||
| 728 | struct event_format *event; | 744 | struct event_format *event; |
| 729 | unsigned long long val; | 745 | unsigned long long val; |
| 730 | gboolean found; | 746 | gboolean found; |
| 731 | gint id; | 747 | gint id; |
| 732 | 748 | ||
| 733 | if (event_wakeup_id < 0) { | 749 | if (ginfo->event_wakeup_id < 0) { |
| 734 | 750 | ||
| 735 | found = FALSE; | 751 | found = FALSE; |
| 736 | 752 | ||
| @@ -738,9 +754,9 @@ static int check_sched_wakeup(struct graph_info *ginfo, | |||
| 738 | "sched", "sched_wakeup"); | 754 | "sched", "sched_wakeup"); |
| 739 | if (event) { | 755 | if (event) { |
| 740 | found = TRUE; | 756 | found = TRUE; |
| 741 | event_wakeup_id = event->id; | 757 | ginfo->event_wakeup_id = event->id; |
| 742 | wakeup_pid_field = pevent_find_field(event, "pid"); | 758 | ginfo->wakeup_pid_field = pevent_find_field(event, "pid"); |
| 743 | wakeup_success_field = pevent_find_field(event, "success"); | 759 | ginfo->wakeup_success_field = pevent_find_field(event, "success"); |
| 744 | } | 760 | } |
| 745 | 761 | ||
| 746 | 762 | ||
| @@ -748,9 +764,9 @@ static int check_sched_wakeup(struct graph_info *ginfo, | |||
| 748 | "sched", "sched_wakeup_new"); | 764 | "sched", "sched_wakeup_new"); |
| 749 | if (event) { | 765 | if (event) { |
| 750 | found = TRUE; | 766 | found = TRUE; |
| 751 | event_wakeup_new_id = event->id; | 767 | ginfo->event_wakeup_new_id = event->id; |
| 752 | wakeup_new_pid_field = pevent_find_field(event, "pid"); | 768 | ginfo->wakeup_new_pid_field = pevent_find_field(event, "pid"); |
| 753 | wakeup_new_success_field = pevent_find_field(event, "success"); | 769 | ginfo->wakeup_new_success_field = pevent_find_field(event, "success"); |
| 754 | } | 770 | } |
| 755 | if (!found) | 771 | if (!found) |
| 756 | return 0; | 772 | return 0; |
| @@ -758,23 +774,23 @@ static int check_sched_wakeup(struct graph_info *ginfo, | |||
| 758 | 774 | ||
| 759 | id = pevent_data_type(ginfo->pevent, record); | 775 | id = pevent_data_type(ginfo->pevent, record); |
| 760 | 776 | ||
| 761 | if (id == event_wakeup_id) { | 777 | if (id == ginfo->event_wakeup_id) { |
| 762 | /* We only want those that actually woke up the task */ | 778 | /* We only want those that actually woke up the task */ |
| 763 | pevent_read_number_field(wakeup_success_field, record->data, &val); | 779 | pevent_read_number_field(ginfo->wakeup_success_field, record->data, &val); |
| 764 | if (!val) | 780 | if (!val) |
| 765 | return 0; | 781 | return 0; |
| 766 | pevent_read_number_field(wakeup_pid_field, record->data, &val); | 782 | pevent_read_number_field(ginfo->wakeup_pid_field, record->data, &val); |
| 767 | if (pid) | 783 | if (pid) |
| 768 | *pid = val; | 784 | *pid = val; |
| 769 | return 1; | 785 | return 1; |
| 770 | } | 786 | } |
| 771 | 787 | ||
| 772 | if (id == event_wakeup_new_id) { | 788 | if (id == ginfo->event_wakeup_new_id) { |
| 773 | /* We only want those that actually woke up the task */ | 789 | /* We only want those that actually woke up the task */ |
| 774 | pevent_read_number_field(wakeup_new_success_field, record->data, &val); | 790 | pevent_read_number_field(ginfo->wakeup_new_success_field, record->data, &val); |
| 775 | if (!val) | 791 | if (!val) |
| 776 | return 0; | 792 | return 0; |
| 777 | pevent_read_number_field(wakeup_new_pid_field, record->data, &val); | 793 | pevent_read_number_field(ginfo->wakeup_new_pid_field, record->data, &val); |
| 778 | if (pid) | 794 | if (pid) |
| 779 | *pid = val; | 795 | *pid = val; |
| 780 | return 1; | 796 | return 1; |
| @@ -787,47 +803,43 @@ static int check_sched_switch(struct graph_info *ginfo, | |||
| 787 | struct record *record, | 803 | struct record *record, |
| 788 | gint *pid, const char **comm) | 804 | gint *pid, const char **comm) |
| 789 | { | 805 | { |
| 790 | static struct format_field *event_pid_field; | ||
| 791 | static struct format_field *event_comm_field; | ||
| 792 | static struct format_field *ftrace_pid_field; | ||
| 793 | static struct format_field *ftrace_comm_field; | ||
| 794 | unsigned long long val; | 806 | unsigned long long val; |
| 795 | struct event_format *event; | 807 | struct event_format *event; |
| 796 | gint id; | 808 | gint id; |
| 797 | 809 | ||
| 798 | if (event_sched_switch_id < 0) { | 810 | if (ginfo->event_sched_switch_id < 0) { |
| 799 | event = pevent_find_event_by_name(ginfo->pevent, | 811 | event = pevent_find_event_by_name(ginfo->pevent, |
| 800 | "sched", "sched_switch"); | 812 | "sched", "sched_switch"); |
| 801 | if (!event) | 813 | if (!event) |
| 802 | return 0; | 814 | return 0; |
| 803 | 815 | ||
| 804 | event_sched_switch_id = event->id; | 816 | ginfo->event_sched_switch_id = event->id; |
| 805 | event_pid_field = pevent_find_field(event, "next_pid"); | 817 | ginfo->event_pid_field = pevent_find_field(event, "next_pid"); |
| 806 | event_comm_field = pevent_find_field(event, "next_comm"); | 818 | ginfo->event_comm_field = pevent_find_field(event, "next_comm"); |
| 807 | 819 | ||
| 808 | event = pevent_find_event_by_name(ginfo->pevent, | 820 | event = pevent_find_event_by_name(ginfo->pevent, |
| 809 | "ftrace", "context_switch"); | 821 | "ftrace", "context_switch"); |
| 810 | if (event) { | 822 | if (event) { |
| 811 | ftrace_sched_switch_id = event->id; | 823 | ginfo->ftrace_sched_switch_id = event->id; |
| 812 | ftrace_pid_field = pevent_find_field(event, "next_pid"); | 824 | ginfo->ftrace_pid_field = pevent_find_field(event, "next_pid"); |
| 813 | ftrace_comm_field = pevent_find_field(event, "next_comm"); | 825 | ginfo->ftrace_comm_field = pevent_find_field(event, "next_comm"); |
| 814 | } | 826 | } |
| 815 | } | 827 | } |
| 816 | 828 | ||
| 817 | id = pevent_data_type(ginfo->pevent, record); | 829 | id = pevent_data_type(ginfo->pevent, record); |
| 818 | if (id == event_sched_switch_id) { | 830 | if (id == ginfo->event_sched_switch_id) { |
| 819 | pevent_read_number_field(event_pid_field, record->data, &val); | 831 | pevent_read_number_field(ginfo->event_pid_field, record->data, &val); |
| 820 | if (comm) | 832 | if (comm) |
| 821 | *comm = record->data + event_comm_field->offset; | 833 | *comm = record->data + ginfo->event_comm_field->offset; |
| 822 | if (pid) | 834 | if (pid) |
| 823 | *pid = val; | 835 | *pid = val; |
| 824 | return 1; | 836 | return 1; |
| 825 | } | 837 | } |
| 826 | 838 | ||
| 827 | if (id == ftrace_sched_switch_id) { | 839 | if (id == ginfo->ftrace_sched_switch_id) { |
| 828 | pevent_read_number_field(ftrace_pid_field, record->data, &val); | 840 | pevent_read_number_field(ginfo->ftrace_pid_field, record->data, &val); |
| 829 | if (comm) | 841 | if (comm) |
| 830 | *comm = record->data + ftrace_comm_field->offset; | 842 | *comm = record->data + ginfo->ftrace_comm_field->offset; |
| 831 | if (pid) | 843 | if (pid) |
| 832 | *pid = val; | 844 | *pid = val; |
| 833 | return 1; | 845 | return 1; |
| @@ -1409,7 +1421,7 @@ static void draw_event_label(struct graph_info *ginfo, gint cpu, | |||
| 1409 | } | 1421 | } |
| 1410 | 1422 | ||
| 1411 | static void draw_cpu(struct graph_info *ginfo, gint cpu, | 1423 | static void draw_cpu(struct graph_info *ginfo, gint cpu, |
| 1412 | gint new_width, int read_comms) | 1424 | gint new_width, gboolean read_comms) |
| 1413 | { | 1425 | { |
| 1414 | static PangoFontDescription *font; | 1426 | static PangoFontDescription *font; |
| 1415 | PangoLayout *layout; | 1427 | PangoLayout *layout; |
| @@ -1477,7 +1489,7 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
| 1477 | 1489 | ||
| 1478 | if (check_sched_switch(ginfo, record, &pid, &comm)) { | 1490 | if (check_sched_switch(ginfo, record, &pid, &comm)) { |
| 1479 | is_sched_switch = TRUE; | 1491 | is_sched_switch = TRUE; |
| 1480 | if (read_comms) { | 1492 | if (ginfo->read_comms) { |
| 1481 | /* | 1493 | /* |
| 1482 | * First time through, register any missing | 1494 | * First time through, register any missing |
| 1483 | * comm / pid mappings. | 1495 | * comm / pid mappings. |
| @@ -1675,7 +1687,6 @@ static void draw_timeline(struct graph_info *ginfo, gint width) | |||
| 1675 | static void draw_info(struct graph_info *ginfo, | 1687 | static void draw_info(struct graph_info *ginfo, |
| 1676 | gint new_width) | 1688 | gint new_width) |
| 1677 | { | 1689 | { |
| 1678 | static int read_comms = 1; | ||
| 1679 | gint cpu; | 1690 | gint cpu; |
| 1680 | 1691 | ||
| 1681 | if (!ginfo->handle) | 1692 | if (!ginfo->handle) |
| @@ -1690,9 +1701,9 @@ static void draw_info(struct graph_info *ginfo, | |||
| 1690 | 1701 | ||
| 1691 | 1702 | ||
| 1692 | for (cpu = 0; cpu < ginfo->cpus; cpu++) | 1703 | for (cpu = 0; cpu < ginfo->cpus; cpu++) |
| 1693 | draw_cpu(ginfo, cpu, new_width, read_comms); | 1704 | draw_cpu(ginfo, cpu, new_width, ginfo->read_comms); |
| 1694 | 1705 | ||
| 1695 | read_comms = 0; | 1706 | ginfo->read_comms = FALSE; |
| 1696 | } | 1707 | } |
| 1697 | 1708 | ||
| 1698 | void trace_graph_select_by_time(struct graph_info *ginfo, guint64 time) | 1709 | void trace_graph_select_by_time(struct graph_info *ginfo, guint64 time) |
| @@ -2035,6 +2046,8 @@ static int load_handle(struct graph_info *ginfo, | |||
| 2035 | ginfo->handle = handle; | 2046 | ginfo->handle = handle; |
| 2036 | tracecmd_ref(handle); | 2047 | tracecmd_ref(handle); |
| 2037 | 2048 | ||
| 2049 | init_event_cache(ginfo); | ||
| 2050 | |||
| 2038 | ginfo->pevent = tracecmd_get_pevent(handle); | 2051 | ginfo->pevent = tracecmd_get_pevent(handle); |
| 2039 | ginfo->cpus = tracecmd_cpus(handle); | 2052 | ginfo->cpus = tracecmd_cpus(handle); |
| 2040 | ginfo->all_events = TRUE; | 2053 | ginfo->all_events = TRUE; |
| @@ -2103,7 +2116,7 @@ trace_graph_create_with_callbacks(struct tracecmd_input *handle, | |||
| 2103 | 2116 | ||
| 2104 | ginfo->task_filter = filter_task_hash_alloc(); | 2117 | ginfo->task_filter = filter_task_hash_alloc(); |
| 2105 | ginfo->hide_tasks = filter_task_hash_alloc(); | 2118 | ginfo->hide_tasks = filter_task_hash_alloc(); |
| 2106 | 2119 | ||
| 2107 | ginfo->widget = gtk_hbox_new(FALSE, 0); | 2120 | ginfo->widget = gtk_hbox_new(FALSE, 0); |
| 2108 | gtk_widget_show(ginfo->widget); | 2121 | gtk_widget_show(ginfo->widget); |
| 2109 | 2122 | ||
diff --git a/trace-graph.h b/trace-graph.h index 7cfe0a2..fc4ea2c 100644 --- a/trace-graph.h +++ b/trace-graph.h | |||
| @@ -61,6 +61,22 @@ struct graph_info { | |||
| 61 | gint systems_size; | 61 | gint systems_size; |
| 62 | gint event_ids_size; | 62 | gint event_ids_size; |
| 63 | 63 | ||
| 64 | /* cache of event fields */ | ||
| 65 | gint ftrace_sched_switch_id; | ||
| 66 | gint event_sched_switch_id; | ||
| 67 | gint event_wakeup_id; | ||
| 68 | gint event_wakeup_new_id; | ||
| 69 | struct format_field *event_pid_field; | ||
| 70 | struct format_field *event_comm_field; | ||
| 71 | struct format_field *ftrace_pid_field; | ||
| 72 | struct format_field *ftrace_comm_field; | ||
| 73 | struct format_field *wakeup_pid_field; | ||
| 74 | struct format_field *wakeup_success_field; | ||
| 75 | struct format_field *wakeup_new_pid_field; | ||
| 76 | struct format_field *wakeup_new_success_field; | ||
| 77 | |||
| 78 | gboolean read_comms; /* Read all comms on first load */ | ||
| 79 | |||
| 64 | struct filter_task *task_filter; | 80 | struct filter_task *task_filter; |
| 65 | gint filter_task_selected; | 81 | gint filter_task_selected; |
| 66 | 82 | ||
