diff options
author | Balint Reczey <balint@balintreczey.hu> | 2014-06-26 23:33:32 +0200 |
---|---|---|
committer | Balint Reczey <balint@balintreczey.hu> | 2014-07-01 09:24:05 +0000 |
commit | 524583298beb671f43e972476693866754d38a38 (patch) | |
tree | f97421171969bbaa5d718e3c97fddcc8c7fd73a2 /ui/gtk | |
parent | eb239946c6faab7a7578021d0ce7b5efe73bc46b (diff) |
GTK: Unlimited, dynamically allocated IO Graph
Bug: 8460
Change-Id: Id9aad3f5f69bee9e5a62601ecac28a6a7019e623
Reviewed-on: https://code.wireshark.org/review/2672
Reviewed-by: Evan Huus <eapache@gmail.com>
Reviewed-by: Graham Bloice <graham.bloice@trihedral.com>
Reviewed-by: Balint Reczey <balint@balintreczey.hu>
Diffstat (limited to 'ui/gtk')
-rw-r--r-- | ui/gtk/io_stat.c | 102 |
1 files changed, 44 insertions, 58 deletions
diff --git a/ui/gtk/io_stat.c b/ui/gtk/io_stat.c index 9ecd671339..1e12746bc7 100644 --- a/ui/gtk/io_stat.c +++ b/ui/gtk/io_stat.c @@ -146,10 +146,9 @@ typedef struct _io_stat_calc_type_t { } io_stat_calc_type_t; #endif -#define NUM_IO_ITEMS 100000 typedef struct _io_stat_graph_t { struct _io_stat_t *io; - io_graph_item_t items[NUM_IO_ITEMS]; + io_graph_item_t *items; int plot_style; gboolean display; GtkWidget *display_button; @@ -174,6 +173,7 @@ typedef struct _io_stat_t { guint32 last_interval; /* the last *displayed* interval */ guint32 max_interval; /* the maximum interval based on the capture duration */ guint32 num_items; /* total number of items in all intervals (zero relative) */ + guint32 space_items; /* space for items allocated */ guint32 left_x_border; guint32 right_x_border; gboolean view_as_time; @@ -220,7 +220,7 @@ io_stat_reset(io_stat_t *io) io->needs_redraw = TRUE; for (i=0; i<MAX_GRAPHS; i++) { - reset_io_graph_items((io_graph_item_t *)io->graphs[i].items, NUM_IO_ITEMS); + reset_io_graph_items(io->graphs[i].items, io->num_items); } io->last_interval = 0xffffffff; io->max_interval = 0; @@ -242,9 +242,9 @@ static gboolean tap_iostat_packet(void *g, packet_info *pinfo, epan_dissect_t *edt, const void *dummy _U_) { io_stat_graph_t *graph = (io_stat_graph_t *)g; - io_stat_t *io; + io_stat_t *io = graph->io; epan_dissect_t *adv_edt = NULL; - int idx; + unsigned int idx; /* we sometimes get called when the graph is disabled. this is a bug since the tap listener should be removed first */ @@ -252,20 +252,43 @@ tap_iostat_packet(void *g, packet_info *pinfo, epan_dissect_t *edt, const void * return FALSE; } - io = graph->io; /* Point up to the parent io_stat_t struct */ io->needs_redraw = TRUE; - idx = get_io_graph_index(pinfo, io->interval); - - /* some sanity checks */ - if ((idx < 0) || (idx >= NUM_IO_ITEMS)) { - io->num_items = NUM_IO_ITEMS-1; - return FALSE; + { + int idx_signed; + idx_signed = get_io_graph_index(pinfo, io->interval); + + /* some sanity checks */ + if (idx_signed < 0) { + return FALSE; + } else { + idx = idx_signed; + } } /* update num_items */ - if ((guint32)idx > io->num_items) { - io->num_items = (guint32) idx; + if (idx + 1 > io->num_items) { + if (idx + 1 > io->space_items) { + /* reallocate graphs */ + const gsize new_size = exp2(log2(idx + 1) + 1); + if (io->space_items == 0) { + /* nothing allocated yet */ + int i; + for (i = 0; i < MAX_GRAPHS; i++) { + io->graphs[i].items = (io_graph_item_t *)g_malloc(sizeof(io->graphs[i].items[0]) * new_size); + reset_io_graph_items(io->graphs[i].items, new_size); + } + } else { + /* resize */ + int i; + for (i = 0; i < MAX_GRAPHS; i++) { + io->graphs[i].items = (io_graph_item_t *)g_realloc(io->graphs[i].items, sizeof(io->graphs[i].items[0]) * new_size); + reset_io_graph_items(&io->graphs[i].items[io->space_items], new_size - io->space_items); + } + } + io->space_items = new_size; + } + io->num_items = idx + 1; } /* set start time */ @@ -278,7 +301,7 @@ tap_iostat_packet(void *g, packet_info *pinfo, epan_dissect_t *edt, const void * adv_edt = edt; } - if (!update_io_graph_item((io_graph_item_t*) graph->items, idx, pinfo, adv_edt, graph->hf_index, CALC_TYPE_TO_ITEM_UNIT(graph->calc_type), io->interval)) { + if (!update_io_graph_item(graph->items, idx, pinfo, adv_edt, graph->hf_index, CALC_TYPE_TO_ITEM_UNIT(graph->calc_type), io->interval)) { return FALSE; } @@ -294,7 +317,9 @@ get_it_value(io_stat_t *io, int graph, int idx) guint32 interval; g_assert(graph < MAX_GRAPHS); - g_assert(idx < NUM_IO_ITEMS); + if (((guint)idx > io->num_items + 1) || (0 == io->num_items)) { + return 0; + } it = &io->graphs[graph].items[idx]; @@ -510,7 +535,6 @@ io_stat_draw(io_stat_t *io) GtkAllocation widget_alloc; /* new variables */ - guint32 num_time_intervals; /* number of intervals relative to 1 */ guint64 max_value; /* max value of seen data */ guint32 max_y; /* max value of the Y scale */ gboolean draw_y_as_time; @@ -530,28 +554,6 @@ io_stat_draw(io_stat_t *io) ((cfile.elapsed_time.nsecs+500000)/1000000) + io->interval); io->max_interval = (io->max_interval / io->interval) * io->interval; - if (io->max_interval >= NUM_IO_ITEMS * io->interval) { - /* XXX: Truncate the graph if it covers too much real time, as - * otherwise we crash later trying to make the graph too wide. There's - * no good way of warning the user, since this gets recalculated a - * lot and any dialogue we pop up would spawn 100+ times when scrolling. - * - * Should at least stop us from crashing in: - * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8583 - */ - io->max_interval = (NUM_IO_ITEMS - 1) * io->interval; - } - /* - * Find the length of the intervals we have data for - * so we know how large arrays we need to malloc() - */ - num_time_intervals = io->num_items+1; - - /* XXX move this check to _packet() */ - if (num_time_intervals > NUM_IO_ITEMS) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "IO-Stat error. There are too many entries, bailing out"); - return; - } /* * find the max value so we can autoscale the y axis @@ -563,7 +565,7 @@ io_stat_draw(io_stat_t *io) if (!io->graphs[i].display) { continue; } - for (idx=0; (guint32)(idx) < num_time_intervals; idx++) { + for (idx=0; (guint32)(idx) < io->num_items; idx++) { guint64 val; val = get_it_value(io, i, idx); @@ -680,24 +682,6 @@ io_stat_draw(io_stat_t *io) draw_width = io->surface_width-io->right_x_border - io->left_x_border; draw_height = io->surface_height-top_y_border - bottom_y_border; - /* - * Add a warning if too many entries - */ - if (num_time_intervals >= NUM_IO_ITEMS-1) { - g_snprintf (label_string, sizeof(label_string), "Warning: Graph limited to %d entries", NUM_IO_ITEMS); - pango_layout_set_text(layout, label_string, -1); - -#if GTK_CHECK_VERSION(2,22,0) - cr = cairo_create (io->surface); -#else - cr = gdk_cairo_create (io->pixmap); -#endif - cairo_move_to (cr, 5, io->surface_height-bottom_y_border-draw_height-label_height/2); - pango_cairo_show_layout (cr, layout); - cairo_destroy (cr); - cr = NULL; - } - /* Draw the y axis and labels * (we always draw the y scale with 11 ticks along the axis) */ @@ -1199,6 +1183,7 @@ iostat_init(const char *opt_arg _U_, void* userdata _U_) io->last_interval = 0xffffffff; io->max_interval = 0; io->num_items = 0; + io->space_items = 0; io->left_x_border = 0; io->right_x_border = 500; io->view_as_time = FALSE; @@ -1278,6 +1263,7 @@ draw_area_destroy_cb(GtkWidget *widget _U_, gpointer user_data) g_free(io->graphs[i].args); io->graphs[i].args = NULL; } + g_free(io->graphs[i].items); } g_free(io); |