mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 15:10:53 +00:00
line-visualizer: auto-discover counter ranges
If we have not received a y-lower/upper value, then we can discover that from the data set at the cost of an extra capture linear scan. This is useful for the meomry source which can change the upper value during the lifetime of a process.
This commit is contained in:
@ -63,6 +63,9 @@ typedef struct
|
|||||||
* help us avoid doing duplicate work.
|
* help us avoid doing duplicate work.
|
||||||
*/
|
*/
|
||||||
guint queued_load;
|
guint queued_load;
|
||||||
|
|
||||||
|
guint y_lower_set : 1;
|
||||||
|
guint y_upper_set : 1;
|
||||||
} SpLineVisualizerRowPrivate;
|
} SpLineVisualizerRowPrivate;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -84,6 +87,8 @@ typedef struct
|
|||||||
gint64 end_time;
|
gint64 end_time;
|
||||||
gdouble y_lower;
|
gdouble y_lower;
|
||||||
gdouble y_upper;
|
gdouble y_upper;
|
||||||
|
guint y_lower_set : 1;
|
||||||
|
guint y_upper_set : 1;
|
||||||
} LoadData;
|
} LoadData;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (SpLineVisualizerRow, sp_line_visualizer_row, SP_TYPE_VISUALIZER_ROW)
|
G_DEFINE_TYPE_WITH_PRIVATE (SpLineVisualizerRow, sp_line_visualizer_row, SP_TYPE_VISUALIZER_ROW)
|
||||||
@ -385,11 +390,13 @@ sp_line_visualizer_row_set_property (GObject *object,
|
|||||||
|
|
||||||
case PROP_Y_LOWER:
|
case PROP_Y_LOWER:
|
||||||
priv->y_lower = g_value_get_double (value);
|
priv->y_lower = g_value_get_double (value);
|
||||||
|
priv->y_lower_set = TRUE;
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_Y_UPPER:
|
case PROP_Y_UPPER:
|
||||||
priv->y_upper = g_value_get_double (value);
|
priv->y_upper = g_value_get_double (value);
|
||||||
|
priv->y_upper_set = TRUE;
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -600,6 +607,53 @@ sp_line_visualizer_row_load_data_frame_cb (const SpCaptureFrame *frame,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
sp_line_visualizer_row_load_data_range_cb (const SpCaptureFrame *frame,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
LoadData *load = user_data;
|
||||||
|
|
||||||
|
g_assert (frame != NULL);
|
||||||
|
g_assert (frame->type == SP_CAPTURE_FRAME_CTRSET ||
|
||||||
|
frame->type == SP_CAPTURE_FRAME_CTRDEF);
|
||||||
|
g_assert (load != NULL);
|
||||||
|
g_assert (load->y_upper_set == FALSE ||
|
||||||
|
load->y_lower_set == FALSE);
|
||||||
|
|
||||||
|
if (frame->type == SP_CAPTURE_FRAME_CTRSET)
|
||||||
|
{
|
||||||
|
const SpCaptureFrameCounterSet *set = (SpCaptureFrameCounterSet *)frame;
|
||||||
|
|
||||||
|
for (guint i = 0; i < set->n_values; i++)
|
||||||
|
{
|
||||||
|
const SpCaptureCounterValues *group = &set->values[i];
|
||||||
|
|
||||||
|
for (guint j = 0; j < G_N_ELEMENTS (group->ids); j++)
|
||||||
|
{
|
||||||
|
guint counter_id = group->ids[j];
|
||||||
|
|
||||||
|
if (counter_id != 0 && contains_id (load->lines, counter_id))
|
||||||
|
{
|
||||||
|
gdouble y;
|
||||||
|
|
||||||
|
if (counter_type (load, counter_id) == SP_CAPTURE_COUNTER_DOUBLE)
|
||||||
|
y = group->values[j].vdbl;
|
||||||
|
else
|
||||||
|
y = group->values[j].v64;
|
||||||
|
|
||||||
|
if (!load->y_upper_set)
|
||||||
|
load->y_upper = MAX (load->y_upper, y);
|
||||||
|
|
||||||
|
if (!load->y_lower_set)
|
||||||
|
load->y_lower = MAX (load->y_lower, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sp_line_visualizer_row_load_data_worker (GTask *task,
|
sp_line_visualizer_row_load_data_worker (GTask *task,
|
||||||
gpointer source_object,
|
gpointer source_object,
|
||||||
@ -621,10 +675,21 @@ sp_line_visualizer_row_load_data_worker (GTask *task,
|
|||||||
g_array_append_val (counter_ids, line_info->id);
|
g_array_append_val (counter_ids, line_info->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
sp_capture_cursor_add_condition (
|
sp_capture_cursor_add_condition (load->cursor,
|
||||||
load->cursor,
|
sp_capture_condition_new_where_counter_in (counter_ids->len,
|
||||||
sp_capture_condition_new_where_counter_in (counter_ids->len,
|
(guint *)(gpointer)counter_ids->data));
|
||||||
(guint *)(gpointer)counter_ids->data));
|
|
||||||
|
/* If y boundaries are not set, we need to discover them by scaning the data. */
|
||||||
|
if (!load->y_lower_set || !load->y_upper_set)
|
||||||
|
{
|
||||||
|
sp_capture_cursor_foreach (load->cursor, sp_line_visualizer_row_load_data_range_cb, load);
|
||||||
|
sp_capture_cursor_reset (load->cursor);
|
||||||
|
|
||||||
|
/* Add extra boundary for some space above the graph line */
|
||||||
|
if (G_MAXDOUBLE - load->y_upper > (load->y_upper * .25))
|
||||||
|
load->y_upper *= 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
sp_capture_cursor_foreach (load->cursor, sp_line_visualizer_row_load_data_frame_cb, load);
|
sp_capture_cursor_foreach (load->cursor, sp_line_visualizer_row_load_data_frame_cb, load);
|
||||||
g_task_return_pointer (task, g_steal_pointer (&load->cache), (GDestroyNotify)point_cache_unref);
|
g_task_return_pointer (task, g_steal_pointer (&load->cache), (GDestroyNotify)point_cache_unref);
|
||||||
}
|
}
|
||||||
@ -659,6 +724,8 @@ sp_line_visualizer_row_load_data_async (SpLineVisualizerRow *self,
|
|||||||
load->cache = point_cache_new ();
|
load->cache = point_cache_new ();
|
||||||
load->y_lower = priv->y_lower;
|
load->y_lower = priv->y_lower;
|
||||||
load->y_upper = priv->y_upper;
|
load->y_upper = priv->y_upper;
|
||||||
|
load->y_lower_set = priv->y_lower_set;
|
||||||
|
load->y_upper_set = priv->y_upper_set;
|
||||||
load->begin_time = sp_capture_reader_get_start_time (priv->reader);
|
load->begin_time = sp_capture_reader_get_start_time (priv->reader);
|
||||||
load->end_time = sp_capture_reader_get_end_time (priv->reader);
|
load->end_time = sp_capture_reader_get_end_time (priv->reader);
|
||||||
load->cursor = sp_capture_cursor_new (priv->reader);
|
load->cursor = sp_capture_cursor_new (priv->reader);
|
||||||
@ -680,9 +747,26 @@ sp_line_visualizer_row_load_data_finish (SpLineVisualizerRow *self,
|
|||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
SpLineVisualizerRowPrivate *priv = sp_line_visualizer_row_get_instance_private (self);
|
||||||
|
LoadData *state;
|
||||||
|
|
||||||
g_assert (SP_IS_LINE_VISUALIZER_ROW (self));
|
g_assert (SP_IS_LINE_VISUALIZER_ROW (self));
|
||||||
g_assert (G_IS_TASK (result));
|
g_assert (G_IS_TASK (result));
|
||||||
|
|
||||||
|
state = g_task_get_task_data (G_TASK (result));
|
||||||
|
|
||||||
|
if (!priv->y_lower_set && priv->y_lower != state->y_lower)
|
||||||
|
{
|
||||||
|
priv->y_lower = state->y_lower;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_Y_LOWER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!priv->y_upper_set && priv->y_upper != state->y_upper)
|
||||||
|
{
|
||||||
|
priv->y_upper = state->y_upper;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_Y_UPPER]);
|
||||||
|
}
|
||||||
|
|
||||||
return g_task_propagate_pointer (G_TASK (result), error);
|
return g_task_propagate_pointer (G_TASK (result), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user