summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Kost <ensonic@users.sf.net>2010-10-08 23:37:20 +0300
committerStefan Kost <ensonic@users.sf.net>2010-10-08 23:37:20 +0300
commit316061a12bba72f823cd92dc791b367547ab032a (patch)
treef863af73978311a951ea0763802d3ac29024cc85
parenteb7420970645235a72959fbb8cdc6aa3eba8d6c0 (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.c108
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)