gfio: add completion percentile bar graph
Mostly just to display the bar graph for now, we'll change this to
be the latency buckets instead.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/gfio.c b/gfio.c
index 90d968a..30e0d6c 100644
--- a/gfio.c
+++ b/gfio.c
@@ -175,6 +175,7 @@
struct gfio_client *client;
int nr_job_files;
char **job_files;
+ struct graph *clat_graph;
};
struct gfio_client {
@@ -545,6 +546,29 @@
ui->log_tree = tree_view;
}
+static struct graph *setup_clat_graph(char *title, unsigned int *ovals,
+ fio_fp64_t *plist,
+ unsigned int len,
+ double xdim, double ydim)
+{
+ struct graph *g;
+ int i;
+
+ g = graph_new(xdim, ydim, gfio_graph_font);
+ graph_title(g, title);
+ graph_x_title(g, "Percentile");
+
+ for (i = 0; i < len; i++) {
+ char fbuf[8];
+
+ sprintf(fbuf, "%2.2f%%", plist[i].u.f);
+ graph_add_label(g, fbuf);
+ graph_add_data(g, fbuf, (double) ovals[i]);
+ }
+
+ return g;
+}
+
static GtkWidget *gfio_output_clat_percentiles(unsigned int *ovals,
fio_fp64_t *plist,
unsigned int len,
@@ -590,7 +614,38 @@
return tree_view;
}
-static void gfio_show_clat_percentiles(GtkWidget *vbox, struct thread_stat *ts,
+static int on_expose_clat_drawing_area(GtkWidget *w, GdkEvent *event, gpointer p)
+{
+ struct graph *g = p;
+ cairo_t *cr;
+
+ cr = gdk_cairo_create(w->window);
+#if 0
+ if (graph_has_tooltips(g)) {
+ g_object_set(w, "has-tooltip", TRUE, NULL);
+ g_signal_connect(w, "query-tooltip", G_CALLBACK(clat_graph_tooltip), g);
+ }
+#endif
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ bar_graph_draw(g, cr);
+ cairo_destroy(cr);
+
+ return FALSE;
+}
+
+static gint on_config_clat_drawing_area(GtkWidget *w, GdkEventConfigure *event,
+ gpointer data)
+{
+ struct graph *g = data;
+
+ graph_set_size(g, w->allocation.width, w->allocation.height);
+ graph_set_size(g, w->allocation.width, w->allocation.height);
+ graph_set_position(g, 0, 0);
+ return TRUE;
+}
+
+static void gfio_show_clat_percentiles(struct gfio_client *gc,
+ GtkWidget *vbox, struct thread_stat *ts,
int ddir)
{
unsigned int *io_u_plat = ts->io_u_plat[ddir];
@@ -598,7 +653,7 @@
fio_fp64_t *plist = ts->percentile_list;
unsigned int *ovals, len, minv, maxv, scale_down;
const char *base;
- GtkWidget *tree_view, *frame, *hbox;
+ GtkWidget *tree_view, *frame, *hbox, *drawing_area, *completion_vbox;
char tmp[64];
len = calc_clat_percentiles(io_u_plat, nr, plist, &ovals, &maxv, &minv);
@@ -617,14 +672,25 @@
base = "usec";
}
- tree_view = gfio_output_clat_percentiles(ovals, plist, len, base, scale_down);
-
sprintf(tmp, "Completion percentiles (%s)", base);
+ tree_view = gfio_output_clat_percentiles(ovals, plist, len, base, scale_down);
+ gc->ge->clat_graph = setup_clat_graph(tmp, ovals, plist, len, 700.0, 300.0);
+
frame = gtk_frame_new(tmp);
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+ completion_vbox = gtk_vbox_new(FALSE, 3);
+ gtk_container_add(GTK_CONTAINER(frame), completion_vbox);
hbox = gtk_hbox_new(FALSE, 3);
- gtk_container_add(GTK_CONTAINER(frame), hbox);
+ gtk_container_add(GTK_CONTAINER(completion_vbox), hbox);
+ drawing_area = gtk_drawing_area_new();
+ gtk_widget_set_size_request(GTK_WIDGET(drawing_area), 700, 300);
+ gtk_widget_modify_bg(drawing_area, GTK_STATE_NORMAL, &white);
+ gtk_container_add(GTK_CONTAINER(completion_vbox), drawing_area);
+ g_signal_connect(G_OBJECT(drawing_area), "expose_event",
+ G_CALLBACK(on_expose_clat_drawing_area), gc->ge->clat_graph);
+ g_signal_connect(G_OBJECT(drawing_area), "configure_event",
+ G_CALLBACK(on_config_clat_drawing_area), gc->ge->clat_graph);
gtk_box_pack_start(GTK_BOX(hbox), tree_view, TRUE, FALSE, 3);
out:
@@ -673,7 +739,8 @@
#define GFIO_SLAT 2
#define GFIO_LAT 4
-static void gfio_show_ddir_status(GtkWidget *mbox, struct group_run_stats *rs,
+static void gfio_show_ddir_status(struct gfio_client *gc, GtkWidget *mbox,
+ struct group_run_stats *rs,
struct thread_stat *ts, int ddir)
{
const char *ddir_label[2] = { "Read", "Write" };
@@ -783,7 +850,7 @@
}
if (ts->clat_percentiles)
- gfio_show_clat_percentiles(main_vbox, ts, ddir);
+ gfio_show_clat_percentiles(gc, main_vbox, ts, ddir);
free(io_p);
@@ -1150,9 +1217,9 @@
entry_set_int_value(entry, ts->pid);
if (ts->io_bytes[DDIR_READ])
- gfio_show_ddir_status(vbox, rs, ts, DDIR_READ);
+ gfio_show_ddir_status(gc, vbox, rs, ts, DDIR_READ);
if (ts->io_bytes[DDIR_WRITE])
- gfio_show_ddir_status(vbox, rs, ts, DDIR_WRITE);
+ gfio_show_ddir_status(gc, vbox, rs, ts, DDIR_WRITE);
gfio_show_latency_buckets(vbox, ts);
gfio_show_cpu_usage(vbox, ts);