Esempio n. 1
0
/**
 * uber_line_graph_get_next_data:
 * @graph: A #UberGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static gboolean
uber_line_graph_get_next_data (UberGraph *graph) /* IN */
{
	UberLineGraphPrivate *priv;
	LineInfo *line;
	gdouble val;
	gboolean ret = FALSE;
	gint i;

	g_return_val_if_fail(UBER_IS_LINE_GRAPH(graph), FALSE);

	priv = UBER_LINE_GRAPH(graph)->priv;
	/*
	 * Retrieve the next data point.
	 */
	if (priv->func) {
		for (i = 0; i < priv->lines->len; i++) {
			val = 0.;
			line = &g_array_index(priv->lines, LineInfo, i);
			if (!(ret = priv->func(UBER_LINE_GRAPH(graph),
			                       i + 1, &val,
			                       priv->func_data))) {
				val = -INFINITY;
			}
			g_ring_append_val(line->raw_data, val);
			/*
			 * TODO: Scale value.
			 */
			g_ring_append_val(line->scaled_data, val);
		}
	}
	return ret;
}
Esempio n. 2
0
/**
 * uber_line_graph_set_stride:
 * @graph: A #UberGraph.
 * @stride: The number of data points within the graph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static void
uber_line_graph_set_stride (UberGraph *graph,  /* IN */
                            guint      stride) /* IN */
{
	UberLineGraphPrivate *priv;
	LineInfo *line;
	gint i;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));

	priv = UBER_LINE_GRAPH(graph)->priv;
	priv->stride = stride;
	/*
	 * TODO: Support changing stride after lines have been added.
	 */
	if (priv->lines->len) {
		for (i = 0; i < priv->lines->len; i++) {
			line = &g_array_index(priv->lines, LineInfo, i);
			g_ring_unref(line->raw_data);
			g_ring_unref(line->scaled_data);
			line->raw_data = g_ring_sized_new(sizeof(gdouble),
			                                  priv->stride, NULL);
			line->scaled_data = g_ring_sized_new(sizeof(gdouble),
			                                     priv->stride, NULL);
			uber_line_graph_init_ring(line->raw_data);
			uber_line_graph_init_ring(line->scaled_data);
		}
		return;
	}
}
Esempio n. 3
0
/**
 * uber_line_graph_get_next_data:
 * @graph: A #UberGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static gboolean
uber_line_graph_get_next_data (UberGraph *graph) /* IN */
{
	UberLineGraphPrivate *priv;
	gboolean scale_changed = FALSE;
	gboolean ret = FALSE;
	LineInfo *line;
	gdouble val;
	gint i;

	g_return_val_if_fail(UBER_IS_LINE_GRAPH(graph), FALSE);

	priv = UBER_LINE_GRAPH(graph)->priv;
	/*
	 * Retrieve the next data point.
	 */
	if (priv->func) {
		for (i = 0; i < priv->lines->len; i++) {
			val = 0.;
			line = &g_array_index(priv->lines, LineInfo, i);
			if (!(ret = priv->func(UBER_LINE_GRAPH(graph),
			                       i + 1, &val,
			                       priv->func_data))) {
				val = -INFINITY;
			}
			g_ring_append_val(line->raw_data, val);
			if (priv->autoscale) {
				if (val < priv->range.begin) {
					priv->range.begin = val - (val * SCALE_FACTOR);
					priv->range.range = priv->range.end - priv->range.begin;
					scale_changed = TRUE;
				} else if (val > priv->range.end) {
					priv->range.end = val + (val * SCALE_FACTOR);
					priv->range.range = priv->range.end - priv->range.begin;
					scale_changed = TRUE;
				}
			}
		}
	}
	if (scale_changed) {
		uber_graph_scale_changed(graph);
	}
	return ret;
}
Esempio n. 4
0
/**
 * uber_line_graph_render:
 * @graph: A #UberGraph.
 *
 * Render the entire contents of the graph.
 *
 * Returns: None.
 * Side effects: None.
 */
