diff options
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | trace-graph.c | 113 | ||||
| -rw-r--r-- | trace-graph.h | 25 | ||||
| -rw-r--r-- | trace-plot-cpu.c | 14 | ||||
| -rw-r--r-- | trace-plot.c | 63 |
5 files changed, 163 insertions, 55 deletions
| @@ -143,7 +143,8 @@ endef | |||
| 143 | TRACE_CMD_OBJS = trace-cmd.o trace-read.o trace-split.o | 143 | TRACE_CMD_OBJS = trace-cmd.o trace-read.o trace-split.o |
| 144 | TRACE_VIEW_OBJS = trace-view.o trace-view-store.o trace-filter.o trace-compat.o \ | 144 | TRACE_VIEW_OBJS = trace-view.o trace-view-store.o trace-filter.o trace-compat.o \ |
| 145 | trace-hash.o | 145 | trace-hash.o |
| 146 | TRACE_GRAPH_OBJS = trace-graph.o trace-compat.o trace-hash.o trace-filter.o | 146 | TRACE_GRAPH_OBJS = trace-graph.o trace-compat.o trace-hash.o trace-filter.o \ |
| 147 | trace-plot.o trace-plot-cpu.o | ||
| 147 | TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) | 148 | TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) |
| 148 | TRACE_GRAPH_MAIN_OBJS = trace-graph-main.o $(TRACE_GRAPH_OBJS) | 149 | TRACE_GRAPH_MAIN_OBJS = trace-graph-main.o $(TRACE_GRAPH_OBJS) |
| 149 | KERNEL_SHARK_OBJS = $(TRACE_VIEW_OBJS) $(TRACE_GRAPH_OBJS) kernel-shark.o | 150 | KERNEL_SHARK_OBJS = $(TRACE_VIEW_OBJS) $(TRACE_GRAPH_OBJS) kernel-shark.o |
diff --git a/trace-graph.c b/trace-graph.c index 77a1153..c16f313 100644 --- a/trace-graph.c +++ b/trace-graph.c | |||
| @@ -45,19 +45,19 @@ | |||
| 45 | 45 | ||
| 46 | #define MAX_WIDTH 10000 | 46 | #define MAX_WIDTH 10000 |
| 47 | 47 | ||
| 48 | #define CPU_SIZE 10 | 48 | #define PLOT_SIZE 10 |
| 49 | #define CPU_BOX_SIZE CPU_SIZE | 49 | #define PLOT_BOX_SIZE PLOT_SIZE |
| 50 | #define CPU_GIVE 2 | 50 | #define PLOT_GIVE 2 |
| 51 | #define CPU_LINE(cpu) (80 * (cpu) + 80 + CPU_SIZE) | 51 | #define PLOT_LINE(cpu) (80 * (cpu) + 80 + PLOT_SIZE) |
| 52 | #define CPU_TOP(cpu) (CPU_LINE(cpu) - CPU_SIZE * 2) | 52 | #define PLOT_TOP(cpu) (PLOT_LINE(cpu) - PLOT_SIZE * 2) |
| 53 | #define CPU_BOX_TOP(cpu) (CPU_LINE(cpu) - CPU_SIZE) | 53 | #define PLOT_BOX_TOP(cpu) (PLOT_LINE(cpu) - PLOT_SIZE) |
| 54 | #define CPU_BOTTOM(cpu) (CPU_LINE(cpu)-1) | 54 | #define PLOT_BOTTOM(cpu) (PLOT_LINE(cpu)-1) |
| 55 | #define CPU_BOX_BOTTOM(cpu) (CPU_LINE(cpu)) | 55 | #define PLOT_BOX_BOTTOM(cpu) (PLOT_LINE(cpu)) |
| 56 | #define CPU_SPACE(cpus) (80 * (cpus) + 80) | 56 | #define PLOT_SPACE(cpus) (80 * (cpus) + 80) |
| 57 | #define CPU_LABEL(cpu) (CPU_TOP(cpu)) | 57 | #define PLOT_LABEL(cpu) (PLOT_TOP(cpu)) |
| 58 | #define CPU_X 5 | 58 | #define PLOT_X 5 |
| 59 | 59 | ||
| 60 | static gint largest_cpu_label = 0; | 60 | static gint largest_plot_label = 0; |
| 61 | 61 | ||
| 62 | static void redraw_pixmap_backend(struct graph_info *ginfo); | 62 | static void redraw_pixmap_backend(struct graph_info *ginfo); |
| 63 | static int check_sched_switch(struct graph_info *ginfo, | 63 | static int check_sched_switch(struct graph_info *ginfo, |
| @@ -527,8 +527,8 @@ do_pop_up(GtkWidget *widget, GdkEventButton *event, gpointer data) | |||
| 527 | time = convert_x_to_time(ginfo, x); | 527 | time = convert_x_to_time(ginfo, x); |
| 528 | 528 | ||
| 529 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | 529 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { |
| 530 | if (y >= (CPU_TOP(cpu) - CPU_GIVE) && | 530 | if (y >= (PLOT_TOP(cpu) - PLOT_GIVE) && |
| 531 | y <= (CPU_BOTTOM(cpu) + CPU_GIVE)) { | 531 | y <= (PLOT_BOTTOM(cpu) + PLOT_GIVE)) { |
| 532 | record = find_record_on_cpu(ginfo, cpu, time); | 532 | record = find_record_on_cpu(ginfo, cpu, time); |
| 533 | break; | 533 | break; |
| 534 | } | 534 | } |
| @@ -746,7 +746,7 @@ static void print_rec_info(struct record *record, struct pevent *pevent, int cpu | |||
| 746 | trace_seq_do_printf(&s); | 746 | trace_seq_do_printf(&s); |
| 747 | } | 747 | } |
| 748 | 748 | ||
| 749 | #define CPU_BOARDER 5 | 749 | #define PLOT_BOARDER 5 |
| 750 | 750 | ||
| 751 | static int check_sched_wakeup(struct graph_info *ginfo, | 751 | static int check_sched_wakeup(struct graph_info *ginfo, |
| 752 | struct record *record, | 752 | struct record *record, |
| @@ -974,8 +974,8 @@ static void draw_cpu_info(struct graph_info *ginfo, gint cpu, gint x, gint y) | |||
| 974 | layout = gtk_widget_create_pango_layout(ginfo->draw, s.buffer); | 974 | layout = gtk_widget_create_pango_layout(ginfo->draw, s.buffer); |
| 975 | pango_layout_get_pixel_size(layout, &width, &height); | 975 | pango_layout_get_pixel_size(layout, &width, &height); |
| 976 | 976 | ||
| 977 | width += CPU_BOARDER * 2; | 977 | width += PLOT_BOARDER * 2; |
| 978 | height += CPU_BOARDER * 2; | 978 | height += PLOT_BOARDER * 2; |
| 979 | 979 | ||
| 980 | view_start = gtk_adjustment_get_value(ginfo->hadj); | 980 | view_start = gtk_adjustment_get_value(ginfo->hadj); |
| 981 | view_width = gtk_adjustment_get_page_size(ginfo->hadj); | 981 | view_width = gtk_adjustment_get_page_size(ginfo->hadj); |
| @@ -1010,7 +1010,7 @@ static void draw_cpu_info(struct graph_info *ginfo, gint cpu, gint x, gint y) | |||
| 1010 | width-1, height-1); | 1010 | width-1, height-1); |
| 1011 | 1011 | ||
| 1012 | gdk_draw_layout(pix, ginfo->draw->style->black_gc, | 1012 | gdk_draw_layout(pix, ginfo->draw->style->black_gc, |
| 1013 | CPU_BOARDER, CPU_BOARDER, layout); | 1013 | PLOT_BOARDER, PLOT_BOARDER, layout); |
| 1014 | gdk_draw_drawable(ginfo->draw->window, | 1014 | gdk_draw_drawable(ginfo->draw->window, |
| 1015 | ginfo->draw->style->fg_gc[GTK_WIDGET_STATE(ginfo->draw)], | 1015 | ginfo->draw->style->fg_gc[GTK_WIDGET_STATE(ginfo->draw)], |
| 1016 | pix, 0, 0, x, y, width, height); | 1016 | pix, 0, 0, x, y, width, height); |
| @@ -1053,8 +1053,8 @@ motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) | |||
| 1053 | } | 1053 | } |
| 1054 | 1054 | ||
| 1055 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | 1055 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { |
| 1056 | if (y >= (CPU_TOP(cpu) - CPU_GIVE) && | 1056 | if (y >= (PLOT_TOP(cpu) - PLOT_GIVE) && |
| 1057 | y <= (CPU_BOTTOM(cpu) + CPU_GIVE)) | 1057 | y <= (PLOT_BOTTOM(cpu) + PLOT_GIVE)) |
| 1058 | draw_cpu_info(ginfo, cpu, x, y); | 1058 | draw_cpu_info(ginfo, cpu, x, y); |
| 1059 | } | 1059 | } |
| 1060 | 1060 | ||
| @@ -1422,13 +1422,13 @@ static void draw_event_label(struct graph_info *ginfo, gint cpu, | |||
| 1422 | if (x < 0) | 1422 | if (x < 0) |
| 1423 | x = 1; | 1423 | x = 1; |
| 1424 | 1424 | ||
| 1425 | y = (CPU_TOP(cpu) - text_height + 5); | 1425 | y = (PLOT_TOP(cpu) - text_height + 5); |
| 1426 | gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc, | 1426 | gdk_draw_layout(ginfo->curr_pixmap, ginfo->draw->style->black_gc, |
| 1427 | x, y, layout); | 1427 | x, y, layout); |
| 1428 | 1428 | ||
| 1429 | 1429 | ||
| 1430 | gdk_draw_line(ginfo->curr_pixmap, ginfo->draw->style->black_gc, | 1430 | gdk_draw_line(ginfo->curr_pixmap, ginfo->draw->style->black_gc, |
| 1431 | p2, CPU_TOP(cpu) - 5, p2, CPU_TOP(cpu) - 1); | 1431 | p2, PLOT_TOP(cpu) - 5, p2, PLOT_TOP(cpu) - 1); |
| 1432 | 1432 | ||
| 1433 | g_object_unref(layout); | 1433 | g_object_unref(layout); |
| 1434 | } | 1434 | } |
| @@ -1438,7 +1438,7 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
| 1438 | { | 1438 | { |
| 1439 | static PangoFontDescription *font; | 1439 | static PangoFontDescription *font; |
| 1440 | PangoLayout *layout; | 1440 | PangoLayout *layout; |
| 1441 | gint height = CPU_LINE(cpu); | 1441 | gint height = PLOT_LINE(cpu); |
| 1442 | struct record *record; | 1442 | struct record *record; |
| 1443 | static GdkGC *gc; | 1443 | static GdkGC *gc; |
| 1444 | static gint width_16; | 1444 | static gint width_16; |
| @@ -1533,8 +1533,8 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
| 1533 | 1533 | ||
| 1534 | gdk_draw_rectangle(ginfo->curr_pixmap, gc, | 1534 | gdk_draw_rectangle(ginfo->curr_pixmap, gc, |
| 1535 | TRUE, | 1535 | TRUE, |
| 1536 | last_x, CPU_BOX_TOP(cpu), | 1536 | last_x, PLOT_BOX_TOP(cpu), |
| 1537 | x - last_x, CPU_BOX_SIZE); | 1537 | x - last_x, PLOT_BOX_SIZE); |
| 1538 | 1538 | ||
| 1539 | last_x = x; | 1539 | last_x = x; |
| 1540 | 1540 | ||
| @@ -1556,7 +1556,7 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
| 1556 | filter = graph_filter_on_event(ginfo, record); | 1556 | filter = graph_filter_on_event(ginfo, record); |
| 1557 | if (!filter) | 1557 | if (!filter) |
| 1558 | gdk_draw_line(ginfo->curr_pixmap, gc, | 1558 | gdk_draw_line(ginfo->curr_pixmap, gc, |
| 1559 | x, CPU_TOP(cpu), x, CPU_BOTTOM(cpu)); | 1559 | x, PLOT_TOP(cpu), x, PLOT_BOTTOM(cpu)); |
| 1560 | } | 1560 | } |
| 1561 | 1561 | ||
| 1562 | last_pid = pid; | 1562 | last_pid = pid; |
| @@ -1604,8 +1604,8 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
| 1604 | 1604 | ||
| 1605 | gdk_draw_rectangle(ginfo->curr_pixmap, gc, | 1605 | gdk_draw_rectangle(ginfo->curr_pixmap, gc, |
| 1606 | TRUE, | 1606 | TRUE, |
| 1607 | last_x, CPU_BOX_TOP(cpu), | 1607 | last_x, PLOT_BOX_TOP(cpu), |
| 1608 | x - last_x, CPU_BOX_SIZE); | 1608 | x - last_x, PLOT_BOX_SIZE); |
| 1609 | } | 1609 | } |
| 1610 | 1610 | ||
| 1611 | free_record(record); | 1611 | free_record(record); |
| @@ -1796,20 +1796,20 @@ void trace_graph_select_by_time(struct graph_info *ginfo, guint64 time) | |||
| 1796 | if (cpu == ginfo->cpus) | 1796 | if (cpu == ginfo->cpus) |
| 1797 | return; | 1797 | return; |
| 1798 | 1798 | ||
| 1799 | /* Make sure CPU is visible */ | 1799 | /* Make sure PLOT is visible */ |
| 1800 | vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(ginfo->scrollwin)); | 1800 | vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(ginfo->scrollwin)); |
| 1801 | view_start = gtk_adjustment_get_value(vadj); | 1801 | view_start = gtk_adjustment_get_value(vadj); |
| 1802 | view_width = gtk_adjustment_get_page_size(vadj); | 1802 | view_width = gtk_adjustment_get_page_size(vadj); |
| 1803 | 1803 | ||
| 1804 | if (CPU_TOP(cpu) > view_start && | 1804 | if (PLOT_TOP(cpu) > view_start && |
| 1805 | CPU_BOTTOM(cpu) < view_start + view_width) | 1805 | PLOT_BOTTOM(cpu) < view_start + view_width) |
| 1806 | return; | 1806 | return; |
| 1807 | 1807 | ||
| 1808 | if (CPU_TOP(cpu) < view_start) | 1808 | if (PLOT_TOP(cpu) < view_start) |
| 1809 | gtk_adjustment_set_value(vadj, CPU_TOP(cpu) - 5); | 1809 | gtk_adjustment_set_value(vadj, PLOT_TOP(cpu) - 5); |
| 1810 | 1810 | ||
| 1811 | if (CPU_BOTTOM(cpu) > view_start + view_width) | 1811 | if (PLOT_BOTTOM(cpu) > view_start + view_width) |
| 1812 | gtk_adjustment_set_value(vadj, (CPU_BOTTOM(cpu) - view_width) + 10); | 1812 | gtk_adjustment_set_value(vadj, (PLOT_BOTTOM(cpu) - view_width) + 10); |
| 1813 | } | 1813 | } |
| 1814 | 1814 | ||
| 1815 | static void graph_free_systems(struct graph_info *ginfo) | 1815 | static void graph_free_systems(struct graph_info *ginfo) |
| @@ -1978,44 +1978,44 @@ info_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) | |||
| 1978 | return FALSE; | 1978 | return FALSE; |
| 1979 | } | 1979 | } |
| 1980 | 1980 | ||
| 1981 | static void info_draw_cpu_label(struct graph_info *ginfo, gint cpu) | 1981 | static void info_draw_plot_label(struct graph_info *ginfo, gint i) |
| 1982 | { | 1982 | { |
| 1983 | PangoLayout *layout; | 1983 | PangoLayout *layout; |
| 1984 | gchar buf[BUFSIZ]; | ||
| 1985 | gint width, height; | 1984 | gint width, height; |
| 1985 | char *label; | ||
| 1986 | 1986 | ||
| 1987 | snprintf(buf, BUFSIZ, "CPU %d", cpu); | 1987 | label = ginfo->plot_array[i]->label; |
| 1988 | 1988 | ||
| 1989 | layout = gtk_widget_create_pango_layout(ginfo->info, buf); | 1989 | layout = gtk_widget_create_pango_layout(ginfo->info, label); |
| 1990 | pango_layout_get_pixel_size(layout, &width, &height); | 1990 | pango_layout_get_pixel_size(layout, &width, &height); |
| 1991 | width += 4; | 1991 | width += 4; |
| 1992 | 1992 | ||
| 1993 | if (width > largest_cpu_label) | 1993 | if (width > largest_plot_label) |
| 1994 | largest_cpu_label = width; | 1994 | largest_plot_label = width; |
| 1995 | gdk_draw_rectangle(ginfo->info_pixmap, | 1995 | gdk_draw_rectangle(ginfo->info_pixmap, |
| 1996 | ginfo->info->style->white_gc, | 1996 | ginfo->info->style->white_gc, |
| 1997 | TRUE, | 1997 | TRUE, |
| 1998 | CPU_X, CPU_LABEL(cpu)+4, | 1998 | PLOT_X, PLOT_LABEL(i)+4, |
| 1999 | width, height); | 1999 | width, height); |
| 2000 | gdk_draw_layout(ginfo->info_pixmap, | 2000 | gdk_draw_layout(ginfo->info_pixmap, |
| 2001 | ginfo->info->style->black_gc, | 2001 | ginfo->info->style->black_gc, |
| 2002 | CPU_X+ 2, CPU_LABEL(cpu) + 4, | 2002 | PLOT_X+ 2, PLOT_LABEL(i) + 4, |
| 2003 | layout); | 2003 | layout); |
| 2004 | g_object_unref(layout); | 2004 | g_object_unref(layout); |
| 2005 | } | 2005 | } |
| 2006 | 2006 | ||
| 2007 | static void info_draw_cpu_labels(struct graph_info *ginfo) | 2007 | static void info_draw_plot_labels(struct graph_info *ginfo) |
| 2008 | { | 2008 | { |
| 2009 | gint cpu; | 2009 | gint i; |
| 2010 | 2010 | ||
| 2011 | if (!ginfo->handle) | 2011 | if (!ginfo->handle) |
| 2012 | return; | 2012 | return; |
| 2013 | 2013 | ||
| 2014 | for (cpu = 0; cpu < ginfo->cpus; cpu++) | 2014 | for (i = 0; i < ginfo->plots; i++) |
| 2015 | info_draw_cpu_label(ginfo, cpu); | 2015 | info_draw_plot_label(ginfo, i); |
| 2016 | } | 2016 | } |
| 2017 | 2017 | ||
| 2018 | static void update_cpu_window(struct graph_info *ginfo) | 2018 | static void update_label_window(struct graph_info *ginfo) |
| 2019 | { | 2019 | { |
| 2020 | if (ginfo->info_pixmap) | 2020 | if (ginfo->info_pixmap) |
| 2021 | g_object_unref(ginfo->info_pixmap); | 2021 | g_object_unref(ginfo->info_pixmap); |
| @@ -2032,9 +2032,9 @@ static void update_cpu_window(struct graph_info *ginfo) | |||
| 2032 | ginfo->info->allocation.width, | 2032 | ginfo->info->allocation.width, |
| 2033 | ginfo->info->allocation.height); | 2033 | ginfo->info->allocation.height); |
| 2034 | 2034 | ||
| 2035 | info_draw_cpu_labels(ginfo); | 2035 | info_draw_plot_labels(ginfo); |
| 2036 | 2036 | ||
| 2037 | gtk_widget_set_size_request(ginfo->info, largest_cpu_label + 10, | 2037 | gtk_widget_set_size_request(ginfo->info, largest_plot_label + 10, |
| 2038 | ginfo->draw_height); | 2038 | ginfo->draw_height); |
| 2039 | } | 2039 | } |
| 2040 | 2040 | ||
| @@ -2043,7 +2043,7 @@ info_configure_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) | |||
| 2043 | { | 2043 | { |
| 2044 | struct graph_info *ginfo = data; | 2044 | struct graph_info *ginfo = data; |
| 2045 | 2045 | ||
| 2046 | update_cpu_window(ginfo); | 2046 | update_label_window(ginfo); |
| 2047 | 2047 | ||
| 2048 | return TRUE; | 2048 | return TRUE; |
| 2049 | } | 2049 | } |
| @@ -2091,6 +2091,9 @@ static int load_handle(struct graph_info *ginfo, | |||
| 2091 | if (!handle) | 2091 | if (!handle) |
| 2092 | return -1; | 2092 | return -1; |
| 2093 | 2093 | ||
| 2094 | trace_graph_plot_free(ginfo); | ||
| 2095 | trace_graph_plot_init(ginfo); | ||
| 2096 | |||
| 2094 | if (ginfo->handle) | 2097 | if (ginfo->handle) |
| 2095 | trace_graph_free_info(ginfo); | 2098 | trace_graph_free_info(ginfo); |
| 2096 | 2099 | ||
| @@ -2106,7 +2109,9 @@ static int load_handle(struct graph_info *ginfo, | |||
| 2106 | ginfo->start_time = -1ULL; | 2109 | ginfo->start_time = -1ULL; |
| 2107 | ginfo->end_time = 0; | 2110 | ginfo->end_time = 0; |
| 2108 | 2111 | ||
| 2109 | ginfo->draw_height = CPU_SPACE(ginfo->cpus); | 2112 | graph_plot_init_cpus(ginfo, ginfo->cpus); |
| 2113 | |||
| 2114 | ginfo->draw_height = PLOT_SPACE(ginfo->plots); | ||
| 2110 | 2115 | ||
| 2111 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | 2116 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { |
| 2112 | record = tracecmd_read_cpu_first(handle, cpu); | 2117 | record = tracecmd_read_cpu_first(handle, cpu); |
| @@ -2143,7 +2148,7 @@ int trace_graph_load_handle(struct graph_info *ginfo, | |||
| 2143 | if (load_handle(ginfo, handle) < 0) | 2148 | if (load_handle(ginfo, handle) < 0) |
| 2144 | return -1; | 2149 | return -1; |
| 2145 | 2150 | ||
| 2146 | update_cpu_window(ginfo); | 2151 | update_label_window(ginfo); |
| 2147 | redraw_graph(ginfo); | 2152 | redraw_graph(ginfo); |
| 2148 | 2153 | ||
| 2149 | return 0; | 2154 | return 0; |
diff --git a/trace-graph.h b/trace-graph.h index fc4ea2c..634707d 100644 --- a/trace-graph.h +++ b/trace-graph.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef _TRACE_GRAPH_H | 1 | #ifndef _TRACE_GRAPH_H |
| 2 | #define _TRACE_GRAPH_H | 2 | #define _TRACE_GRAPH_H |
| 3 | 3 | ||
| 4 | #include <gtk/gtk.h> | ||
| 4 | #include "trace-cmd.h" | 5 | #include "trace-cmd.h" |
| 5 | #include "trace-hash.h" | 6 | #include "trace-hash.h" |
| 6 | 7 | ||
| @@ -11,6 +12,16 @@ typedef void (graph_filter_cb)(struct graph_info *ginfo, | |||
| 11 | struct filter_task *task_filter, | 12 | struct filter_task *task_filter, |
| 12 | struct filter_task *hide_tasks); | 13 | struct filter_task *hide_tasks); |
| 13 | 14 | ||
| 15 | struct plot_callbacks { | ||
| 16 | void *private; | ||
| 17 | }; | ||
| 18 | |||
| 19 | struct graph_plot { | ||
| 20 | struct graph_plot *next; | ||
| 21 | char *label; | ||
| 22 | struct plot_callbacks *cb; | ||
| 23 | }; | ||
| 24 | |||
| 14 | struct graph_callbacks { | 25 | struct graph_callbacks { |
| 15 | graph_select_cb *select; | 26 | graph_select_cb *select; |
| 16 | graph_filter_cb *filter; | 27 | graph_filter_cb *filter; |
| @@ -20,6 +31,11 @@ struct graph_info { | |||
| 20 | struct tracecmd_input *handle; | 31 | struct tracecmd_input *handle; |
| 21 | struct pevent *pevent; | 32 | struct pevent *pevent; |
| 22 | gint cpus; | 33 | gint cpus; |
| 34 | |||
| 35 | gint plots; | ||
| 36 | struct graph_plot **plot_array; | ||
| 37 | struct graph_plot *plot_list; | ||
| 38 | |||
| 23 | GtkWidget *widget; /* Box to hold graph */ | 39 | GtkWidget *widget; /* Box to hold graph */ |
| 24 | GtkWidget *scrollwin; /* graph scroll window */ | 40 | GtkWidget *scrollwin; /* graph scroll window */ |
| 25 | GtkWidget *info_scrollwin; /* graph scroll window (for info widget) */ | 41 | GtkWidget *info_scrollwin; /* graph scroll window (for info widget) */ |
| @@ -134,4 +150,13 @@ void trace_graph_free_info(struct graph_info *ginfo); | |||
| 134 | int trace_graph_load_handle(struct graph_info *ginfo, | 150 | int trace_graph_load_handle(struct graph_info *ginfo, |
| 135 | struct tracecmd_input *handle); | 151 | struct tracecmd_input *handle); |
| 136 | 152 | ||
| 153 | /* plots */ | ||
| 154 | void trace_graph_plot_free(struct graph_info *ginfo); | ||
| 155 | void trace_graph_plot_init(struct graph_info *ginfo); | ||
| 156 | void trace_graph_plot_append(struct graph_info *ginfo, | ||
| 157 | const char *label, struct plot_callbacks *cb); | ||
| 158 | |||
| 159 | /* cpu plot */ | ||
| 160 | void graph_plot_init_cpus(struct graph_info *ginfo, int cpus); | ||
| 161 | |||
| 137 | #endif /* _TRACE_GRAPH_H */ | 162 | #endif /* _TRACE_GRAPH_H */ |
diff --git a/trace-plot-cpu.c b/trace-plot-cpu.c new file mode 100644 index 0000000..31b88f1 --- /dev/null +++ b/trace-plot-cpu.c | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | #include "trace-graph.h" | ||
| 2 | |||
| 3 | static struct plot_callbacks cpu_plot_cb; | ||
| 4 | |||
| 5 | void graph_plot_init_cpus(struct graph_info *ginfo, int cpus) | ||
| 6 | { | ||
| 7 | char label[100]; | ||
| 8 | int cpu; | ||
| 9 | |||
| 10 | for (cpu = 0; cpu < cpus; cpu++) { | ||
| 11 | snprintf(label, 100, "CPU %d", cpu); | ||
| 12 | trace_graph_plot_append(ginfo, label, &cpu_plot_cb); | ||
| 13 | } | ||
| 14 | } | ||
diff --git a/trace-plot.c b/trace-plot.c new file mode 100644 index 0000000..35d3352 --- /dev/null +++ b/trace-plot.c | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | #include <string.h> | ||
| 2 | #include "trace-graph.h" | ||
| 3 | |||
| 4 | void trace_graph_plot_free(struct graph_info *ginfo) | ||
| 5 | { | ||
| 6 | struct graph_plot *plot; | ||
| 7 | |||
| 8 | while (ginfo->plot_list) { | ||
| 9 | plot = ginfo->plot_list; | ||
| 10 | ginfo->plot_list = plot->next; | ||
| 11 | free(plot); | ||
| 12 | } | ||
| 13 | |||
| 14 | if (ginfo->plot_array) { | ||
| 15 | free(ginfo->plot_array); | ||
| 16 | ginfo->plot_array = NULL; | ||
| 17 | }; | ||
| 18 | |||
| 19 | ginfo->plots = 0; | ||
| 20 | } | ||
| 21 | |||
| 22 | void trace_graph_plot_init(struct graph_info *ginfo) | ||
| 23 | { | ||
| 24 | ginfo->plots = 0; | ||
| 25 | ginfo->plot_array = NULL; | ||
| 26 | ginfo->plot_list = NULL; | ||
| 27 | } | ||
| 28 | |||
| 29 | void trace_graph_plot_append(struct graph_info *ginfo, | ||
| 30 | const char *label, struct plot_callbacks *cb) | ||
| 31 | { | ||
| 32 | struct graph_plot *plot; | ||
| 33 | char *name; | ||
| 34 | |||
| 35 | name = strdup(label); | ||
| 36 | if (!name) | ||
| 37 | die("Unable to allocate label"); | ||
| 38 | |||
| 39 | plot = malloc_or_die(sizeof(*plot)); | ||
| 40 | memset(plot, 0, sizeof(*plot)); | ||
| 41 | |||
| 42 | plot->label = name; | ||
| 43 | plot->cb = cb; | ||
| 44 | |||
| 45 | plot->next = ginfo->plot_list; | ||
| 46 | ginfo->plot_list = plot; | ||
| 47 | |||
| 48 | if (!ginfo->plots) { | ||
| 49 | ginfo->plot_array = malloc_or_die(sizeof(ginfo->plot_array[0])); | ||
| 50 | ginfo->plot_array[0] = plot; | ||
| 51 | } else { | ||
| 52 | ginfo->plot_array = realloc(ginfo->plot_array, | ||
| 53 | sizeof(ginfo->plot_array[0]) * | ||
| 54 | (ginfo->plots + 1)); | ||
| 55 | |||
| 56 | if (!ginfo->plot_array) | ||
| 57 | die("unable to resize plot array"); | ||
| 58 | |||
| 59 | ginfo->plot_array[ginfo->plots] = plot; | ||
| 60 | } | ||
| 61 | |||
| 62 | ginfo->plots++; | ||
| 63 | } | ||
