diff options
author | Stefan Kost <ensonic@users.sf.net> | 2010-10-08 23:37:20 +0300 |
---|---|---|
committer | Stefan Kost <ensonic@users.sf.net> | 2010-10-08 23:37:20 +0300 |
commit | 316061a12bba72f823cd92dc791b367547ab032a (patch) | |
tree | f863af73978311a951ea0763802d3ac29024cc85 | |
parent | eb7420970645235a72959fbb8cdc6aa3eba8d6c0 (diff) |
tracelib: rework stats storage
Instead of the sequence number set the statistics as a qdata iteam on the
objects. Store the statistics in a GPtrArray instead of GHashTables for later
processing.
-rw-r--r-- | src/gsttracelib.c | 108 |
1 files changed, 53 insertions, 55 deletions
diff --git a/src/gsttracelib.c b/src/gsttracelib.c index b991393..80b09a5 100644 --- a/src/gsttracelib.c +++ b/src/gsttracelib.c @@ -86,9 +86,9 @@ static gboolean gsttl_do_log_topo = TRUE; /* global statistics */ static GHashTable *threads = NULL; -static GHashTable *elements = NULL; -static GHashTable *bins = NULL; -static GHashTable *pads = NULL; +static GPtrArray *elements = NULL; +static GPtrArray *bins = NULL; +static GPtrArray *pads = NULL; static guint max_qos = 0; static gboolean check_cpuload = FALSE; static guint max_cpuload = 0; @@ -105,7 +105,7 @@ static GstClockTime areal = G_GUINT64_CONSTANT(0); #define GSTTL_TIME_AS_SECOND(t) ((gdouble)t/(gdouble)GST_SECOND) /* for statistics */ -static GQuark idquark; +static GQuark data_quark; G_LOCK_DEFINE (_stats); typedef struct { @@ -139,7 +139,7 @@ typedef struct { /* time spend in this element */ GstClockTime treal; /* hierarchy */ - gpointer parent_id; + guint parent_ix; } GsttlElementStats; typedef struct { @@ -455,43 +455,43 @@ _fill_element_stats (GstElement *element) GsttlElementStats *stats = g_new0(GsttlElementStats,1); if(GST_IS_BIN(element)) { - num_bins++; + stats->index = num_bins++; + } else { + stats->index = num_elements++; } - stats->index = num_elements++; stats->type = G_OBJECT_TYPE (element); stats->first_ts = GST_CLOCK_TIME_NONE; + stats->parent_ix = G_MAXUINT; return stats; } static GsttlElementStats* -_get_bin_stats_by_id (gpointer id) +_get_bin_stats_by_id (guint ix) { - return g_hash_table_lookup (bins, id); + return g_ptr_array_index (bins, ix); } static GsttlElementStats* _get_bin_stats (GstElement *element); static inline GsttlElementStats* -_get_bin_or_element_stats (GstElement *element, GHashTable *ht) +_get_bin_or_element_stats (GstElement *element, GPtrArray *arr) { GsttlElementStats *stats; - gpointer id; G_LOCK (_stats); - id = g_object_get_qdata ((GObject *)element, idquark); - stats = id ? g_hash_table_lookup (ht, id) : NULL; - if (!id || !stats) { - id = GUINT_TO_POINTER (num_elements+1); + if (!(stats = g_object_get_qdata ((GObject *)element, data_quark))) { stats = _fill_element_stats (element); - g_object_set_qdata ((GObject *)element, idquark, id); - g_hash_table_insert (ht, id, (gpointer)stats); + g_object_set_qdata ((GObject *)element, data_quark, stats); + if (arr->len <= stats->index) + g_ptr_array_set_size (arr, stats->index+1); + g_ptr_array_index (arr, stats->index) = stats; } G_UNLOCK (_stats); - if(G_UNLIKELY(!stats->parent_id)) { + if(G_UNLIKELY(stats->parent_ix == G_MAXUINT)) { GstElement *parent = GST_ELEMENT_PARENT (element); if(parent) { GsttlElementStats *parent_stats = _get_bin_stats (parent); - stats->parent_id = GUINT_TO_POINTER (parent_stats->index + 1); + stats->parent_ix = parent_stats->index; } } if(G_UNLIKELY(!stats->name)) { @@ -573,7 +573,6 @@ static GsttlPadStats* _get_pad_stats (GstPad *pad) { GsttlPadStats *stats; - gpointer id; if(!pad) return NULL; @@ -581,13 +580,12 @@ _get_pad_stats (GstPad *pad) //g_assert(GST_IS_PAD(pad)); G_LOCK (_stats); - id = g_object_get_qdata ((GObject *)pad, idquark); - stats = id ? g_hash_table_lookup (pads, id) : NULL; - if (!id || !stats) { - id = GUINT_TO_POINTER (num_pads+1); + if (!(stats = g_object_get_qdata ((GObject *)pad, data_quark))) { stats = _fill_pad_stats (pad); - g_object_set_qdata ((GObject *)pad, idquark, id); - g_hash_table_insert (pads, id, (gpointer)stats); + g_object_set_qdata ((GObject *)pad, data_quark, stats); + if (pads->len <= stats->index) + g_ptr_array_set_size (pads, stats->index+1); + g_ptr_array_index (pads, stats->index) = stats; } G_UNLOCK (_stats); if(G_UNLIKELY(!stats->name)) { @@ -768,8 +766,8 @@ _accum_element_stats (gpointer value, gpointer user_data) { GsttlElementStats *stats=(GsttlElementStats *)value; - if (stats->parent_id) { - GsttlElementStats *parent_stats = _get_bin_stats_by_id (stats->parent_id); + if (stats->parent_ix != G_MAXUINT) { + GsttlElementStats *parent_stats = _get_bin_stats_by_id (stats->parent_ix); parent_stats->num_events += stats->num_events; parent_stats->num_messages += stats->num_messages; @@ -798,7 +796,7 @@ _sort_pad_stats_by_first_activity (gconstpointer es1, gconstpointer es2) } static void -_sort_pad_stats (gpointer key, gpointer value, gpointer user_data) +_sort_pad_stats (gpointer value, gpointer user_data) { GSList **list=user_data; @@ -812,27 +810,19 @@ _sort_element_stats_by_first_activity (gconstpointer es1, gconstpointer es2) } static void -_sort_element_stats (gpointer key, gpointer value, gpointer user_data) +_sort_element_stats (gpointer value, gpointer user_data) { GSList **list=user_data; *list = g_slist_insert_sorted (*list, value, _sort_element_stats_by_first_activity); } -static void -_copy_bin_stats (gpointer key, gpointer value, gpointer user_data) -{ - GHashTable **accum_bins=user_data; - - g_hash_table_insert (*accum_bins, key, value); -} - static gboolean _check_bin_parent (gpointer key, gpointer value, gpointer user_data) { GsttlElementStats *stats=(GsttlElementStats *)value; - return (stats->parent_id == user_data); + return (stats->parent_ix == GPOINTER_TO_UINT(user_data)); } static gboolean @@ -840,7 +830,9 @@ _process_leaf_bins (gpointer key, gpointer value, gpointer user_data) { GHashTable *accum_bins = user_data; + /* if we find no bin that has this bin as a parent ... */ if (!g_hash_table_find (accum_bins, _check_bin_parent, key)) { + /* accumulate stats to the parent and remove */ _accum_element_stats(value,NULL); return TRUE; } @@ -1809,11 +1801,11 @@ gst_preload_init (void) } /* init structures to gather stats */ - idquark = g_quark_from_static_string ("gsttl:id"); + data_quark = g_quark_from_static_string ("gsttl:data"); + elements = g_ptr_array_new_with_free_func ((GDestroyNotify)g_free); + bins = g_ptr_array_new_with_free_func ((GDestroyNotify)g_free); + pads = g_ptr_array_new_with_free_func ((GDestroyNotify)g_free); threads = g_hash_table_new_full (NULL,NULL,NULL,(GDestroyNotify)g_free); - elements = g_hash_table_new_full (NULL,NULL,NULL,(GDestroyNotify)g_free); - bins = g_hash_table_new_full (NULL,NULL,NULL,(GDestroyNotify)g_free); - pads = g_hash_table_new_full (NULL,NULL,NULL,(GDestroyNotify)g_free); /* load library (abort if not found) */ lib_gstreamer = dlopen ("libgstreamer-0.10.so", RTLD_LAZY); @@ -1866,6 +1858,7 @@ gst_preload_done (void) { GstClockTimeDiff treal = _get_elapsed(); guint cpuload = 0; + guint num_threads; /* no statistics wanted */ if(gsttl_no_stats) @@ -1878,11 +1871,13 @@ gst_preload_done (void) if(tusersys) { cpuload = (guint) gst_util_uint64_scale (tusersys, G_GINT64_CONSTANT(100), last_ts); } + + num_threads = g_hash_table_size(threads); /* print overall stats */ puts("\nOverall Statistics:"); - printf("Number of Threads: %u\n", g_hash_table_size(threads)); - printf("Number of Elements: %u\n", num_elements - num_bins); + printf("Number of Threads: %u\n", num_threads); + printf("Number of Elements: %u\n", num_elements); printf("Number of Bins: %u\n", num_bins); printf("Number of Pads: %u\n", num_pads - num_ghostpads); printf("Number of GhostPads: %u\n", num_ghostpads); @@ -1896,10 +1891,10 @@ gst_preload_done (void) printf("Max Memory usage: %u kb\n\n", max_memory); /* foreach pad */ - if (g_hash_table_size(threads)) { + if (num_threads) { GSList *list=NULL; - g_hash_table_foreach(pads,_sort_pad_stats,&list); + g_ptr_array_foreach(pads,_sort_pad_stats,&list); //g_slist_foreach(list,_print_thread_stats, NULL); g_hash_table_foreach(threads,_print_thread_stats,list); puts(""); @@ -1907,12 +1902,12 @@ gst_preload_done (void) } /* foreach element */ - if (g_hash_table_size(elements)) { + if (num_elements) { GSList *list=NULL; puts("Element Statistics:"); /* sort by first_activity */ - g_hash_table_foreach(elements,_sort_element_stats,&list); + g_ptr_array_foreach(elements,_sort_element_stats,&list); /* attribute element stats to bins */ g_slist_foreach(list,_accum_element_stats, NULL); g_slist_foreach(list,_print_element_stats, NULL); @@ -1921,19 +1916,22 @@ gst_preload_done (void) } /* foreach bin */ - if (g_hash_table_size(bins)) { + if (num_bins) { GSList *list=NULL; + guint i; GHashTable *accum_bins = g_hash_table_new_full (NULL,NULL,NULL,NULL); puts("Bin Statistics:"); /* attribute bin stats to parent-bins */ - g_hash_table_foreach (bins, _copy_bin_stats, &accum_bins); + for (i = 0; i < num_bins; i++) { + g_hash_table_insert (accum_bins, GUINT_TO_POINTER(i), g_ptr_array_index (bins, i)); + } while(g_hash_table_size (accum_bins)) { g_hash_table_foreach_remove (accum_bins, _process_leaf_bins, accum_bins); } g_hash_table_destroy (accum_bins); /* sort by first_activity */ - g_hash_table_foreach(bins,_sort_element_stats,&list); + g_ptr_array_foreach(bins,_sort_element_stats,&list); g_slist_foreach(list,_print_element_stats, NULL); puts(""); g_slist_free(list); @@ -1962,9 +1960,9 @@ done: } g_free (log_buf); } - g_hash_table_destroy (pads); - g_hash_table_destroy (bins); - g_hash_table_destroy (elements); + g_ptr_array_free (pads, TRUE); + g_ptr_array_free (bins, TRUE); + g_ptr_array_free (elements, TRUE); g_hash_table_destroy (threads); if(lib_gstreamer) |