mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
cogl/trace: Make each thread have its own trace context ref
This means that when we disable tracing, the writer will be kept alive until the last thread using it is disabled. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2998>
This commit is contained in:
parent
604aeba9b3
commit
dd3c1046c1
@ -43,6 +43,7 @@
|
||||
|
||||
struct _CoglTraceContext
|
||||
{
|
||||
gatomicrefcount ref_count;
|
||||
SysprofCaptureWriter *writer;
|
||||
};
|
||||
|
||||
@ -51,23 +52,24 @@ typedef struct _CoglTraceThreadContext
|
||||
int cpu_id;
|
||||
GPid pid;
|
||||
char *group;
|
||||
CoglTraceContext *trace_context;
|
||||
} CoglTraceThreadContext;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fd;
|
||||
char *filename;
|
||||
char *group;
|
||||
CoglTraceContext *trace_context;
|
||||
} TraceData;
|
||||
|
||||
static void cogl_trace_context_unref (CoglTraceContext *trace_context);
|
||||
|
||||
static void
|
||||
trace_data_free (gpointer user_data)
|
||||
{
|
||||
TraceData *data = user_data;
|
||||
|
||||
data->fd = -1;
|
||||
g_clear_pointer (&data->group, g_free);
|
||||
g_clear_pointer (&data->filename, g_free);
|
||||
g_clear_pointer (&data->trace_context, cogl_trace_context_unref);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
@ -102,27 +104,42 @@ cogl_trace_context_new (int fd,
|
||||
|
||||
context = g_new0 (CoglTraceContext, 1);
|
||||
context->writer = writer;
|
||||
g_atomic_ref_count_init (&context->ref_count);
|
||||
return context;
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_trace_context_free (CoglTraceContext *trace_context)
|
||||
cogl_trace_context_unref (CoglTraceContext *trace_context)
|
||||
{
|
||||
if (g_atomic_ref_count_dec (&trace_context->ref_count))
|
||||
{
|
||||
if (trace_context->writer)
|
||||
sysprof_capture_writer_flush (trace_context->writer);
|
||||
g_clear_pointer (&trace_context->writer, sysprof_capture_writer_unref);
|
||||
g_free (trace_context);
|
||||
}
|
||||
}
|
||||
|
||||
static CoglTraceContext *
|
||||
cogl_trace_context_ref (CoglTraceContext *trace_context)
|
||||
{
|
||||
g_atomic_ref_count_inc (&trace_context->ref_count);
|
||||
return trace_context;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_trace_context (TraceData *data)
|
||||
ensure_trace_context (int fd,
|
||||
const char *filename)
|
||||
{
|
||||
g_mutex_lock (&cogl_trace_mutex);
|
||||
if (!cogl_trace_context)
|
||||
cogl_trace_context = cogl_trace_context_new (data->fd, data->filename);
|
||||
cogl_trace_context = cogl_trace_context_new (fd, filename);
|
||||
g_mutex_unlock (&cogl_trace_mutex);
|
||||
}
|
||||
|
||||
static CoglTraceThreadContext *
|
||||
cogl_trace_thread_context_new (const char *group)
|
||||
cogl_trace_thread_context_new (const char *group,
|
||||
CoglTraceContext *trace_context)
|
||||
{
|
||||
CoglTraceThreadContext *thread_context;
|
||||
pid_t tid;
|
||||
@ -134,6 +151,7 @@ cogl_trace_thread_context_new (const char *group)
|
||||
thread_context->pid = getpid ();
|
||||
thread_context->group =
|
||||
group ? g_strdup (group) : g_strdup_printf ("t:%d", tid);
|
||||
thread_context->trace_context = cogl_trace_context_ref (trace_context);
|
||||
|
||||
return thread_context;
|
||||
}
|
||||
@ -145,15 +163,14 @@ enable_tracing_idle_callback (gpointer user_data)
|
||||
g_private_get (&cogl_trace_thread_data);
|
||||
TraceData *data = user_data;
|
||||
|
||||
ensure_trace_context (data);
|
||||
|
||||
if (thread_context)
|
||||
{
|
||||
g_warning ("Tracing already enabled");
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
thread_context = cogl_trace_thread_context_new (data->group);
|
||||
thread_context = cogl_trace_thread_context_new (data->group,
|
||||
data->trace_context);
|
||||
g_private_set (&cogl_trace_thread_data, thread_context);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
@ -176,7 +193,6 @@ disable_tracing_idle_callback (gpointer user_data)
|
||||
{
|
||||
CoglTraceThreadContext *thread_context =
|
||||
g_private_get (&cogl_trace_thread_data);
|
||||
CoglTraceContext *trace_context;
|
||||
|
||||
if (!thread_context)
|
||||
{
|
||||
@ -186,14 +202,6 @@ disable_tracing_idle_callback (gpointer user_data)
|
||||
|
||||
g_private_replace (&cogl_trace_thread_data, NULL);
|
||||
|
||||
g_mutex_lock (&cogl_trace_mutex);
|
||||
trace_context = cogl_trace_context;
|
||||
sysprof_capture_writer_flush (trace_context->writer);
|
||||
|
||||
g_clear_pointer (&cogl_trace_context, cogl_trace_context_free);
|
||||
|
||||
g_mutex_unlock (&cogl_trace_mutex);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
@ -205,10 +213,11 @@ set_tracing_enabled_on_thread (GMainContext *main_context,
|
||||
{
|
||||
TraceData *data;
|
||||
|
||||
ensure_trace_context (fd, filename);
|
||||
|
||||
data = g_new0 (TraceData, 1);
|
||||
data->fd = fd;
|
||||
data->group = group ? strdup (group) : NULL;
|
||||
data->filename = filename ? strdup (filename) : NULL;
|
||||
data->trace_context = cogl_trace_context_ref (cogl_trace_context);
|
||||
|
||||
if (main_context == g_main_context_get_thread_default ())
|
||||
{
|
||||
@ -249,6 +258,10 @@ cogl_set_tracing_enabled_on_thread (GMainContext *main_context,
|
||||
void
|
||||
cogl_set_tracing_disabled_on_thread (GMainContext *main_context)
|
||||
{
|
||||
g_mutex_lock (&cogl_trace_mutex);
|
||||
g_clear_pointer (&cogl_trace_context, cogl_trace_context_unref);
|
||||
g_mutex_unlock (&cogl_trace_mutex);
|
||||
|
||||
if (g_main_context_get_thread_default () == main_context)
|
||||
{
|
||||
disable_tracing_idle_callback (NULL);
|
||||
@ -275,8 +288,8 @@ cogl_trace_end_with_description (CoglTraceHead *head,
|
||||
CoglTraceThreadContext *trace_thread_context;
|
||||
|
||||
end_time = g_get_monotonic_time () * 1000;
|
||||
trace_context = cogl_trace_context;
|
||||
trace_thread_context = g_private_get (&cogl_trace_thread_data);
|
||||
trace_context = trace_thread_context->trace_context;
|
||||
|
||||
g_mutex_lock (&cogl_trace_mutex);
|
||||
if (!sysprof_capture_writer_add_mark (trace_context->writer,
|
||||
|
Loading…
Reference in New Issue
Block a user