mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 15:36:14 +01:00
Merge branch 'sysprof' into 'master'
Add initial sysprof support See merge request GNOME/glib!1551
This commit is contained in:
commit
4486ac1448
@ -22,6 +22,7 @@ if get_option('gtk_doc')
|
||||
'gprintfint.h',
|
||||
'gmirroringtable.h',
|
||||
'gscripttable.h',
|
||||
'gtrace-private.h',
|
||||
'glib-mirroring-tab',
|
||||
'gnulib',
|
||||
'pcre',
|
||||
|
@ -87,6 +87,7 @@
|
||||
* GTask *task;
|
||||
*
|
||||
* task = g_task_new (initable, cancellable, callback, user_data);
|
||||
* g_task_set_name (task, G_STRFUNC);
|
||||
*
|
||||
* switch (self->priv->state)
|
||||
* {
|
||||
|
@ -632,6 +632,7 @@ g_dbus_interface_method_dispatch_helper (GDBusInterfaceSkeleton *interface
|
||||
|
||||
task = g_task_new (interface, NULL, NULL, NULL);
|
||||
g_task_set_source_tag (task, g_dbus_interface_method_dispatch_helper);
|
||||
g_task_set_name (task, "[gio] D-Bus interface method dispatch");
|
||||
g_task_set_task_data (task, data, (GDestroyNotify) dispatch_data_unref);
|
||||
g_task_run_in_thread (task, dispatch_in_thread_func);
|
||||
g_object_unref (task);
|
||||
|
@ -183,6 +183,7 @@ _g_socket_read_with_control_messages (GSocket *socket,
|
||||
|
||||
task = g_task_new (socket, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _g_socket_read_with_control_messages);
|
||||
g_task_set_name (task, "[gio] D-Bus read");
|
||||
g_task_set_task_data (task, data, (GDestroyNotify) read_with_control_data_free);
|
||||
|
||||
if (g_socket_condition_check (socket, G_IO_IN))
|
||||
@ -1123,6 +1124,7 @@ write_message_async (GDBusWorker *worker,
|
||||
{
|
||||
data->task = g_task_new (NULL, NULL, callback, user_data);
|
||||
g_task_set_source_tag (data->task, write_message_async);
|
||||
g_task_set_name (data->task, "[gio] D-Bus write message");
|
||||
data->total_written = 0;
|
||||
write_message_continue_writing (data);
|
||||
}
|
||||
|
@ -1631,6 +1631,7 @@ async_initable_init_second_async (GAsyncInitable *initable,
|
||||
|
||||
task = g_task_new (proxy, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, async_initable_init_second_async);
|
||||
g_task_set_name (task, "[gio] D-Bus proxy init");
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
/* Check name ownership asynchronously - possibly also start the service */
|
||||
@ -1802,6 +1803,7 @@ async_initable_init_async (GAsyncInitable *initable,
|
||||
|
||||
task = g_task_new (proxy, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, async_initable_init_async);
|
||||
g_task_set_name (task, "[gio] D-Bus proxy init");
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
if (proxy->priv->bus_type != G_BUS_TYPE_NONE)
|
||||
@ -2649,6 +2651,7 @@ g_dbus_proxy_call_internal (GDBusProxy *proxy,
|
||||
my_callback = (GAsyncReadyCallback) reply_cb;
|
||||
task = g_task_new (proxy, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, g_dbus_proxy_call_internal);
|
||||
g_task_set_name (task, "[gio] D-Bus proxy call");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -576,6 +576,7 @@ lookup_by_name_async_real (GResolver *resolver,
|
||||
|
||||
task = g_task_new (resolver, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, lookup_by_name_async_real);
|
||||
g_task_set_name (task, "[gio] resolver lookup");
|
||||
if (addrs)
|
||||
g_task_return_pointer (task, addrs, (GDestroyNotify) g_resolver_free_addresses);
|
||||
else
|
||||
@ -595,6 +596,7 @@ lookup_by_name_async_real (GResolver *resolver,
|
||||
_("Invalid hostname"));
|
||||
task = g_task_new (resolver, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, lookup_by_name_async_real);
|
||||
g_task_set_name (task, "[gio] resolver lookup");
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
@ -613,6 +615,7 @@ lookup_by_name_async_real (GResolver *resolver,
|
||||
_("%s not implemented"), "lookup_by_name_with_flags_async");
|
||||
task = g_task_new (resolver, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, lookup_by_name_async_real);
|
||||
g_task_set_name (task, "[gio] resolver lookup");
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
11
gio/gtask.c
11
gio/gtask.c
@ -759,6 +759,7 @@ g_task_report_error (gpointer source_object,
|
||||
|
||||
task = g_task_new (source_object, NULL, callback, callback_data);
|
||||
g_task_set_source_tag (task, source_tag);
|
||||
g_task_set_name (task, G_STRFUNC);
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
}
|
||||
@ -982,8 +983,8 @@ g_task_set_return_on_cancel (GTask *task,
|
||||
* Since: 2.36
|
||||
*/
|
||||
void
|
||||
g_task_set_source_tag (GTask *task,
|
||||
gpointer source_tag)
|
||||
(g_task_set_source_tag) (GTask *task,
|
||||
gpointer source_tag)
|
||||
{
|
||||
g_return_if_fail (G_IS_TASK (task));
|
||||
|
||||
@ -1241,6 +1242,7 @@ g_task_return (GTask *task,
|
||||
GTaskReturnType type)
|
||||
{
|
||||
GSource *source;
|
||||
gchar *source_name = NULL;
|
||||
|
||||
if (type != G_TASK_RETURN_FROM_THREAD)
|
||||
task->ever_returned = TRUE;
|
||||
@ -1289,7 +1291,10 @@ g_task_return (GTask *task,
|
||||
|
||||
/* Otherwise, complete in the next iteration */
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_name (source, "[gio] complete_in_idle_cb");
|
||||
source_name = g_strdup_printf ("[gio] %s complete_in_idle_cb",
|
||||
(task->name != NULL) ? task->name : "(unnamed)");
|
||||
g_source_set_name (source, source_name);
|
||||
g_free (source_name);
|
||||
g_task_attach_source (task, source, complete_in_idle_cb);
|
||||
g_source_unref (source);
|
||||
}
|
||||
|
@ -78,6 +78,14 @@ GLIB_AVAILABLE_IN_2_60
|
||||
void g_task_set_name (GTask *task,
|
||||
const gchar *name);
|
||||
|
||||
/* Macro wrapper to set the task name when setting the source tag. */
|
||||
#define g_task_set_source_tag(task, tag) G_STMT_START { \
|
||||
GTask *_task = (task); \
|
||||
(g_task_set_source_tag) (_task, tag); \
|
||||
if (g_task_get_name (_task) == NULL) \
|
||||
g_task_set_name (_task, G_STRINGIFY (tag)); \
|
||||
} G_STMT_END
|
||||
|
||||
GLIB_AVAILABLE_IN_2_36
|
||||
gpointer g_task_get_source_object (GTask *task);
|
||||
GLIB_AVAILABLE_IN_2_36
|
||||
|
@ -187,6 +187,7 @@ lookup_by_name (GResolver *resolver,
|
||||
data = lookup_data_new (hostname, AF_UNSPEC);
|
||||
task = g_task_new (resolver, cancellable, NULL, NULL);
|
||||
g_task_set_source_tag (task, lookup_by_name);
|
||||
g_task_set_name (task, "[gio] resolver lookup");
|
||||
g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free);
|
||||
g_task_set_return_on_cancel (task, TRUE);
|
||||
g_task_run_in_thread_sync (task, do_lookup_by_name);
|
||||
@ -228,6 +229,7 @@ lookup_by_name_with_flags (GResolver *resolver,
|
||||
data = lookup_data_new (hostname, AF_UNSPEC);
|
||||
task = g_task_new (resolver, cancellable, NULL, NULL);
|
||||
g_task_set_source_tag (task, lookup_by_name_with_flags);
|
||||
g_task_set_name (task, "[gio] resolver lookup");
|
||||
g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free);
|
||||
g_task_set_return_on_cancel (task, TRUE);
|
||||
g_task_run_in_thread_sync (task, do_lookup_by_name);
|
||||
@ -251,6 +253,7 @@ lookup_by_name_with_flags_async (GResolver *resolver,
|
||||
data = lookup_data_new (hostname, flags_to_family (flags));
|
||||
task = g_task_new (resolver, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, lookup_by_name_with_flags_async);
|
||||
g_task_set_name (task, "[gio] resolver lookup");
|
||||
g_task_set_task_data (task, data, (GDestroyNotify)lookup_data_free);
|
||||
g_task_set_return_on_cancel (task, TRUE);
|
||||
g_task_run_in_thread (task, do_lookup_by_name);
|
||||
@ -350,6 +353,7 @@ lookup_by_address (GResolver *resolver,
|
||||
|
||||
task = g_task_new (resolver, cancellable, NULL, NULL);
|
||||
g_task_set_source_tag (task, lookup_by_address);
|
||||
g_task_set_name (task, "[gio] resolver lookup");
|
||||
g_task_set_task_data (task, g_object_ref (address), g_object_unref);
|
||||
g_task_set_return_on_cancel (task, TRUE);
|
||||
g_task_run_in_thread_sync (task, do_lookup_by_address);
|
||||
@ -370,6 +374,7 @@ lookup_by_address_async (GResolver *resolver,
|
||||
|
||||
task = g_task_new (resolver, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, lookup_by_address_async);
|
||||
g_task_set_name (task, "[gio] resolver lookup");
|
||||
g_task_set_task_data (task, g_object_ref (address), g_object_unref);
|
||||
g_task_set_return_on_cancel (task, TRUE);
|
||||
g_task_run_in_thread (task, do_lookup_by_address);
|
||||
@ -1040,6 +1045,7 @@ lookup_records (GResolver *resolver,
|
||||
|
||||
task = g_task_new (resolver, cancellable, NULL, NULL);
|
||||
g_task_set_source_tag (task, lookup_records);
|
||||
g_task_set_name (task, "[gio] resolver lookup records");
|
||||
|
||||
lrd = g_slice_new (LookupRecordsData);
|
||||
lrd->rrname = g_strdup (rrname);
|
||||
@ -1067,6 +1073,7 @@ lookup_records_async (GResolver *resolver,
|
||||
|
||||
task = g_task_new (resolver, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, lookup_records_async);
|
||||
g_task_set_name (task, "[gio] resolver lookup records");
|
||||
|
||||
lrd = g_slice_new (LookupRecordsData);
|
||||
lrd->rrname = g_strdup (rrname);
|
||||
|
@ -186,6 +186,7 @@ g_tls_database_real_verify_chain_async (GTlsDatabase *self,
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, g_tls_database_real_verify_chain_async);
|
||||
g_task_set_name (task, "[gio] verify TLS chain");
|
||||
g_task_set_task_data (task, args, async_verify_chain_free);
|
||||
g_task_run_in_thread (task, async_verify_chain_thread);
|
||||
g_object_unref (task);
|
||||
@ -264,6 +265,7 @@ g_tls_database_real_lookup_certificate_for_handle_async (GTlsDatabase
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task,
|
||||
g_tls_database_real_lookup_certificate_for_handle_async);
|
||||
g_task_set_name (task, "[gio] lookup TLS certificate");
|
||||
g_task_set_task_data (task, args, async_lookup_certificate_for_handle_free);
|
||||
g_task_run_in_thread (task, async_lookup_certificate_for_handle_thread);
|
||||
g_object_unref (task);
|
||||
@ -338,6 +340,7 @@ g_tls_database_real_lookup_certificate_issuer_async (GTlsDatabase *sel
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task,
|
||||
g_tls_database_real_lookup_certificate_issuer_async);
|
||||
g_task_set_name (task, "[gio] lookup certificate issuer");
|
||||
g_task_set_task_data (task, args, async_lookup_certificate_issuer_free);
|
||||
g_task_run_in_thread (task, async_lookup_certificate_issuer_thread);
|
||||
g_object_unref (task);
|
||||
@ -419,6 +422,7 @@ g_tls_database_real_lookup_certificates_issued_by_async (GTlsDatabase
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task,
|
||||
g_tls_database_real_lookup_certificates_issued_by_async);
|
||||
g_task_set_name (task, "[gio] lookup certificates issued by");
|
||||
g_task_set_task_data (task, args, async_lookup_certificates_issued_by_free);
|
||||
g_task_run_in_thread (task, async_lookup_certificates_issued_by_thread);
|
||||
g_object_unref (task);
|
||||
|
@ -302,7 +302,8 @@ eject_unmount_do (GMount *mount,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data,
|
||||
char **argv)
|
||||
char **argv,
|
||||
const gchar *task_name)
|
||||
{
|
||||
GUnixMount *unix_mount = G_UNIX_MOUNT (mount);
|
||||
GTask *task;
|
||||
@ -310,6 +311,7 @@ eject_unmount_do (GMount *mount,
|
||||
|
||||
task = g_task_new (mount, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, eject_unmount_do);
|
||||
g_task_set_name (task, task_name);
|
||||
g_task_set_task_data (task, g_strdupv (argv), (GDestroyNotify) g_strfreev);
|
||||
|
||||
if (unix_mount->volume_monitor != NULL)
|
||||
@ -337,7 +339,7 @@ g_unix_mount_unmount (GMount *mount,
|
||||
else
|
||||
argv[1] = unix_mount->device_path;
|
||||
|
||||
eject_unmount_do (mount, cancellable, callback, user_data, argv);
|
||||
eject_unmount_do (mount, cancellable, callback, user_data, argv, "[gio] unmount mount");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -363,7 +365,7 @@ g_unix_mount_eject (GMount *mount,
|
||||
else
|
||||
argv[1] = unix_mount->device_path;
|
||||
|
||||
eject_unmount_do (mount, cancellable, callback, user_data, argv);
|
||||
eject_unmount_do (mount, cancellable, callback, user_data, argv, "[gio] eject mount");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -305,7 +305,8 @@ eject_mount_do (GVolume *volume,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data,
|
||||
const gchar * const *argv)
|
||||
const gchar * const *argv,
|
||||
const gchar *task_name)
|
||||
{
|
||||
GSubprocess *subprocess;
|
||||
GError *error = NULL;
|
||||
@ -313,6 +314,7 @@ eject_mount_do (GVolume *volume,
|
||||
|
||||
task = g_task_new (volume, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, eject_mount_do);
|
||||
g_task_set_name (task, task_name);
|
||||
|
||||
if (g_task_return_error_if_cancelled (task))
|
||||
{
|
||||
@ -344,7 +346,7 @@ g_unix_volume_mount (GVolume *volume,
|
||||
else
|
||||
argv[1] = unix_volume->device_path;
|
||||
|
||||
eject_mount_do (volume, cancellable, callback, user_data, argv);
|
||||
eject_mount_do (volume, cancellable, callback, user_data, argv, "[gio] mount volume");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -369,7 +371,7 @@ g_unix_volume_eject (GVolume *volume,
|
||||
|
||||
argv[1] = unix_volume->device_path;
|
||||
|
||||
eject_mount_do (volume, cancellable, callback, user_data, argv);
|
||||
eject_mount_do (volume, cancellable, callback, user_data, argv, "[gio] eject volume");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
43
glib/gmain.c
43
glib/gmain.c
@ -88,6 +88,7 @@
|
||||
#include "gstrfuncs.h"
|
||||
#include "gtestutils.h"
|
||||
#include "gthreadprivate.h"
|
||||
#include "gtrace-private.h"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include "gwin32.h"
|
||||
@ -1248,6 +1249,12 @@ g_source_attach_unlocked (GSource *source,
|
||||
if (do_wakeup && context->owner && context->owner != G_THREAD_SELF)
|
||||
g_wakeup_signal (context->wakeup);
|
||||
|
||||
g_trace_mark (G_TRACE_CURRENT_TIME, 0,
|
||||
"GLib", "g_source_attach",
|
||||
"%s to context %p",
|
||||
(g_source_get_name (source) != NULL) ? g_source_get_name (source) : "(unnamed)",
|
||||
context);
|
||||
|
||||
return source->source_id;
|
||||
}
|
||||
|
||||
@ -3291,6 +3298,7 @@ g_main_dispatch (GMainContext *context)
|
||||
GSourceFunc,
|
||||
gpointer);
|
||||
GSource *prev_source;
|
||||
gint64 begin_time_nsec G_GNUC_UNUSED;
|
||||
|
||||
dispatch = source->source_funcs->dispatch;
|
||||
cb_funcs = source->callback_funcs;
|
||||
@ -3317,12 +3325,20 @@ g_main_dispatch (GMainContext *context)
|
||||
current->source = source;
|
||||
current->depth++;
|
||||
|
||||
begin_time_nsec = G_TRACE_CURRENT_TIME;
|
||||
|
||||
TRACE (GLIB_MAIN_BEFORE_DISPATCH (g_source_get_name (source), source,
|
||||
dispatch, callback, user_data));
|
||||
need_destroy = !(* dispatch) (source, callback, user_data);
|
||||
TRACE (GLIB_MAIN_AFTER_DISPATCH (g_source_get_name (source), source,
|
||||
dispatch, need_destroy));
|
||||
|
||||
g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
|
||||
"GLib", "GSource.dispatch",
|
||||
"%s ⇒ %s",
|
||||
(g_source_get_name (source) != NULL) ? g_source_get_name (source) : "(unnamed)",
|
||||
need_destroy ? "destroy" : "keep");
|
||||
|
||||
current->source = prev_source;
|
||||
current->depth--;
|
||||
|
||||
@ -3626,12 +3642,22 @@ g_main_context_prepare (GMainContext *context,
|
||||
|
||||
if (prepare)
|
||||
{
|
||||
gint64 begin_time_nsec G_GNUC_UNUSED;
|
||||
|
||||
context->in_check_or_prepare++;
|
||||
UNLOCK_CONTEXT (context);
|
||||
|
||||
begin_time_nsec = G_TRACE_CURRENT_TIME;
|
||||
|
||||
result = (* prepare) (source, &source_timeout);
|
||||
TRACE (GLIB_MAIN_AFTER_PREPARE (source, prepare, source_timeout));
|
||||
|
||||
g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
|
||||
"GLib", "GSource.prepare",
|
||||
"%s ⇒ %s",
|
||||
(g_source_get_name (source) != NULL) ? g_source_get_name (source) : "(unnamed)",
|
||||
result ? "ready" : "unready");
|
||||
|
||||
LOCK_CONTEXT (context);
|
||||
context->in_check_or_prepare--;
|
||||
}
|
||||
@ -3886,14 +3912,24 @@ g_main_context_check (GMainContext *context,
|
||||
|
||||
if (check)
|
||||
{
|
||||
gint64 begin_time_nsec G_GNUC_UNUSED;
|
||||
|
||||
/* If the check function is set, call it. */
|
||||
context->in_check_or_prepare++;
|
||||
UNLOCK_CONTEXT (context);
|
||||
|
||||
begin_time_nsec = G_TRACE_CURRENT_TIME;
|
||||
|
||||
result = (* check) (source);
|
||||
|
||||
TRACE (GLIB_MAIN_AFTER_CHECK (source, check, result));
|
||||
|
||||
g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
|
||||
"GLib", "GSource.check",
|
||||
"%s ⇒ %s",
|
||||
(g_source_get_name (source) != NULL) ? g_source_get_name (source) : "(unnamed)",
|
||||
result ? "dispatch" : "ignore");
|
||||
|
||||
LOCK_CONTEXT (context);
|
||||
context->in_check_or_prepare--;
|
||||
}
|
||||
@ -4004,9 +4040,12 @@ g_main_context_iterate (GMainContext *context,
|
||||
gboolean some_ready;
|
||||
gint nfds, allocated_nfds;
|
||||
GPollFD *fds = NULL;
|
||||
gint64 begin_time_nsec G_GNUC_UNUSED;
|
||||
|
||||
UNLOCK_CONTEXT (context);
|
||||
|
||||
begin_time_nsec = G_TRACE_CURRENT_TIME;
|
||||
|
||||
if (!g_main_context_acquire (context))
|
||||
{
|
||||
gboolean got_ownership;
|
||||
@ -4061,6 +4100,10 @@ g_main_context_iterate (GMainContext *context,
|
||||
|
||||
g_main_context_release (context);
|
||||
|
||||
g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
|
||||
"GLib", "g_main_context_iterate",
|
||||
"Context %p, %s ⇒ %s", context, block ? "blocking" : "non-blocking", some_ready ? "dispatched" : "nothing");
|
||||
|
||||
LOCK_CONTEXT (context);
|
||||
|
||||
return some_ready;
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "gspawn.h"
|
||||
#include "gspawn-private.h"
|
||||
#include "gthread.h"
|
||||
#include "gtrace-private.h"
|
||||
#include "glib/gstdio.h"
|
||||
|
||||
#include "genviron.h"
|
||||
@ -1760,7 +1761,10 @@ fork_exec_with_fds (gboolean intermediate_child,
|
||||
if (!intermediate_child && working_directory == NULL && !close_descriptors &&
|
||||
!search_path_from_envp && child_setup == NULL)
|
||||
{
|
||||
g_debug ("Launching with posix_spawn");
|
||||
g_trace_mark (G_TRACE_CURRENT_TIME, 0,
|
||||
"GLib", "posix_spawn",
|
||||
"%s", argv[0]);
|
||||
|
||||
status = do_posix_spawn (argv,
|
||||
envp,
|
||||
search_path,
|
||||
@ -1796,12 +1800,14 @@ fork_exec_with_fds (gboolean intermediate_child,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("posix_spawn avoided %s%s%s%s%s",
|
||||
!intermediate_child ? "" : "(automatic reaping requested) ",
|
||||
working_directory == NULL ? "" : "(workdir specified) ",
|
||||
!close_descriptors ? "" : "(fd close requested) ",
|
||||
!search_path_from_envp ? "" : "(using envp for search path) ",
|
||||
child_setup == NULL ? "" : "(child_setup specified) ");
|
||||
g_trace_mark (G_TRACE_CURRENT_TIME, 0,
|
||||
"GLib", "fork",
|
||||
"posix_spawn avoided %s%s%s%s%s",
|
||||
!intermediate_child ? "" : "(automatic reaping requested) ",
|
||||
working_directory == NULL ? "" : "(workdir specified) ",
|
||||
!close_descriptors ? "" : "(fd close requested) ",
|
||||
!search_path_from_envp ? "" : "(using envp for search path) ",
|
||||
child_setup == NULL ? "" : "(child_setup specified) ");
|
||||
}
|
||||
#endif /* POSIX_SPAWN_AVAILABLE */
|
||||
|
||||
|
70
glib/gtrace-private.h
Normal file
70
glib/gtrace-private.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright © 2020 Endless Mobile, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Philip Withnall <withnall@endlessm.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef HAVE_SYSPROF
|
||||
#include <sysprof-capture.h>
|
||||
#endif
|
||||
|
||||
#include "gmem.h"
|
||||
#include "gmacros.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* G_TRACE_CURRENT_TIME:
|
||||
*
|
||||
* Get the current time, in nanoseconds since the tracing epoch. This (and only
|
||||
* this) is suitable for passing to tracing functions like g_trace_mark(). It is
|
||||
* not suitable for other timekeeping.
|
||||
*
|
||||
* The tracing epoch is implementation defined, but is guaranteed to be
|
||||
* unchanged within the lifetime of each thread. It is not comparable across
|
||||
* threads or process instances.
|
||||
*
|
||||
* If tracing support is disabled, this evaluates to `0`.
|
||||
*
|
||||
* Since: 2.66
|
||||
*/
|
||||
#ifdef HAVE_SYSPROF
|
||||
#define G_TRACE_CURRENT_TIME SYSPROF_CAPTURE_CURRENT_TIME
|
||||
#else
|
||||
#define G_TRACE_CURRENT_TIME 0
|
||||
#endif
|
||||
|
||||
void (g_trace_mark) (gint64 begin_time_nsec,
|
||||
gint64 duration_nsec,
|
||||
const gchar *group,
|
||||
const gchar *name,
|
||||
const gchar *message_format,
|
||||
...);
|
||||
|
||||
#ifndef HAVE_SYSPROF
|
||||
/* Optimise the whole call out */
|
||||
#if defined(G_HAVE_ISO_VARARGS)
|
||||
#define g_trace_mark(b, d, g, n, m, ...)
|
||||
#elif defined(G_HAVE_GNUC_VARARGS)
|
||||
#define g_trace_mark(b, d, g, n, m...)
|
||||
#else
|
||||
/* no varargs macro support; the call will have to be optimised out by the compiler */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
98
glib/gtrace.c
Normal file
98
glib/gtrace.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright © 2020 Endless Mobile, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Philip Withnall <withnall@endlessm.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* SECTION:trace
|
||||
* @Title: Performance tracing
|
||||
* @Short_description: Functions for measuring and tracing performance
|
||||
*
|
||||
* The performance tracing functions allow for the performance of code using
|
||||
* GLib to be measured by passing metrics from the current process to an
|
||||
* external measurement process such as `sysprof-cli` or `sysprofd`.
|
||||
*
|
||||
* They are designed to execute quickly, especially in the common case where no
|
||||
* measurement process is connected. They are guaranteed to not block the caller
|
||||
* and are guaranteed to have zero runtime cost if tracing support is disabled
|
||||
* at configure time.
|
||||
*
|
||||
* Tracing information can be provided as ‘marks’ with a start time and
|
||||
* duration; or as marks with a start time and no duration. Marks with a
|
||||
* duration are intended to show the execution time of a piece of code. Marks
|
||||
* with no duration are intended to show an instantaneous performance problem,
|
||||
* such as an unexpectedly large allocation, or that a slow path has been taken
|
||||
* in some code.
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* gint64 begin_time_nsec G_GNUC_UNUSED;
|
||||
*
|
||||
* begin_time_nsec = G_TRACE_CURRENT_TIME;
|
||||
*
|
||||
* // some code which might take a while
|
||||
*
|
||||
* g_trace_mark (begin_time_nsec, G_TRACE_CURRENT_TIME - begin_time_nsec,
|
||||
* "GLib", "GSource.dispatch",
|
||||
* "%s ⇒ %s", g_source_get_name (source), need_destroy ? "destroy" : "keep");
|
||||
* ]|
|
||||
*
|
||||
* The tracing API is currently internal to GLib.
|
||||
*
|
||||
* Since: 2.66
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtrace-private.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
* g_trace_mark:
|
||||
* @begin_time_nsec: start time of the mark, as returned by %G_TRACE_CURRENT_TIME
|
||||
* @duration_nsec: duration of the mark, in nanoseconds
|
||||
* @group: name of the group for categorising this mark
|
||||
* @name: name of the mark
|
||||
* @message_format: format for the detailed message for the mark, in `printf()` format
|
||||
* @...: arguments to substitute into @message_format; none of these should have
|
||||
* side effects
|
||||
*
|
||||
* Add a mark to the trace, starting at @begin_time_nsec and having length
|
||||
* @duration_nsec (which may be zero). The @group should typically be `GLib`,
|
||||
* and the @name should concisely describe the call site.
|
||||
*
|
||||
* All of the arguments to this function must not have side effects, as the
|
||||
* entire function call may be dropped if sysprof support is not available.
|
||||
*
|
||||
* Since: 2.66
|
||||
*/
|
||||
void
|
||||
(g_trace_mark) (gint64 begin_time_nsec,
|
||||
gint64 duration_nsec,
|
||||
const gchar *group,
|
||||
const gchar *name,
|
||||
const gchar *message_format,
|
||||
...)
|
||||
{
|
||||
#ifdef HAVE_SYSPROF
|
||||
va_list args;
|
||||
|
||||
va_start (args, message_format);
|
||||
sysprof_collector_mark_vprintf (begin_time_nsec, duration_nsec, group, name, message_format, args);
|
||||
va_end (args);
|
||||
#endif /* HAVE_SYSPROF */
|
||||
}
|
@ -7,6 +7,22 @@ if not use_system_pcre
|
||||
subdir('pcre')
|
||||
endif
|
||||
|
||||
# libsysprof-capture support
|
||||
libsysprof_capture_dep = dependency('sysprof-capture-4',
|
||||
required: get_option('sysprof'),
|
||||
default_options: [
|
||||
'enable_examples=false',
|
||||
'enable_gtk=false',
|
||||
'enable_tests=false',
|
||||
'enable_tools=false',
|
||||
'libsysprof=false',
|
||||
'with_sysprofd=none',
|
||||
'help=false',
|
||||
],
|
||||
fallback: ['sysprof', 'libsysprof_capture_dep'],
|
||||
)
|
||||
glib_conf.set('HAVE_SYSPROF', libsysprof_capture_dep.found())
|
||||
|
||||
# TODO: gnulib_objects, pcre_objects and pcre_deps are a workaround for
|
||||
# <https://github.com/mesonbuild/meson/issues/3934> and
|
||||
# <https://github.com/mesonbuild/meson/issues/3937>. When we can depend
|
||||
@ -275,6 +291,8 @@ glib_sources = files(
|
||||
'gthreadpool.c',
|
||||
'gtimer.c',
|
||||
'gtimezone.c',
|
||||
'gtrace.c',
|
||||
'gtrace-private.h',
|
||||
'gtranslit.c',
|
||||
'gtrashstack.c',
|
||||
'gtree.c',
|
||||
@ -357,7 +375,7 @@ libglib = library('glib-2.0',
|
||||
# intl.lib is not compatible with SAFESEH
|
||||
link_args : [noseh_link_args, glib_link_flags, win32_ldflags],
|
||||
include_directories : configinc,
|
||||
dependencies : pcre_deps + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + gnulib_libm_dependency,
|
||||
dependencies : pcre_deps + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + gnulib_libm_dependency + [libsysprof_capture_dep],
|
||||
c_args : glib_c_args,
|
||||
objc_args : glib_c_args,
|
||||
)
|
||||
|
@ -59,6 +59,11 @@ option('tapset_install_dir',
|
||||
value : '',
|
||||
description : 'path where systemtap tapsets are installed')
|
||||
|
||||
option('sysprof',
|
||||
type : 'feature',
|
||||
value : 'disabled',
|
||||
description : 'include tracing support for sysprof')
|
||||
|
||||
option('gtk_doc',
|
||||
type : 'boolean',
|
||||
value : false,
|
||||
|
4
subprojects/sysprof.wrap
Normal file
4
subprojects/sysprof.wrap
Normal file
@ -0,0 +1,4 @@
|
||||
[wrap-git]
|
||||
directory=sysprof
|
||||
url=https://gitlab.gnome.org/GNOME/sysprof.git
|
||||
revision=6b1cd7a722fcebae1ac392562c47957477ade8bf
|
Loading…
Reference in New Issue
Block a user