static void
uber_line_graph_render (UberGraph    *graph, /* IN */
                        cairo_t      *cr,    /* IN */
                        GdkRectangle *rect)  /* IN */
{
	UberLineGraphPrivate *priv;
	LineInfo *line;
	gint i;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));

	priv = UBER_LINE_GRAPH(graph)->priv;
	/*
	 * Render each line to the graph.
	 */
	for (i = 0; i < priv->lines->len; i++) {
		line = &g_array_index(priv->lines, LineInfo, i);
		uber_line_graph_render_line(UBER_LINE_GRAPH(graph), cr, rect, line);
	}
}
Esempio n. 5
0
/**
 * uber_line_graph_get_yrange:
 * @graph: A #UberGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static void
uber_line_graph_get_yrange (UberGraph *graph, /* IN */
                            UberRange *range) /* OUT */
{
	UberLineGraphPrivate *priv;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));
	g_return_if_fail(range != NULL);

	priv = UBER_LINE_GRAPH(graph)->priv;
	*range = priv->range;
}
Esempio n. 6
0
/**
 * uber_line_graph_finalize:
 * @object: A #UberLineGraph.
 *
 * Finalizer for a #UberLineGraph instance.  Frees any resources held by
 * the instance.
 *
 * Returns: None.
 * Side effects: None.
 */
static void
uber_line_graph_finalize (GObject *object) /* IN */
{
	UberLineGraphPrivate *priv;
	LineInfo *line;
	gint i;

	priv = UBER_LINE_GRAPH(object)->priv;
	/*
	 * Clean up after cached values.
	 */
	for (i = 0; i < priv->lines->len; i++) {
		line = &g_array_index(priv->lines, LineInfo, i);
		g_ring_unref(line->raw_data);
		g_ring_unref(line->scaled_data);
	}
	G_OBJECT_CLASS(uber_line_graph_parent_class)->finalize(object);
}
Esempio n. 7
0
/**
 * uber_line_graph_set_property:
 * @object: (in): A #GObject.
 * @prop_id: (in): The property identifier.
 * @value: (in): The given property.
 * @pspec: (in): A #ParamSpec.
 *
 * Set a given #GObject property.
 */
