mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-24 14:36:13 +01:00
gio: Add SystemTap and DTrace probes for GTask
This adds a basic tapset for GIO, covering various interesting parts of GTask. https://bugzilla.gnome.org/show_bug.cgi?id=759813
This commit is contained in:
parent
cfb692825a
commit
195a0cb6bb
@ -51,6 +51,7 @@ IGNORE_HFILES = \
|
||||
gfileattribute-priv.h \
|
||||
gfileinfo-priv.h \
|
||||
ghttpproxy.h \
|
||||
gio_trace.h \
|
||||
giomodule-priv.h \
|
||||
gioprivate.h \
|
||||
giowin32-priv.h \
|
||||
|
@ -310,7 +310,8 @@ Which would print the contents of each widget in a list of widgets.
|
||||
<ulink url="http://sourceware.org/systemtap/">SystemTap</ulink> is a dynamic whole-system
|
||||
analysis toolkit. GLib ships with a file <filename>glib.stp</filename> which defines a
|
||||
set of probe points, which you can hook into with custom SystemTap scripts.
|
||||
See the files <filename>glib.stp</filename> and <filename>gobject.stp</filename> which
|
||||
See the files <filename>glib.stp</filename>, <filename>gobject.stp</filename>
|
||||
and <filename>gio.stp</filename> which
|
||||
are in your shared SystemTap scripts directory.
|
||||
</para>
|
||||
|
||||
|
@ -391,6 +391,7 @@ libgio_2_0_la_SOURCES = \
|
||||
ginetsocketaddress.c \
|
||||
ginitable.c \
|
||||
ginputstream.c \
|
||||
gio_trace.h \
|
||||
gioenums.h \
|
||||
gioerror.c \
|
||||
giomodule.c \
|
||||
@ -755,6 +756,40 @@ dist_schema_DATA = gschema.dtd
|
||||
itsdir = $(datadir)/gettext/its
|
||||
dist_its_DATA = gschema.loc gschema.its
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# SystemTap and dtrace
|
||||
|
||||
if ENABLE_DTRACE
|
||||
DTCOMPILE = $(patsubst -W%,,$(LTCOMPILE))
|
||||
DTCFLAGS = $(patsubst -W%,,$(CFLAGS))
|
||||
|
||||
gio_probes.h: gio_probes.d
|
||||
$(AM_V_GEN) $(DTRACE) -C -h -s $< -o $@.tmp
|
||||
@$(SED) -e "s,define STAP_HAS_SEMAPHORES 1,undef STAP_HAS_SEMAPHORES," < $@.tmp > $@ && rm -f $@.tmp
|
||||
|
||||
gio_probes.lo: gio_probes.d
|
||||
$(AM_V_GEN) env CC="$(DTCOMPILE)" CFLAGS="$(DTCFLAGS)" $(DTRACE) -G -s $< -o $@
|
||||
|
||||
BUILT_SOURCES += gio_probes.h gio_probes.lo
|
||||
CLEANFILES += gio_probes.h gio_probes.h.tmp
|
||||
libgio_2_0_la_LIBADD += gio_probes.lo
|
||||
endif
|
||||
|
||||
if ENABLE_SYSTEMTAP
|
||||
tapset_in_files = gio.stp.in
|
||||
tapsetdir = @ABS_TAPSET_DIR@
|
||||
tapset_DATA = $(tapset_in_files:.stp.in=.stp)
|
||||
EXTRA_DIST += $(tapset_in_files)
|
||||
CLEANFILES += $(tapset_in_files:.stp.in=.stp)
|
||||
|
||||
$(tapset_DATA): %.stp: %.stp.in Makefile
|
||||
$(AM_V_GEN)$(SED) \
|
||||
-e 's|[@]ABS_GLIB_RUNTIME_LIBDIR[@]|$(ABS_GLIB_RUNTIME_LIBDIR)|g' \
|
||||
-e 's|[@]LT_CURRENT[@]|$(LT_CURRENT)|g' \
|
||||
-e 's|[@]LT_REVISION[@]|$(LT_REVISION)|g' \
|
||||
$< > $@
|
||||
endif
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# gdbus(1) tool
|
||||
|
||||
|
107
gio/gio.stp.in
Normal file
107
gio/gio.stp.in
Normal file
@ -0,0 +1,107 @@
|
||||
/**
|
||||
* probe gio.task_new - Called when a new #GTask is created
|
||||
* @task: the new #GTask object
|
||||
* @source_object: the source object
|
||||
* @cancellable: the #GCancellable
|
||||
* @callback: the task’s callback
|
||||
* @callback_data: data for @callback
|
||||
*/
|
||||
probe gio.task_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__new")
|
||||
{
|
||||
task = $arg1;
|
||||
source_object = $arg2;
|
||||
cancellable = $arg3;
|
||||
callback = $arg4;
|
||||
callback_data = $arg5;
|
||||
probestr = sprintf("gio.task_new(%p, %p, %p, %p) -> %p", source_object, cancellable, callback, callback_data, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* probe gio.task_set_task_data - Called when the task data is set on a #GTask
|
||||
* @task: the #GTask object
|
||||
* @task_data: the task data
|
||||
* @task_data_destroy: the destroy notify function for the data
|
||||
*/
|
||||
probe gio.task_set_task_data = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__set_task_data")
|
||||
{
|
||||
task = $arg1;
|
||||
task_data = $arg2;
|
||||
task_data_destroy = $arg3;
|
||||
probestr = sprintf("gio.task_set_task_data(%p, %p, %p)", task, task_data, task_data_destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
* probe gio.task_set_priority - Called when the priority of a #GTask is set
|
||||
* @task: the #GTask object
|
||||
* @priority: the priority
|
||||
*/
|
||||
probe gio.task_set_priority = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__set_priority")
|
||||
{
|
||||
task = $arg1;
|
||||
priority = $arg2;
|
||||
probestr = sprintf("gio.task_set_priority(%p, %i)", task, priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* probe gio.task_set_source_tag - Called when the source tag of a #GTask is set
|
||||
* @task: the #GTask object
|
||||
* @source_tag: the source tag
|
||||
*/
|
||||
probe gio.task_set_source_tag = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__set_source_tag")
|
||||
{
|
||||
task = $arg1;
|
||||
source_tag = $arg2;
|
||||
probestr = sprintf("gio.task_set_source_tag(%p, %p)", task, source_tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* probe gio.task_before_return - Called before a #GTask invokes its callback or returns from g_task_run_in_thread_sync()
|
||||
* @task: the #GTask object
|
||||
* @source_object: the source object passed to the callback
|
||||
* @callback: the callback about to be invoked
|
||||
* @callback_data: data passed to @callback
|
||||
*/
|
||||
probe gio.task_before_return = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__before_return")
|
||||
{
|
||||
task = $arg1;
|
||||
source_object = $arg2;
|
||||
callback = $arg3;
|
||||
callback_data = $arg4;
|
||||
probestr = sprintf("gio.task_before_return(%p, %p, %p, %p)", task, source_object, callback, callback_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* probe gio.task_propagate - Called when a #GTask’s result is propagated
|
||||
* @task: the #GTask object
|
||||
* @error_set: %TRUE if propagating an error, %FALSE otherwise
|
||||
*/
|
||||
probe gio.task_propagate = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__propagate")
|
||||
{
|
||||
task = $arg1;
|
||||
error_set = $arg2;
|
||||
probestr = sprintf("gio.task_propagate(%p) -> %u", task, error_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* probe gio.task_before_run_in_thread - Called before a #GTask’s function is run in a thread
|
||||
* @task: the #GTask object
|
||||
* @task_func: the task function being run
|
||||
*/
|
||||
probe gio.task_before_run_in_thread = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__before_run_in_thread")
|
||||
{
|
||||
task = $arg1;
|
||||
task_func = $arg2;
|
||||
probestr = sprintf("gio.task_before_run_in_thread(%p, %p)", task, task_func);
|
||||
}
|
||||
|
||||
/**
|
||||
* probe gio.task_after_run_in_thread - Called after a #GTask’s function is run in a thread
|
||||
* @task: the #GTask object
|
||||
* @thread_cancelled: %TRUE if the thread was cancelled, %FALSE otherwise
|
||||
*/
|
||||
probe gio.task_after_run_in_thread = process("@ABS_GLIB_RUNTIME_LIBDIR@/libgio-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("task__after_run_in_thread")
|
||||
{
|
||||
task = $arg1;
|
||||
thread_cancelled = $arg2;
|
||||
probestr = sprintf("gio.task_after_run_in_thread(%p) -> %u", task, thread_cancelled);
|
||||
}
|
10
gio/gio_probes.d
Normal file
10
gio/gio_probes.d
Normal file
@ -0,0 +1,10 @@
|
||||
provider gio {
|
||||
probe task__new(void*, void*, void*, void*, void*);
|
||||
probe task__set_task_data(void*, void*, void*);
|
||||
probe task__set_priority(void*, int);
|
||||
probe task__set_source_tag(void*, void*);
|
||||
probe task__before_return(void*, void*, void*, void*);
|
||||
probe task__propagate(void*, unsigned int);
|
||||
probe task__before_run_in_thread(void*, void*);
|
||||
probe task__after_run_in_thread(void*, unsigned int);
|
||||
};
|
41
gio/gio_trace.h
Normal file
41
gio/gio_trace.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
*
|
||||
* Copyright (C) 2009,2010 Red Hat, 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 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: Alexander Larsson <alexl@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __GIOTRACE_H__
|
||||
#define __GIOTRACE_H__
|
||||
|
||||
#ifndef SIZEOF_CHAR
|
||||
#error "config.h must be included prior to gio_trace.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DTRACE
|
||||
|
||||
/* include the generated probes header and put markers in code */
|
||||
#include "gio_probes.h"
|
||||
#define TRACE(probe) probe
|
||||
|
||||
#else
|
||||
|
||||
/* Wrap the probe to allow it to be removed when no systemtap available */
|
||||
#define TRACE(probe)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __GIOTRACE_H__ */
|
34
gio/gtask.c
34
gio/gtask.c
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gio_trace.h"
|
||||
|
||||
#include "gtask.h"
|
||||
|
||||
@ -700,6 +701,9 @@ g_task_new (gpointer source_object,
|
||||
if (source)
|
||||
task->creation_time = g_source_get_time (source);
|
||||
|
||||
TRACE (GIO_TASK_NEW (task, source_object, cancellable,
|
||||
callback, callback_data));
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
@ -803,6 +807,8 @@ g_task_set_task_data (GTask *task,
|
||||
|
||||
task->task_data = task_data;
|
||||
task->task_data_destroy = task_data_destroy;
|
||||
|
||||
TRACE (GIO_TASK_SET_TASK_DATA (task, task_data, task_data_destroy));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -825,6 +831,8 @@ g_task_set_priority (GTask *task,
|
||||
gint priority)
|
||||
{
|
||||
task->priority = priority;
|
||||
|
||||
TRACE (GIO_TASK_SET_PRIORITY (task, priority));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -951,6 +959,8 @@ g_task_set_source_tag (GTask *task,
|
||||
gpointer source_tag)
|
||||
{
|
||||
task->source_tag = source_tag;
|
||||
|
||||
TRACE (GIO_TASK_SET_SOURCE_TAG (task, source_tag));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1101,6 +1111,9 @@ g_task_get_source_tag (GTask *task)
|
||||
static void
|
||||
g_task_return_now (GTask *task)
|
||||
{
|
||||
TRACE (GIO_TASK_BEFORE_RETURN (task, task->source_object, task->callback,
|
||||
task->callback_data));
|
||||
|
||||
g_main_context_push_thread_default (task->context);
|
||||
|
||||
if (task->callback != NULL)
|
||||
@ -1219,6 +1232,8 @@ g_task_thread_complete (GTask *task)
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE (GIO_TASK_AFTER_RUN_IN_THREAD (task, task->thread_cancelled));
|
||||
|
||||
task->thread_complete = TRUE;
|
||||
g_mutex_unlock (&task->lock);
|
||||
|
||||
@ -1338,6 +1353,8 @@ g_task_start_task_thread (GTask *task,
|
||||
|
||||
g_mutex_lock (&task->lock);
|
||||
|
||||
TRACE (GIO_TASK_BEFORE_RUN_IN_THREAD (task, task_func));
|
||||
|
||||
task->task_func = task_func;
|
||||
|
||||
if (task->cancellable)
|
||||
@ -1347,6 +1364,7 @@ g_task_start_task_thread (GTask *task,
|
||||
&task->error))
|
||||
{
|
||||
task->thread_cancelled = task->thread_complete = TRUE;
|
||||
TRACE (GIO_TASK_AFTER_RUN_IN_THREAD (task, task->thread_cancelled));
|
||||
g_thread_pool_push (task_pool, g_object_ref (task), NULL);
|
||||
return;
|
||||
}
|
||||
@ -1453,6 +1471,10 @@ g_task_run_in_thread_sync (GTask *task,
|
||||
|
||||
g_mutex_unlock (&task->lock);
|
||||
|
||||
TRACE (GIO_TASK_BEFORE_RETURN (task, task->source_object,
|
||||
NULL /* callback */,
|
||||
NULL /* callback data */));
|
||||
|
||||
/* Notify of completion in this thread. */
|
||||
task->completed = TRUE;
|
||||
g_object_notify (G_OBJECT (task), "completed");
|
||||
@ -1491,18 +1513,24 @@ static gboolean
|
||||
g_task_propagate_error (GTask *task,
|
||||
GError **error)
|
||||
{
|
||||
gboolean error_set;
|
||||
|
||||
if (task->check_cancellable &&
|
||||
g_cancellable_set_error_if_cancelled (task->cancellable, error))
|
||||
return TRUE;
|
||||
error_set = TRUE;
|
||||
else if (task->error)
|
||||
{
|
||||
g_propagate_error (error, task->error);
|
||||
task->error = NULL;
|
||||
task->had_error = TRUE;
|
||||
return TRUE;
|
||||
error_set = TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
error_set = FALSE;
|
||||
|
||||
TRACE (GIO_TASK_PROPAGATE (task, error_set));
|
||||
|
||||
return error_set;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user