mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 01:50: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
|
struct _CoglTraceContext
|
||||||
{
|
{
|
||||||
|
gatomicrefcount ref_count;
|
||||||
SysprofCaptureWriter *writer;
|
SysprofCaptureWriter *writer;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,23 +52,24 @@ typedef struct _CoglTraceThreadContext
|
|||||||
int cpu_id;
|
int cpu_id;
|
||||||
GPid pid;
|
GPid pid;
|
||||||
char *group;
|
char *group;
|
||||||
|
CoglTraceContext *trace_context;
|
||||||
} CoglTraceThreadContext;
|
} CoglTraceThreadContext;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int fd;
|
|
||||||
char *filename;
|
|
||||||
char *group;
|
char *group;
|
||||||
|
CoglTraceContext *trace_context;
|
||||||
} TraceData;
|
} TraceData;
|
||||||
|
|
||||||
|
static void cogl_trace_context_unref (CoglTraceContext *trace_context);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
trace_data_free (gpointer user_data)
|
trace_data_free (gpointer user_data)
|
||||||
{
|
{
|
||||||
TraceData *data = user_data;
|
TraceData *data = user_data;
|
||||||
|
|
||||||
data->fd = -1;
|
|
||||||
g_clear_pointer (&data->group, g_free);
|
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);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,27 +104,42 @@ cogl_trace_context_new (int fd,
|
|||||||
|
|
||||||
context = g_new0 (CoglTraceContext, 1);
|
context = g_new0 (CoglTraceContext, 1);
|
||||||
context->writer = writer;
|
context->writer = writer;
|
||||||
|
g_atomic_ref_count_init (&context->ref_count);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cogl_trace_context_free (CoglTraceContext *trace_context)
|
cogl_trace_context_unref (CoglTraceContext *trace_context)
|
||||||
{
|
{
|
||||||
g_clear_pointer (&trace_context->writer, sysprof_capture_writer_unref);
|
if (g_atomic_ref_count_dec (&trace_context->ref_count))
|
||||||
g_free (trace_context);
|
{
|
||||||
|
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
|
static void
|
||||||
ensure_trace_context (TraceData *data)
|
ensure_trace_context (int fd,
|
||||||
|
const char *filename)
|
||||||
{
|
{
|
||||||
g_mutex_lock (&cogl_trace_mutex);
|
g_mutex_lock (&cogl_trace_mutex);
|
||||||
if (!cogl_trace_context)
|
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);
|
g_mutex_unlock (&cogl_trace_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglTraceThreadContext *
|
static CoglTraceThreadContext *
|
||||||
cogl_trace_thread_context_new (const char *group)
|
cogl_trace_thread_context_new (const char *group,
|
||||||
|
CoglTraceContext *trace_context)
|
||||||
{
|
{
|
||||||
CoglTraceThreadContext *thread_context;
|
CoglTraceThreadContext *thread_context;
|
||||||
pid_t tid;
|
pid_t tid;
|
||||||
@ -134,6 +151,7 @@ cogl_trace_thread_context_new (const char *group)
|
|||||||
thread_context->pid = getpid ();
|
thread_context->pid = getpid ();
|
||||||
thread_context->group =
|
thread_context->group =
|
||||||
group ? g_strdup (group) : g_strdup_printf ("t:%d", tid);
|
group ? g_strdup (group) : g_strdup_printf ("t:%d", tid);
|
||||||
|
thread_context->trace_context = cogl_trace_context_ref (trace_context);
|
||||||
|
|
||||||
return thread_context;
|
return thread_context;
|
||||||
}
|
}
|
||||||
@ -145,15 +163,14 @@ enable_tracing_idle_callback (gpointer user_data)
|
|||||||
g_private_get (&cogl_trace_thread_data);
|
g_private_get (&cogl_trace_thread_data);
|
||||||
TraceData *data = user_data;
|
TraceData *data = user_data;
|
||||||
|
|
||||||
ensure_trace_context (data);
|
|
||||||
|
|
||||||
if (thread_context)
|
if (thread_context)
|
||||||
{
|
{
|
||||||
g_warning ("Tracing already enabled");
|
g_warning ("Tracing already enabled");
|
||||||
return G_SOURCE_REMOVE;
|
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);
|
g_private_set (&cogl_trace_thread_data, thread_context);
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
@ -176,7 +193,6 @@ disable_tracing_idle_callback (gpointer user_data)
|
|||||||
{
|
{
|
||||||
CoglTraceThreadContext *thread_context =
|
CoglTraceThreadContext *thread_context =
|
||||||
g_private_get (&cogl_trace_thread_data);
|
g_private_get (&cogl_trace_thread_data);
|
||||||
CoglTraceContext *trace_context;
|
|
||||||
|
|
||||||
if (!thread_context)
|
if (!thread_context)
|
||||||
{
|
{
|
||||||
@ -186,14 +202,6 @@ disable_tracing_idle_callback (gpointer user_data)
|
|||||||
|
|
||||||
g_private_replace (&cogl_trace_thread_data, NULL);
|
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;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,10 +213,11 @@ set_tracing_enabled_on_thread (GMainContext *main_context,
|
|||||||
{
|
{
|
||||||
TraceData *data;
|
TraceData *data;
|
||||||
|
|
||||||
|
ensure_trace_context (fd, filename);
|
||||||
|
|
||||||
data = g_new0 (TraceData, 1);
|
data = g_new0 (TraceData, 1);
|
||||||
data->fd = fd;
|
|
||||||
data->group = group ? strdup (group) : NULL;
|
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 ())
|
if (main_context == g_main_context_get_thread_default ())
|
||||||
{
|
{
|
||||||
@ -249,6 +258,10 @@ cogl_set_tracing_enabled_on_thread (GMainContext *main_context,
|
|||||||
void
|
void
|
||||||
cogl_set_tracing_disabled_on_thread (GMainContext *main_context)
|
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)
|
if (g_main_context_get_thread_default () == main_context)
|
||||||
{
|
{
|
||||||
disable_tracing_idle_callback (NULL);
|
disable_tracing_idle_callback (NULL);
|
||||||
@ -275,8 +288,8 @@ cogl_trace_end_with_description (CoglTraceHead *head,
|
|||||||
CoglTraceThreadContext *trace_thread_context;
|
CoglTraceThreadContext *trace_thread_context;
|
||||||
|
|
||||||
end_time = g_get_monotonic_time () * 1000;
|
end_time = g_get_monotonic_time () * 1000;
|
||||||
trace_context = cogl_trace_context;
|
|
||||||
trace_thread_context = g_private_get (&cogl_trace_thread_data);
|
trace_thread_context = g_private_get (&cogl_trace_thread_data);
|
||||||
|
trace_context = trace_thread_context->trace_context;
|
||||||
|
|
||||||
g_mutex_lock (&cogl_trace_mutex);
|
g_mutex_lock (&cogl_trace_mutex);
|
||||||
if (!sysprof_capture_writer_add_mark (trace_context->writer,
|
if (!sysprof_capture_writer_add_mark (trace_context->writer,
|
||||||
|
Loading…
Reference in New Issue
Block a user