[glib/halfline/debug-metrics: 5/9] gsignal: Add debug metrics for gnome-shell




commit 5c29e2984febb5676b1236c59e5b03d647097aea
Author: Ray Strode <rstrode redhat com>
Date:   Wed May 26 23:47:11 2021 -0400

    gsignal: Add debug metrics for gnome-shell

 gobject/gsignal.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 101 insertions(+), 1 deletion(-)
---
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
index 1c5f5ee87..be55caceb 100644
--- a/gobject/gsignal.c
+++ b/gobject/gsignal.c
@@ -853,16 +853,116 @@ signal_key_cmp (gconstpointer node1,
     return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype);
 }
 
+static GMetricsFile *handlers_by_object_metrics_file;
+static GMetricsFile *total_handlers_metrics_file;
+static gsize old_total_handlers;
+
+static void
+on_signal_metrics_timeout (void)
+{
+  GPtrArray *counts_array;
+  GHashTableIter iter;
+  static int generation = 0;
+  GHashTable *counts_hash;
+  gpointer key;
+  int count;
+  Handler **handlers;
+  guint length, i;
+  gsize new_total_handlers;
+  gssize change;
+
+  SIGNAL_LOCK ();
+
+  if (total_handlers_metrics_file)
+    {
+      g_metrics_file_start_record (total_handlers_metrics_file);
+      new_total_handlers = g_hash_table_size (g_handlers);
+
+      change = new_total_handlers - old_total_handlers;
+      old_total_handlers = new_total_handlers;
+
+      g_metrics_file_add_row (total_handlers_metrics_file,
+                              g_handlers,
+                              new_total_handlers,
+                              change > 0? "+" : "",
+                              change);
+      g_metrics_file_end_record (total_handlers_metrics_file);
+    }
+
+  if (handlers_by_object_metrics_file)
+    {
+      g_metrics_file_start_record (handlers_by_object_metrics_file);
+      if ((generation % 10) == 0)
+        {
+          g_hide_hash(TRUE);
+          counts_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+          g_hide_hash(FALSE);
+
+          handlers = (Handler **) g_hash_table_get_keys_as_array (g_handlers, &length);
+          for (i = 0; i < length; i++)
+          {
+              Handler *handler = handlers[i];
+              key = g_strdup_printf ("(%p) %s::%s", handler->instance, g_type_name (G_TYPE_FROM_INSTANCE 
(handler->instance)),g_signal_name_unlocked (handler->signal_id));
+              count = GPOINTER_TO_INT (g_hash_table_lookup (counts_hash, key));
+
+              g_hash_table_replace (counts_hash, key, GINT_TO_POINTER (count + 1));
+          }
+
+          counts_array = g_ptr_array_new ();
+          g_hash_table_iter_init (&iter, counts_hash);
+          while (g_hash_table_iter_next (&iter, &key, NULL))
+              g_ptr_array_add (counts_array, key);
+          g_ptr_array_sort (counts_array, (GCompareFunc) g_strcmp0);
+
+          for (i = 0; i < counts_array->len; i++)
+          {
+              key = g_ptr_array_index (counts_array, i);
+              count = GPOINTER_TO_INT (g_hash_table_lookup (counts_hash, key));
+              g_metrics_file_add_row (handlers_by_object_metrics_file,
+                                      key,
+                                      count);
+          }
+
+          g_free (handlers);
+          g_ptr_array_free (counts_array, TRUE);
+          g_hash_table_unref (counts_hash);
+        }
+      g_metrics_file_end_record (handlers_by_object_metrics_file);
+    }
+  SIGNAL_UNLOCK ();
+  generation++;
+}
+
 void
 _g_signal_init (void)
 {
   SIGNAL_LOCK ();
   if (!g_n_signal_nodes)
     {
+      gboolean needs_signal_metrics = FALSE, needs_handler_metrics = FALSE;
+
       /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */
       g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL);
       g_signal_key_bsa = g_bsearch_array_create (&g_signal_key_bconfig);
-      
+
+      needs_signal_metrics = g_metrics_requested ("signals");
+      needs_handler_metrics = g_metrics_requested ("handlers");
+
+      if (needs_signal_metrics)
+        handlers_by_object_metrics_file = g_metrics_file_new ("signals",
+                                                              "name", "%s",
+                                                              "count", "%ld",
+                                                              NULL);
+      if (needs_handler_metrics)
+        total_handlers_metrics_file = g_metrics_file_new ("handlers",
+                                                          "address", "%p",
+                                                          "total handlers", "%ld",
+                                                          "change", "%s%ld",
+                                                          NULL);
+
+      if (needs_signal_metrics || needs_handler_metrics)
+        g_metrics_start_timeout (on_signal_metrics_timeout);
+
       /* invalid (0) signal_id */
       g_n_signal_nodes = 1;
       g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]