}
static void
-send_latency_probe (GstLatencyTracer * self, GstElement * parent, GstPad * pad,
- guint64 ts)
+send_latency_probe (GstElement * parent, GstPad * pad, guint64 ts)
{
if (parent && (!GST_IS_BIN (parent)) &&
GST_OBJECT_FLAG_IS_SET (parent, GST_ELEMENT_FLAG_SOURCE)) {
GstPad *pad = va_arg (var_args, GstPad *);
GstElement *parent = get_real_pad_parent (pad);
- send_latency_probe ((GstLatencyTracer *) self, parent, pad, ts);
+ send_latency_probe (parent, pad, ts);
}
static void
GstPad *peer_pad = GST_PAD_PEER (pad);
GstElement *parent = get_real_pad_parent (peer_pad);
- send_latency_probe ((GstLatencyTracer *) self, parent, peer_pad, ts);
+ send_latency_probe (parent, peer_pad, ts);
}
static void
-calculate_latency (GstLatencyTracer * self, GstElement * parent, GstPad * pad,
- guint64 ts)
+calculate_latency (GstElement * parent, GstPad * pad, guint64 ts)
{
if (parent && (!GST_IS_BIN (parent)) &&
GST_OBJECT_FLAG_IS_SET (parent, GST_ELEMENT_FLAG_SINK)) {
GstPad *peer_pad = GST_PAD_PEER (pad);
GstElement *parent = get_real_pad_parent (peer_pad);
- calculate_latency ((GstLatencyTracer *) self, parent, peer_pad, ts);
+ calculate_latency (parent, peer_pad, ts);
}
static void
GstPad *pad = va_arg (var_args, GstPad *);
GstElement *parent = get_real_pad_parent (pad);
- calculate_latency ((GstLatencyTracer *) self, parent, pad, ts);
+ calculate_latency (parent, pad, ts);
}
static void
GST_DEBUG_CATEGORY_STATIC (gst_rusage_debug);
#define GST_CAT_DEFAULT gst_rusage_debug
+G_LOCK_DEFINE (_proc);
+
#define _do_init \
GST_DEBUG_CATEGORY_INIT (gst_rusage_debug, "rusage", 0, "rusage tracer");
#define gst_rusage_tracer_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstRUsageTracer, gst_rusage_tracer, GST_TYPE_TRACER,
_do_init);
-/* we remember x measurements per self->window */
+/* remember x measurements per self->window */
#define WINDOW_SUBDIV 100
-/* for ts calibration */
-static gpointer main_thread_id = NULL;
-static guint64 tproc_base = G_GINT64_CONSTANT (0);
+/* number of cpus to scale cpu-usage in threads */
static glong num_cpus = 1;
typedef struct
{
- GstClockTime ts;
- GstClockTime val;
-} GstTraceValue;
-
-typedef struct
-{
- GstClockTime window;
- GMutex lock;
- GQueue values; /* GstTraceValue* */
-} GstTraceValues;
-
-typedef struct
-{
/* time spend in this thread */
GstClockTime tthread;
GstTraceValues *tvs_thread;
} GstThreadStats;
-static GstTraceValues *tvs_proc;
-
/* data helper */
static void
{
GstTraceValues *self = g_slice_new0 (GstTraceValues);
self->window = window;
- g_mutex_init (&self->lock);
g_queue_init (&self->values);
return self;
}
free_trace_values (GstTraceValues * self)
{
g_queue_free_full (&self->values, free_trace_value);
- g_mutex_clear (&self->lock);
g_slice_free (GstTraceValues, self);
}
* the time is larger than ts, as our base-ts is taken after the process has
* started.
*/
- if (G_UNLIKELY (thread_id == main_thread_id)) {
- main_thread_id = NULL;
+ if (G_UNLIKELY (thread_id == self->main_thread_id)) {
+ self->main_thread_id = NULL;
/* when the registry gets updated, the tproc is less than the debug time ? */
/* TODO(ensonic): we still see cases where tproc overtakes ts, especially
* when with sync=false, can this be due to multiple cores in use? */
if (tproc > ts) {
- tproc_base = tproc - ts;
+ self->tproc_base = tproc - ts;
GST_DEBUG ("rusage: calibrating by %" G_GUINT64_FORMAT ", thread: %"
G_GUINT64_FORMAT ", proc: %" G_GUINT64_FORMAT,
- tproc_base, stats->tthread, tproc);
- stats->tthread -= tproc_base;
+ self->tproc_base, stats->tthread, tproc);
+ stats->tthread -= self->tproc_base;
}
}
/* we always need to correct proc time */
- tproc -= tproc_base;
+ tproc -= self->tproc_base;
/* FIXME: how can we take cpu-frequency scaling into account?
* - looking at /sys/devices/system/cpu/cpu0/cpufreq/
avg_cpuload = (guint) gst_util_uint64_scale (tproc / num_cpus,
G_GINT64_CONSTANT (1000), ts);
- g_mutex_lock (&tvs_proc->lock);
- update_trace_value (tvs_proc, ts, tproc, &dts, &dtproc);
- g_mutex_unlock (&tvs_proc->lock);
+ G_LOCK (_proc);
+ update_trace_value (self->tvs_proc, ts, tproc, &dts, &dtproc);
+ G_UNLOCK (_proc);
cur_cpuload = (guint) gst_util_uint64_scale (dtproc / num_cpus,
G_GINT64_CONSTANT (1000), dts);
gst_tracer_log_trace (gst_structure_new ("proc-rusage",
/* tracer class */
static void
+gst_rusage_tracer_finalize (GObject * obj)
+{
+ GstRUsageTracer *self = GST_RUSAGE_TRACER (obj);
+
+ g_hash_table_destroy (self->threads);
+ free_trace_values (self->tvs_proc);
+
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
gst_rusage_tracer_class_init (GstRUsageTracerClass * klass)
{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = gst_rusage_tracer_finalize;
+
+ if ((num_cpus = sysconf (_SC_NPROCESSORS_ONLN)) == -1) {
+ GST_WARNING ("failed to get number of cpus online");
+ if ((num_cpus = sysconf (_SC_NPROCESSORS_CONF)) == -1) {
+ GST_WARNING ("failed to get number of cpus, assuming 1");
+ num_cpus = 1;
+ }
+ }
+ GST_DEBUG ("rusage: num_cpus=%ld", num_cpus);
+
/* announce trace formats */
/* *INDENT-OFF* */
gst_tracer_log_trace (gst_structure_new ("thread-rusage.class",
gst_tracer_register_hook_id (tracer, 0, do_stats);
self->threads = g_hash_table_new_full (NULL, NULL, NULL, free_thread_stats);
+ self->tvs_proc = make_trace_values (GST_SECOND);
+ self->main_thread_id = g_thread_self ();
- main_thread_id = g_thread_self ();
- tvs_proc = make_trace_values (GST_SECOND);
- if ((num_cpus = sysconf (_SC_NPROCESSORS_ONLN)) == -1) {
- GST_WARNING_OBJECT (self, "failed to get number of cpus online");
- if ((num_cpus = sysconf (_SC_NPROCESSORS_CONF)) == -1) {
- GST_WARNING_OBJECT (self, "failed to get number of cpus, assuming 1");
- num_cpus = 1;
- }
- }
- GST_DEBUG ("rusage: main thread=%p, num_cpus=%ld", main_thread_id, num_cpus);
+ GST_DEBUG ("rusage: main thread=%p", self->main_thread_id);
}
typedef struct _GstRUsageTracer GstRUsageTracer;
typedef struct _GstRUsageTracerClass GstRUsageTracerClass;
+typedef struct
+{
+ GstClockTime ts;
+ GstClockTime val;
+} GstTraceValue;
+
+typedef struct
+{
+ GstClockTime window;
+ GQueue values; /* GstTraceValue* */
+} GstTraceValues;
+
/**
* GstRUsageTracer:
*
/*< private >*/
GHashTable *threads;
+ GstTraceValues *tvs_proc;
+
+ /* for ts calibration */
+ gpointer main_thread_id;
+ guint64 tproc_base;
};
struct _GstRUsageTracerClass {
#define GST_CAT_DEFAULT gst_stats_debug
static GQuark data_quark;
-G_LOCK_DEFINE (_stats);
+G_LOCK_DEFINE (_elem_stats);
+G_LOCK_DEFINE (_pad_stats);
#define _do_init \
GST_DEBUG_CATEGORY_INIT (gst_stats_debug, "stats", 0, "stats tracer"); \
"is-bin", G_TYPE_BOOLEAN, GST_IS_BIN (element), NULL));
}
+static void
+free_element_stats (gpointer data)
+{
+ g_slice_free (GstElementStats, data);
+}
+
static inline GstElementStats *
get_element_stats (GstStatsTracer * self, GstElement * element)
{
return &no_elem_stats;
}
- G_LOCK (_stats);
+ G_LOCK (_elem_stats);
if (!(stats = g_object_get_qdata ((GObject *) element, data_quark))) {
stats = fill_element_stats (self, element);
- g_object_set_qdata ((GObject *) element, data_quark, stats);
- if (self->elements->len <= stats->index)
- g_ptr_array_set_size (self->elements, stats->index + 1);
- g_ptr_array_index (self->elements, stats->index) = stats;
+ g_object_set_qdata_full ((GObject *) element, data_quark, stats,
+ free_element_stats);
is_new = TRUE;
}
- G_UNLOCK (_stats);
+ G_UNLOCK (_elem_stats);
if (G_UNLIKELY (stats->parent_ix == G_MAXUINT)) {
GstElement *parent = GST_ELEMENT_PARENT (element);
if (parent) {
return stats;
}
-static void
-free_element_stats (gpointer data)
-{
- g_slice_free (GstElementStats, data);
-}
-
/*
* Get the element/bin owning the pad.
*
"thread-id", G_TYPE_UINT, GPOINTER_TO_UINT (g_thread_self ()), NULL));
}
+static void
+free_pad_stats (gpointer data)
+{
+ g_slice_free (GstPadStats, data);
+}
+
static GstPadStats *
get_pad_stats (GstStatsTracer * self, GstPad * pad)
{
return &no_pad_stats;
}
- G_LOCK (_stats);
+ G_LOCK (_pad_stats);
if (!(stats = g_object_get_qdata ((GObject *) pad, data_quark))) {
stats = fill_pad_stats (self, pad);
- g_object_set_qdata ((GObject *) pad, data_quark, stats);
- if (self->pads->len <= stats->index)
- g_ptr_array_set_size (self->pads, stats->index + 1);
- g_ptr_array_index (self->pads, stats->index) = stats;
+ g_object_set_qdata_full ((GObject *) pad, data_quark, stats,
+ free_pad_stats);
is_new = TRUE;
}
- G_UNLOCK (_stats);
+ G_UNLOCK (_pad_stats);
if (G_UNLIKELY (stats->parent_ix == G_MAXUINT)) {
GstElement *elem = get_real_pad_parent (pad);
if (elem) {
}
static void
-free_pad_stats (gpointer data)
-{
- g_slice_free (GstPadStats, data);
-}
-
-static void
do_buffer_stats (GstStatsTracer * self, GstPad * this_pad,
GstPadStats * this_pad_stats, GstPad * that_pad,
GstPadStats * that_pad_stats, GstBuffer * buf, GstClockTime elapsed)
}
static void
-do_push_event_post (GstStatsTracer * self, va_list var_args)
-{
-#if 0
- guint64 ts = va_arg (var_args, guint64);
- GstPad *pad = va_arg (var_args, GstPad *);
-#endif
-}
-
-static void
do_post_message_pre (GstStatsTracer * self, va_list var_args)
{
guint64 ts = va_arg (var_args, guint64);
}
static void
-do_post_message_post (GstStatsTracer * self, va_list var_args)
-{
-#if 0
- guint64 ts = va_arg (var_args, guint64);
- GstElement *elem = va_arg (var_args, GstElement *);
-#endif
-}
-
-static void
do_query_pre (GstStatsTracer * self, va_list var_args)
{
guint64 ts = va_arg (var_args, guint64);
"name", G_TYPE_STRING, GST_QUERY_TYPE_NAME (qry), NULL));
}
-static void
-do_query_post (GstStatsTracer * self, va_list var_args)
-{
-#if 0
- guint64 ts = va_arg (var_args, guint64);
- GstElement *elem = va_arg (var_args, GstElement *);
-#endif
-}
-
/* tracer class */
static void
(GstTracerHookFunction) do_pull_range_post);
gst_tracer_register_hook (tracer, "pad-push-event-pre",
(GstTracerHookFunction) do_push_event_pre);
- gst_tracer_register_hook (tracer, "pad-push-event-post",
- (GstTracerHookFunction) do_push_event_post);
gst_tracer_register_hook (tracer, "element-post-message-pre",
(GstTracerHookFunction) do_post_message_pre);
- gst_tracer_register_hook (tracer, "element-post-message-post",
- (GstTracerHookFunction) do_post_message_post);
gst_tracer_register_hook (tracer, "element-query-pre",
(GstTracerHookFunction) do_query_pre);
- gst_tracer_register_hook (tracer, "element-query-post",
- (GstTracerHookFunction) do_query_post);
-
- self->elements = g_ptr_array_new_with_free_func (free_element_stats);
- self->pads = g_ptr_array_new_with_free_func (free_pad_stats);
}
GstTracer parent;
/*< private >*/
- GPtrArray *elements;
- GPtrArray *pads;
guint num_elements, num_pads;
};