Blame perf/gtkwidgetprofiler.c

Packit 98cdb6
#include "config.h"
Packit 98cdb6
#include <string.h>
Packit 98cdb6
#include "gtkwidgetprofiler.h"
Packit 98cdb6
#include "marshalers.h"
Packit 98cdb6
#include "typebuiltins.h"
Packit 98cdb6
Packit 98cdb6
typedef enum {
Packit 98cdb6
  STATE_NOT_CREATED,
Packit 98cdb6
  STATE_INSTRUMENTED_NOT_MAPPED,
Packit 98cdb6
  STATE_INSTRUMENTED_MAPPED
Packit 98cdb6
} State;
Packit 98cdb6
Packit 98cdb6
struct _GtkWidgetProfilerPrivate {
Packit 98cdb6
  State state;
Packit 98cdb6
Packit 98cdb6
  GtkWidget *profiled_widget;
Packit 98cdb6
  GtkWidget *toplevel;
Packit 98cdb6
Packit 98cdb6
  int n_iterations;
Packit 98cdb6
Packit 98cdb6
  GTimer *timer;
Packit 98cdb6
Packit 98cdb6
  gulong toplevel_expose_event_id;
Packit 98cdb6
  gulong toplevel_property_notify_event_id;
Packit 98cdb6
Packit 98cdb6
  GdkAtom profiler_atom;
Packit 98cdb6
Packit 98cdb6
  guint profiling : 1;
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
G_DEFINE_TYPE (GtkWidgetProfiler, gtk_widget_profiler, G_TYPE_OBJECT);
Packit 98cdb6
Packit 98cdb6
static void gtk_widget_profiler_finalize (GObject *object);
Packit 98cdb6
Packit 98cdb6
enum {
Packit 98cdb6
  CREATE_WIDGET,
Packit 98cdb6
  REPORT,
Packit 98cdb6
  LAST_SIGNAL
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
static guint signals[LAST_SIGNAL];
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gtk_widget_profiler_class_init (GtkWidgetProfilerClass *class)
Packit 98cdb6
{
Packit 98cdb6
  GObjectClass *object_class;
Packit 98cdb6
Packit 98cdb6
  object_class = (GObjectClass *) class;
Packit 98cdb6
Packit 98cdb6
  signals[CREATE_WIDGET] =
Packit 98cdb6
    g_signal_new ("create-widget",
Packit 98cdb6
		  G_OBJECT_CLASS_TYPE (object_class),
Packit 98cdb6
		  G_SIGNAL_RUN_LAST,
Packit 98cdb6
		  G_STRUCT_OFFSET (GtkWidgetProfilerClass, create_widget),
Packit 98cdb6
		  NULL, NULL,
Packit 98cdb6
		  _gtk_marshal_OBJECT__VOID,
Packit 98cdb6
		  G_TYPE_OBJECT, 0);
Packit 98cdb6
Packit 98cdb6
  signals[REPORT] =
Packit 98cdb6
    g_signal_new ("report",
Packit 98cdb6
		  G_OBJECT_CLASS_TYPE (object_class),
Packit 98cdb6
		  G_SIGNAL_RUN_FIRST,
Packit 98cdb6
		  G_STRUCT_OFFSET (GtkWidgetProfilerClass, report),
Packit 98cdb6
		  NULL, NULL,
Packit 98cdb6
		  _gtk_marshal_VOID__ENUM_OBJECT_DOUBLE,
Packit 98cdb6
		  G_TYPE_NONE, 3,
Packit 98cdb6
		  GTK_TYPE_WIDGET_PROFILER_REPORT,
Packit 98cdb6
		  G_TYPE_OBJECT,
Packit 98cdb6
		  G_TYPE_DOUBLE);
Packit 98cdb6
Packit 98cdb6
  object_class->finalize = gtk_widget_profiler_finalize;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gtk_widget_profiler_init (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
Packit 98cdb6
  priv = g_new0 (GtkWidgetProfilerPrivate, 1);
Packit 98cdb6
  profiler->priv = priv;
Packit 98cdb6
Packit 98cdb6
  priv->state = STATE_NOT_CREATED;
Packit 98cdb6
  priv->n_iterations = 1;
Packit 98cdb6
Packit 98cdb6
  priv->timer = g_timer_new ();
Packit 98cdb6
Packit 98cdb6
  priv->profiler_atom = gdk_atom_intern ("GtkWidgetProfiler", FALSE);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
reset_state (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  if (priv->toplevel)
Packit 98cdb6
    {
Packit 98cdb6
      g_signal_handler_disconnect (priv->toplevel, priv->toplevel_expose_event_id);
Packit 98cdb6
      priv->toplevel_expose_event_id = 0;
Packit 98cdb6
Packit 98cdb6
      g_signal_handler_disconnect (priv->toplevel, priv->toplevel_property_notify_event_id);
Packit 98cdb6
      priv->toplevel_property_notify_event_id = 0;
Packit 98cdb6
Packit 98cdb6
      gtk_widget_destroy (priv->toplevel);
Packit 98cdb6
      priv->toplevel = NULL;
Packit 98cdb6
      priv->profiled_widget = NULL;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  priv->state = STATE_NOT_CREATED;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gtk_widget_profiler_finalize (GObject *object)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfiler *profiler;
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
Packit 98cdb6
  profiler = GTK_WIDGET_PROFILER (object);
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  reset_state (profiler);
Packit 98cdb6
  g_timer_destroy (priv->timer);
Packit 98cdb6
Packit 98cdb6
  g_free (priv);
Packit 98cdb6
Packit 98cdb6
  G_OBJECT_CLASS (gtk_widget_profiler_parent_class)->finalize (object);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GtkWidgetProfiler *
Packit 98cdb6
gtk_widget_profiler_new (void)
Packit 98cdb6
{
Packit 98cdb6
  return g_object_new (GTK_TYPE_WIDGET_PROFILER, NULL);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gtk_widget_profiler_set_num_iterations (GtkWidgetProfiler *profiler,
Packit 98cdb6
					gint               n_iterations)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
Packit 98cdb6
  g_return_if_fail (GTK_IS_WIDGET_PROFILER (profiler));
Packit 98cdb6
  g_return_if_fail (n_iterations > 0);
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
  priv->n_iterations = n_iterations;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
report (GtkWidgetProfiler      *profiler,
Packit 98cdb6
	GtkWidgetProfilerReport report,
Packit 98cdb6
	gdouble                 elapsed)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  g_signal_emit (profiler, signals[REPORT], 0, report, priv->profiled_widget, elapsed);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GtkWidget *
Packit 98cdb6
create_widget_via_emission (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *widget;
Packit 98cdb6
Packit 98cdb6
  widget = NULL;
Packit 98cdb6
  g_signal_emit (profiler, signals[CREATE_WIDGET], 0, &widget);
Packit 98cdb6
  if (!widget)
Packit 98cdb6
    g_error ("The profiler emitted the \"create-widget\" signal but the signal handler returned no widget!");
Packit 98cdb6
Packit 98cdb6
  if (gtk_widget_get_visible (widget) || gtk_widget_get_mapped (widget))
Packit 98cdb6
    g_error ("The handler for \"create-widget\" must return an unmapped and unshown widget");
Packit 98cdb6
Packit 98cdb6
  return widget;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
toplevel_property_notify_event_cb (GtkWidget *widget, GdkEventProperty *event, gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfiler *profiler;
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
  gdouble elapsed;
Packit 98cdb6
Packit 98cdb6
  profiler = GTK_WIDGET_PROFILER (data);
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  if (event->atom != priv->profiler_atom)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
Packit 98cdb6
  /* Finish timing map/expose */
Packit 98cdb6
Packit 98cdb6
  elapsed = g_timer_elapsed (priv->timer, NULL);
Packit 98cdb6
  report (profiler, GTK_WIDGET_PROFILER_REPORT_EXPOSE, elapsed);
Packit 98cdb6
Packit 98cdb6
  gtk_main_quit (); /* This will get us back to the end of profile_map_expose() */
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
toplevel_idle_after_expose_cb (gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfiler *profiler;
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
Packit 98cdb6
  profiler = GTK_WIDGET_PROFILER (data);
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  gdk_property_change (priv->toplevel->window,
Packit 98cdb6
		       priv->profiler_atom,
Packit 98cdb6
		       gdk_atom_intern ("STRING", FALSE),
Packit 98cdb6
		       8,
Packit 98cdb6
		       GDK_PROP_MODE_REPLACE,
Packit 98cdb6
		       (guchar *) "hello",
Packit 98cdb6
		       strlen ("hello"));
Packit 98cdb6
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
toplevel_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfiler *profiler;
Packit 98cdb6
Packit 98cdb6
  profiler = GTK_WIDGET_PROFILER (data);
Packit 98cdb6
Packit 98cdb6
  gdk_threads_add_idle_full (G_PRIORITY_HIGH, toplevel_idle_after_expose_cb, profiler, NULL);
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
instrument_toplevel (GtkWidgetProfiler *profiler,
Packit 98cdb6
		     GtkWidget         *toplevel)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  priv->toplevel_expose_event_id = g_signal_connect (toplevel, "expose-event",
Packit 98cdb6
						     G_CALLBACK (toplevel_expose_event_cb), profiler);
Packit 98cdb6
Packit 98cdb6
  gtk_widget_add_events (toplevel, GDK_PROPERTY_CHANGE_MASK);
Packit 98cdb6
  priv->toplevel_property_notify_event_id = g_signal_connect (toplevel, "property-notify-event",
Packit 98cdb6
							      G_CALLBACK (toplevel_property_notify_event_cb), profiler);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GtkWidget *
Packit 98cdb6
ensure_and_get_toplevel (GtkWidget *widget)
Packit 98cdb6
{
Packit 98cdb6
	GtkWidget *toplevel;
Packit 98cdb6
	GtkWidget *window;
Packit 98cdb6
Packit 98cdb6
	toplevel = gtk_widget_get_toplevel (widget);
Packit 98cdb6
	if (gtk_widget_is_toplevel (toplevel))
Packit 98cdb6
		return toplevel;
Packit 98cdb6
Packit 98cdb6
	g_assert (toplevel == widget); /* we don't want extraneous ancestors */
Packit 98cdb6
Packit 98cdb6
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
Packit 98cdb6
	gtk_container_add (GTK_CONTAINER (window), widget);
Packit 98cdb6
Packit 98cdb6
	return window;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GtkWidget *
Packit 98cdb6
get_instrumented_toplevel (GtkWidgetProfiler *profiler,
Packit 98cdb6
			   GtkWidget         *widget)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *window;
Packit 98cdb6
Packit 98cdb6
  window = ensure_and_get_toplevel (widget);
Packit 98cdb6
  instrument_toplevel (profiler, window);
Packit 98cdb6
Packit 98cdb6
  return window;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
map_widget (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
  g_assert (priv->state == STATE_INSTRUMENTED_NOT_MAPPED);
Packit 98cdb6
Packit 98cdb6
  /* Time map.
Packit 98cdb6
   *
Packit 98cdb6
   * FIXME: we are really timing a show_all(); we don't really wait for all the "map_event" signals
Packit 98cdb6
   * to happen.  Should we rename GTK_WIDGET_PROFILER_REPORT_MAP report to something else?
Packit 98cdb6
   */
Packit 98cdb6
Packit 98cdb6
  gtk_widget_show_all (priv->toplevel);
Packit 98cdb6
  priv->state = STATE_INSTRUMENTED_MAPPED;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
profile_map_expose (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
  gdouble elapsed;
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  g_assert (priv->state == STATE_INSTRUMENTED_NOT_MAPPED);
Packit 98cdb6
Packit 98cdb6
  g_timer_reset (priv->timer);
Packit 98cdb6
  map_widget (profiler);
Packit 98cdb6
  elapsed = g_timer_elapsed (priv->timer, NULL);
Packit 98cdb6
Packit 98cdb6
  report (profiler, GTK_WIDGET_PROFILER_REPORT_MAP, elapsed);
Packit 98cdb6
Packit 98cdb6
  /* Time expose; this gets recorded in toplevel_property_notify_event_cb() */
Packit 98cdb6
Packit 98cdb6
  g_timer_reset (priv->timer);
Packit 98cdb6
  gtk_main ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
profile_destroy (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
  gdouble elapsed;
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  g_assert (priv->state != STATE_NOT_CREATED);
Packit 98cdb6
Packit 98cdb6
  g_timer_reset (priv->timer);
Packit 98cdb6
  reset_state (profiler);
Packit 98cdb6
  elapsed = g_timer_elapsed (priv->timer, NULL);
Packit 98cdb6
Packit 98cdb6
  report (profiler, GTK_WIDGET_PROFILER_REPORT_DESTROY, elapsed);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
create_widget (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  g_assert (priv->state == STATE_NOT_CREATED);
Packit 98cdb6
Packit 98cdb6
  priv->profiled_widget = create_widget_via_emission (profiler);
Packit 98cdb6
  priv->toplevel = get_instrumented_toplevel (profiler, priv->profiled_widget);
Packit 98cdb6
Packit 98cdb6
  priv->state = STATE_INSTRUMENTED_NOT_MAPPED;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* The "boot time" of a widget is the time needed to
Packit 98cdb6
 *
Packit 98cdb6
 *   1. Create the widget
Packit 98cdb6
 *   2. Map it
Packit 98cdb6
 *   3. Expose it
Packit 98cdb6
 *   4. Destroy it.
Packit 98cdb6
 *
Packit 98cdb6
 * This runs a lot of interesting code:  instantiation, size requisition and
Packit 98cdb6
 * allocation, realization, mapping, exposing, destruction.
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
profile_boot (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
  gdouble elapsed;
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  g_assert (priv->state == STATE_NOT_CREATED);
Packit 98cdb6
Packit 98cdb6
  /* Time creation */
Packit 98cdb6
Packit 98cdb6
  g_timer_reset (priv->timer);
Packit 98cdb6
  create_widget (profiler);
Packit 98cdb6
  elapsed = g_timer_elapsed (priv->timer, NULL);
Packit 98cdb6
Packit 98cdb6
  report (profiler, GTK_WIDGET_PROFILER_REPORT_CREATE, elapsed);
Packit 98cdb6
Packit 98cdb6
  /* Start timing map/expose */
Packit 98cdb6
Packit 98cdb6
  profile_map_expose (profiler);
Packit 98cdb6
Packit 98cdb6
  /* Profile destruction */
Packit 98cdb6
Packit 98cdb6
  profile_destroy (profiler);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* To measure expose time, we trigger a full expose on the toplevel window.  We
Packit 98cdb6
 * do the same as xrefresh(1), i.e. we map and unmap a window to make the other
Packit 98cdb6
 * one expose.
Packit 98cdb6
 */
Packit 98cdb6
static void
Packit 98cdb6
profile_expose (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
  GdkWindow *window;
Packit 98cdb6
  GdkWindowAttr attr;
Packit 98cdb6
  int attr_mask;
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
Packit 98cdb6
  g_assert (priv->state == STATE_INSTRUMENTED_MAPPED);
Packit 98cdb6
Packit 98cdb6
  /* Time creation */
Packit 98cdb6
Packit 98cdb6
  attr.x = 0;
Packit 98cdb6
  attr.y = 0;
Packit 98cdb6
  attr.width = priv->toplevel->allocation.width;
Packit 98cdb6
  attr.height = priv->toplevel->allocation.width;
Packit 98cdb6
  attr.wclass = GDK_INPUT_OUTPUT;
Packit 98cdb6
  attr.window_type = GDK_WINDOW_CHILD;
Packit 98cdb6
Packit 98cdb6
  attr_mask = GDK_WA_X | GDK_WA_Y;
Packit 98cdb6
Packit 98cdb6
  window = gdk_window_new (priv->toplevel->window, &attr, attr_mask);
Packit 98cdb6
  gdk_window_set_back_pixmap (window, NULL, TRUE); /* avoid flicker */
Packit 98cdb6
Packit 98cdb6
  gdk_window_show (window);
Packit 98cdb6
  gdk_window_hide (window);
Packit 98cdb6
  gdk_window_destroy (window);
Packit 98cdb6
Packit 98cdb6
  /* Time expose; this gets recorded in toplevel_property_notify_event_cb() */
Packit 98cdb6
Packit 98cdb6
  g_timer_reset (priv->timer);
Packit 98cdb6
  gtk_main ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gtk_widget_profiler_profile_boot (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
  int i, n;
Packit 98cdb6
Packit 98cdb6
  g_return_if_fail (GTK_IS_WIDGET_PROFILER (profiler));
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
  g_return_if_fail (!priv->profiling);
Packit 98cdb6
Packit 98cdb6
  reset_state (profiler);
Packit 98cdb6
  priv->profiling = TRUE;
Packit 98cdb6
Packit 98cdb6
  n = priv->n_iterations;
Packit 98cdb6
  for (i = 0; i < n; i++)
Packit 98cdb6
    profile_boot (profiler);
Packit 98cdb6
Packit 98cdb6
  priv->profiling = FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gtk_widget_profiler_profile_expose (GtkWidgetProfiler *profiler)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidgetProfilerPrivate *priv;
Packit 98cdb6
  int i, n;
Packit 98cdb6
Packit 98cdb6
  g_return_if_fail (GTK_IS_WIDGET_PROFILER (profiler));
Packit 98cdb6
Packit 98cdb6
  priv = profiler->priv;
Packit 98cdb6
  g_return_if_fail (!priv->profiling);
Packit 98cdb6
Packit 98cdb6
  reset_state (profiler);
Packit 98cdb6
  priv->profiling = TRUE;
Packit 98cdb6
Packit 98cdb6
  create_widget (profiler);
Packit 98cdb6
  map_widget (profiler);
Packit 98cdb6
Packit 98cdb6
  n = priv->n_iterations;
Packit 98cdb6
  for (i = 0; i < n; i++)
Packit 98cdb6
    profile_expose (profiler);
Packit 98cdb6
Packit 98cdb6
  priv->profiling = FALSE;
Packit 98cdb6
Packit 98cdb6
  reset_state (profiler);
Packit 98cdb6
}