static void
uber_line_graph_set_property (GObject      *object,  /* IN */
                              guint         prop_id, /* IN */
                              const GValue *value,   /* IN */
                              GParamSpec   *pspec)   /* IN */
{
	UberLineGraph *graph = UBER_LINE_GRAPH(object);

	switch (prop_id) {
	case PROP_AUTOSCALE:
		uber_line_graph_set_autoscale(graph, g_value_get_boolean(value));
		break;
	case PROP_RANGE:
		uber_line_graph_set_range(graph, g_value_get_boxed(value));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
	}
}
Esempio n. 8
0
/**
 * uber_line_graph_downscale:
 * @graph: A #UberGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static gboolean
uber_line_graph_downscale (UberGraph *graph) /* IN */
{
	UberLineGraphPrivate *priv;
	gboolean ret = FALSE;
	gdouble val = 0;
	gdouble cur;
	LineInfo *line;
	gint i;
	gint j;

	g_return_val_if_fail(UBER_IS_LINE_GRAPH(graph), FALSE);

	priv = UBER_LINE_GRAPH(graph)->priv;
	/*
	 * If we are set to autoscale, ignore request.
	 */
	if (!priv->autoscale) {
		return FALSE;
	}
	/*
	 * Determine the largest value available.
	 */
	for (i = 0; i < priv->lines->len; i++) {
		line = &g_array_index(priv->lines, LineInfo, i);
		for (j = 0; j < line->raw_data->len; j++) {
			cur = g_ring_get_index(line->raw_data, gdouble, j);
			val = (cur > val) ? cur : val;
		}
	}
	/*
	 * Downscale if we can.
	 */
	if (val != priv->range.begin) {
		if ((val * (1. + SCALE_FACTOR)) < priv->range.end) {
			priv->range.end = val * (1. + SCALE_FACTOR);
			priv->range.range = priv->range.end - priv->range.begin;
			ret = TRUE;
		}
	}
	return ret;
}
Esempio n. 9
0
/**
 * uber_line_graph_render_fast:
 * @graph: A #UberGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static void
uber_line_graph_render_fast (UberGraph    *graph, /* IN */
                             cairo_t      *cr,    /* IN */
                             GdkRectangle *rect,  /* IN */
                             guint         epoch, /* IN */
                             gfloat        each)  /* IN */
{
	UberLineGraphPrivate *priv;
	LineInfo *line;
	gdouble last_y;
	gdouble y;
	gint i;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));
	g_return_if_fail(cr != NULL);
	g_return_if_fail(rect != NULL);

	priv = UBER_LINE_GRAPH(graph)->priv;
	/*
	 * Prepare cairo line styling.
	 */
	cairo_set_line_width(cr, 1.0);
	cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
	cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
	cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
	/*
	 * Render most recent data point for each line.
	 */
	for (i = 0; i < priv->lines->len; i++) {
		line = &g_array_index(priv->lines, LineInfo, i);
		gdk_cairo_set_source_color(cr, &line->color);
		/*
		 * Calculate positions.
		 */
		y = g_ring_get_index(line->scaled_data, gdouble, 0);
		last_y = g_ring_get_index(line->scaled_data, gdouble, 1);
		/*
		 * Don't try to draw before we have real values.
		 */
		if ((isnan(y) || isinf(y)) || (isnan(last_y) || isinf(last_y))) {
			continue;
		}
		/*
		 * Translate position from bottom right corner.
		 */
		y = RECT_BOTTOM(*rect) - y;
		last_y = RECT_BOTTOM(*rect) - last_y;
		/*
		 * Convert relative position to fixed from bottom pixel.
		 */
		cairo_new_path(cr);
		cairo_move_to(cr, epoch, y);
		cairo_curve_to(cr,
		               epoch - (each / 2.),
		               y,
		               epoch - (each / 2.),
		               last_y,
		               epoch - each,
		               last_y);
		cairo_stroke(cr);
	}
}
Esempio n. 10
0
/**
 * uber_line_graph_render_fast:
 * @graph: A #UberGraph.
 *
 * XXX
 *
 * Returns: None.
 * Side effects: None.
 */
