summaryrefslogtreecommitdiff
path: root/ui/gtk/io_stat.c
diff options
context:
space:
mode:
authorBalint Reczey <balint@balintreczey.hu>2014-06-26 23:33:32 +0200
committerBalint Reczey <balint@balintreczey.hu>2014-07-01 09:24:05 +0000
commit524583298beb671f43e972476693866754d38a38 (patch)
treef97421171969bbaa5d718e3c97fddcc8c7fd73a2 /ui/gtk/io_stat.c
parenteb239946c6faab7a7578021d0ce7b5efe73bc46b (diff)
downloadwireshark-524583298beb671f43e972476693866754d38a38.tar.gz
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/io_stat.c')
-rw-r--r--ui/gtk/io_stat.c102
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);