[glib/halfline/debug-metrics: 2/9] ghash: Add debug metrics for gnome-shell
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/halfline/debug-metrics: 2/9] ghash: Add debug metrics for gnome-shell
- Date: Tue, 13 Jul 2021 04:42:27 +0000 (UTC)
commit aacb53efbb7d6caca69f78a7844f646c3917d042
Author: Ray Strode <rstrode redhat com>
Date: Wed May 26 23:04:46 2021 -0400
ghash: Add debug metrics for gnome-shell
glib/ghash.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
glib/ghash.h | 3 ++
2 files changed, 129 insertions(+)
---
diff --git a/glib/ghash.c b/glib/ghash.c
index 131d4ab99..3e889001a 100644
--- a/glib/ghash.c
+++ b/glib/ghash.c
@@ -238,6 +238,7 @@ struct _GHashTable
#endif
GDestroyNotify key_destroy_func;
GDestroyNotify value_destroy_func;
+ gulong last_sweep;
};
typedef struct
@@ -253,6 +254,9 @@ typedef struct
G_STATIC_ASSERT (sizeof (GHashTableIter) == sizeof (RealIter));
G_STATIC_ASSERT (_g_alignof (GHashTableIter) >= _g_alignof (RealIter));
+G_LOCK_DEFINE_STATIC (hash_tables);
+static GMetricsList *hash_tables_list = NULL;
+
/* Each table size has an associated prime modulo (the first prime
* lower than the table size) used to find the initial bucket. Probing
* then works modulo 2^n. The prime modulo is necessary to get a
@@ -680,7 +684,84 @@ g_hash_table_new (GHashFunc hash_func,
return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
}
+static GMetricsFile *metrics_file;
+static GMetricsFile *combined_metrics_file;
+static unsigned long old_total_items = 0, old_total_tables;
+
+static void
+on_hash_table_metrics_timeout (void)
+{
+ GHashTable *hash_table;
+ unsigned long new_total_items = 0, new_total_tables = 0;
+ long change, table_change;
+ GMetricsListIter iter;
+
+ if (combined_metrics_file)
+ g_metrics_file_start_record (combined_metrics_file);
+
+ if (metrics_file)
+ g_metrics_file_start_record (metrics_file);
+
+ G_LOCK (hash_tables);
+ g_metrics_list_iter_init (&iter, hash_tables_list);
+ while (g_metrics_list_iter_next (&iter, &hash_table))
+ {
+ glong new_items;
+
+ if (combined_metrics_file)
+ {
+ new_total_items += hash_table->nnodes;
+ new_total_tables++;
+ }
+
+ if (!metrics_file)
+ continue;
+
+ new_items = (glong) hash_table->nnodes - (glong) hash_table->last_sweep;
+ if (new_items != 0)
+ {
+ if (hash_table->last_sweep != 0)
+ g_metrics_file_add_row (metrics_file,
+ hash_table,
+ hash_table->nnodes,
+ new_items > 0 ? "+" : "",
+ new_items);
+ hash_table->last_sweep = hash_table->nnodes;
+ }
+ }
+ G_UNLOCK (hash_tables);
+
+ if (metrics_file)
+ g_metrics_file_end_record (metrics_file);
+ if (combined_metrics_file)
+ {
+ table_change = new_total_tables - old_total_tables;
+ change = new_total_items - old_total_items;
+
+ g_metrics_file_add_row (combined_metrics_file,
+ (gpointer) new_total_items,
+ change > 0? "+" : "",
+ change,
+ new_total_tables,
+ table_change > 0? "+" : "",
+ table_change);
+ g_metrics_file_end_record (combined_metrics_file);
+ }
+
+ old_total_items = new_total_items;
+ old_total_tables = new_total_tables;
+}
+
+static gboolean metrics_timeout_started;
+
+gboolean hide_hash = FALSE;
+
+void
+g_hide_hash (gboolean val)
+{
+ hide_hash = val;
+}
/**
* g_hash_table_new_full:
* @hash_func: a function to create a hash value from a key
@@ -713,10 +794,12 @@ g_hash_table_new_full (GHashFunc hash_func,
GDestroyNotify value_destroy_func)
{
GHashTable *hash_table;
+ gboolean needs_hash_table_metrics = FALSE, needs_hash_table_totals = FALSE;
HASH_TABLE_MIN_SHIFT = atoi(getenv ("G_HASH_TABLE_MIN_SHIFT")? : "3");
hash_table = g_slice_new (GHashTable);
g_hash_table_set_shift (hash_table, HASH_TABLE_MIN_SHIFT);
hash_table->nnodes = 0;
+ hash_table->last_sweep = 0;
hash_table->noccupied = 0;
hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
hash_table->key_equal_func = key_equal_func;
@@ -730,6 +813,45 @@ g_hash_table_new_full (GHashFunc hash_func,
hash_table->values = hash_table->keys;
hash_table->hashes = g_new0 (guint, hash_table->size);
+ if (!hide_hash)
+ {
+ G_LOCK (hash_tables);
+ if (g_metrics_enabled ())
+ {
+ if (hash_tables_list == NULL)
+ {
+ needs_hash_table_metrics = g_metrics_requested ("hash-tables");
+ needs_hash_table_totals = g_metrics_requested ("total-hash-tables");
+ hash_tables_list = g_metrics_list_new ();
+ }
+ g_metrics_list_add_item (hash_tables_list, hash_table);
+ }
+ G_UNLOCK (hash_tables);
+
+ if (!metrics_timeout_started)
+ {
+ metrics_timeout_started = TRUE;
+
+ if (needs_hash_table_metrics)
+ metrics_file = g_metrics_file_new ("hash-tables",
+ "address", "%p",
+ "total items", "%ld",
+ "total items change", "%s%ld",
+ NULL);
+
+ if (needs_hash_table_totals)
+ combined_metrics_file = g_metrics_file_new ("total-hash-tables",
+ "total items", "%ld",
+ "total items change", "%s%ld",
+ "total tables", "%ld",
+ "total tables changed", "%s%ld",
+ NULL);
+
+ if (needs_hash_table_metrics || needs_hash_table_totals)
+ g_metrics_start_timeout (on_hash_table_metrics_timeout);
+ }
+ }
+
return hash_table;
}
@@ -1105,6 +1227,10 @@ g_hash_table_unref (GHashTable *hash_table)
g_free (hash_table->values);
g_free (hash_table->keys);
g_free (hash_table->hashes);
+ G_LOCK (hash_tables);
+ if (hash_tables_list != NULL)
+ g_metrics_list_remove_item (hash_tables_list, hash_table);
+ G_UNLOCK (hash_tables);
g_slice_free (GHashTable, hash_table);
}
}
diff --git a/glib/ghash.h b/glib/ghash.h
index 5c8cb9195..7b2604578 100644
--- a/glib/ghash.h
+++ b/glib/ghash.h
@@ -143,6 +143,9 @@ GHashTable* g_hash_table_ref (GHashTable *hash_table);
GLIB_AVAILABLE_IN_ALL
void g_hash_table_unref (GHashTable *hash_table);
+GLIB_AVAILABLE_IN_ALL
+void g_hide_hash (gboolean val);
+
#ifndef G_DISABLE_DEPRECATED
#define g_hash_table_freeze(hash_table) ((void)0)
#define g_hash_table_thaw(hash_table) ((void)0)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]