static void
uber_line_graph_render_fast (UberGraph    *graph, /* IN */
                             cairo_t      *cr,    /* IN */
                             GdkRectangle *rect,  /* IN */
                             guint         epoch, /* IN */
                             gfloat        each)  /* IN */
{
	UberLineGraphPrivate *priv;
	UberRange pixel_range;
	LineInfo *line;
	gdouble last_y;
	gdouble y;
	gint i;

	g_return_if_fail(UBER_IS_LINE_GRAPH(graph));
	g_return_if_fail(cr != NULL);
	g_return_if_fail(rect != NULL);

	priv = UBER_LINE_GRAPH(graph)->priv;
	pixel_range.begin = rect->y + 1;
	pixel_range.end = rect->y + rect->height;
	pixel_range.range = pixel_range.end - pixel_range.begin;
	/*
	 * Render most recent data point for each line.
	 */
	for (i = 0; i < priv->lines->len; i++) {
		line = &g_array_index(priv->lines, LineInfo, i);
		uber_line_graph_stylize_line(UBER_LINE_GRAPH(graph), line, cr);
		/*
		 * Calculate positions.
		 */
		y = g_ring_get_index(line->raw_data, gdouble, 0);
		last_y = g_ring_get_index(line->raw_data, gdouble, 1);
		/*
		 * Don't try to draw before we have real values.
		 */
		if ((isnan(y) || isinf(y)) || (isnan(last_y) || isinf(last_y))) {
			continue;
		}
		/*
		 * Translate to coordinate scale.
		 */
		if (!priv->scale(&priv->range, &pixel_range, &y, priv->scale_data) ||
		    !priv->scale(&priv->range, &pixel_range, &last_y, priv->scale_data)) {
			continue;
		}
		/*
		 * Translate position from bottom right corner.
		 */
		y = (gint)(RECT_BOTTOM(*rect) - y) - .5;
		last_y = (gint)(RECT_BOTTOM(*rect) - last_y) - .5;
		/*
		 * Convert relative position to fixed from bottom pixel.
		 */
		cairo_new_path(cr);
		cairo_move_to(cr, epoch, y);
		cairo_curve_to(cr,
		               epoch - (each / 2.),
		               y,
		               epoch - (each / 2.),
		               last_y,
		               epoch - each,
		               last_y);
		cairo_stroke(cr);
	}
}
Esempio n. 11
0
gint
main (gint   argc,   /* IN */
      gchar *argv[]) /* IN */
{
	gdouble dashes[] = { 1.0, 4.0 };
	UberRange cpu_range = { 0., 100., 100. };
	UberRange net_range = { 0., 512., 512. };
	UberRange ui_range = { 0., 10., 10. };
	GtkWidget *window;
	GtkWidget *cpu;
	GtkWidget *net;
	GtkWidget *line;
	GtkWidget *map;
	GtkWidget *scatter;
	GtkWidget *label;
	GtkAccelGroup *ag;
	GdkColor color;
	gint lineno;
	gint nprocs;
	gint i;
	gint mod;

	g_thread_init(NULL);
	gtk_init(&argc, &argv);
	nprocs = get_nprocs();
	/*
	 * Check for blktrace hack.
	 */
	if (argc > 1 && (g_strcmp0(argv[1], "--i-can-haz-blktrace") == 0)) {
		want_blktrace = TRUE;
	}
	/*
	 * Warm up differential samplers.
	 */
	smon_next_cpu_info();
	smon_next_cpu_freq_info();
	if (want_blktrace) {
		uber_blktrace_init();
	}
	/*
	 * Install event hook to track how many X events we are doing.
	 */
	gdk_event_handler_set(smon_gdk_event_hook, NULL, NULL);
	/*
	 * Create window and graphs.
	 */
	window = uber_window_new();
	cpu = uber_line_graph_new();
	net = uber_line_graph_new();
	line = uber_line_graph_new();
	map = uber_heat_map_new();
	scatter = uber_scatter_new();
	/*
	 * Configure CPU graph.
	 */
	uber_line_graph_set_autoscale(UBER_LINE_GRAPH(cpu), FALSE);
	uber_graph_set_format(UBER_GRAPH(cpu), UBER_GRAPH_FORMAT_PERCENT);
	uber_line_graph_set_range(UBER_LINE_GRAPH(cpu), &cpu_range);
	uber_line_graph_set_data_func(UBER_LINE_GRAPH(cpu),
	                              smon_get_cpu_info, NULL, NULL);
	for (i = 0; i < nprocs; i++) {
		mod = i % G_N_ELEMENTS(default_colors);
		gdk_color_parse(default_colors[mod], &color);
		label = uber_label_new();
		uber_label_set_color(UBER_LABEL(label), &color);
		uber_line_graph_add_line(UBER_LINE_GRAPH(cpu), &color,
		                         UBER_LABEL(label));
		cpu_info.labels[i] = label;
		/*
		 * XXX: Add the line regardless. Just dont populate it if we don't
		 *      have data.
		 */
		lineno = uber_line_graph_add_line(UBER_LINE_GRAPH(cpu), &color, NULL);
		if (smon_cpu_has_freq_scaling(i)) {
			uber_line_graph_set_line_dash(UBER_LINE_GRAPH(cpu), lineno,
			                              dashes, G_N_ELEMENTS(dashes), 0);
			uber_line_graph_set_line_alpha(UBER_LINE_GRAPH(cpu), lineno, 1.);
		}
	}
	/*
	 * Add lines for GDK/X events.
	 */
	uber_line_graph_set_range(UBER_LINE_GRAPH(line), &ui_range);
	label = uber_label_new();
	uber_label_set_text(UBER_LABEL(label), "GDK Events");
	gdk_color_parse("#729fcf", &color);
	uber_line_graph_add_line(UBER_LINE_GRAPH(line), &color, UBER_LABEL(label));
	label = uber_label_new();
	uber_label_set_text(UBER_LABEL(label), "X Events");
	gdk_color_parse("#a40000", &color);
	uber_line_graph_add_line(UBER_LINE_GRAPH(line), &color, UBER_LABEL(label));
	uber_line_graph_set_data_func(UBER_LINE_GRAPH(line),
	                              smon_get_xevent_info, NULL, NULL);
	/*
	 * Add lines for bytes in/out.
	 */
	uber_line_graph_set_range(UBER_LINE_GRAPH(net), &net_range);
	uber_line_graph_set_data_func(UBER_LINE_GRAPH(net),
	                              smon_get_net_info, NULL, NULL);
	uber_graph_set_format(UBER_GRAPH(net), UBER_GRAPH_FORMAT_DIRECT1024);
	label = uber_label_new();
	uber_label_set_text(UBER_LABEL(label), "Bytes In");
	gdk_color_parse("#a40000", &color);
	uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));
	label = uber_label_new();
	uber_label_set_text(UBER_LABEL(label), "Bytes Out");
	gdk_color_parse("#4e9a06", &color);
	uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));

	/*
	 * Configure heat map.
	 */
	uber_graph_set_show_ylines(UBER_GRAPH(map), FALSE);
	gdk_color_parse(default_colors[0], &color);
	uber_heat_map_set_fg_color(UBER_HEAT_MAP(map), &color);
	uber_heat_map_set_data_func(UBER_HEAT_MAP(map),
	                            (UberHeatMapFunc)dummy_scatter_func, NULL, NULL);
	uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(map), "IO Latency");
	uber_graph_set_show_xlabels(UBER_GRAPH(map), FALSE);
	gtk_widget_show(map);

	/*
	 * Configure scatter.
	 */
	if (want_blktrace) {
		uber_graph_set_show_ylines(UBER_GRAPH(scatter), FALSE);
		gdk_color_parse(default_colors[3], &color);
		uber_scatter_set_fg_color(UBER_SCATTER(scatter), &color);
		uber_scatter_set_data_func(UBER_SCATTER(scatter),
								   (UberScatterFunc)uber_blktrace_get, NULL, NULL);
		uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(scatter), "IOPS By Size");
		uber_graph_set_show_xlabels(UBER_GRAPH(scatter), TRUE);
		gtk_widget_show(scatter);
	}
	/*
	 * Add graphs.
	 */
	uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(cpu), "CPU");
	uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(net), "Network");
	uber_window_add_graph(UBER_WINDOW(window), UBER_GRAPH(line), "UI Events");
	/*
	 * Disable X tick labels by default (except last).
	 */
	uber_graph_set_show_xlabels(UBER_GRAPH(cpu), FALSE);
	uber_graph_set_show_xlabels(UBER_GRAPH(net), FALSE);
	uber_graph_set_show_xlabels(UBER_GRAPH(line), FALSE);
	/*
	 * Show widgets.
	 */
	gtk_widget_show(net);
	gtk_widget_show(line);
	gtk_widget_show(cpu);
	gtk_widget_show(window);
	/*
	 * Show cpu labels by default.
	 */
	uber_window_show_labels(UBER_WINDOW(window), UBER_GRAPH(cpu));
	/*
	 * Setup accelerators.
	 */
	ag = gtk_accel_group_new();
	gtk_accel_group_connect(ag, GDK_KEY_w, GDK_CONTROL_MASK, GTK_ACCEL_MASK,
	                        g_cclosure_new(gtk_main_quit, NULL, NULL));
	gtk_window_add_accel_group(GTK_WINDOW(window), ag);
	/*
	 * Attach signals.
	 */
	g_signal_connect(window,
	                 "delete-event",
	                 G_CALLBACK(gtk_main_quit),
	                 NULL);
	/*
	 * Start sampling thread.
	 */
	g_thread_create((GThreadFunc)sample_thread, NULL, FALSE, NULL);
	gtk_main();
	/*
	 * Cleanup after blktrace.
	 */
	if (want_blktrace) {
		uber_blktrace_shutdown();
	}
	return EXIT_SUCCESS;
}