From cfb692825aaa64c2663963568df1b7dfa4b67e89 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 23 Dec 2015 16:28:50 +0000 Subject: [PATCH] glib: Add more GLib main context SystemTap and DTrace probes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expand the set of available probes, and add a few more output parameters to some of the existing ones to make them more useful. I do not know if this breaks any existing stability guarantees for GLib’s SystemTap tapset, as it is effectively just adding some more local variables in the user’s probe. https://bugzilla.gnome.org/show_bug.cgi?id=759813 --- glib/glib.stp.in | 508 +++++++++++++++++++++++++++++++++++++++++++-- glib/glib_probes.d | 41 +++- glib/gmain.c | 194 ++++++++++++----- glib/gthread.c | 4 + 4 files changed, 677 insertions(+), 70 deletions(-) diff --git a/glib/glib.stp.in b/glib/glib.stp.in index 41f2bbd9d..fd831ea48 100644 --- a/glib/glib.stp.in +++ b/glib/glib.stp.in @@ -84,23 +84,505 @@ probe glib.slice_free = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_ } /** - * * probe glib.main_before_dispatch - Called before dispatching a GSource - * * @source: name of the source - * * @callback: address of the callback - * */ -probe glib.main_before_dispatch = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__before_dispatch") + * probe glib.main_after_prepare - Called after preparing a GSource + * @source: source pointer + * @prepare: prepare function pointer + * @source_timeout: callback function pointer + */ +probe glib.main_after_prepare = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__after_prepare") { - source = user_string2($arg1, "unnamed"); - probestr = sprintf("glib.main_before_dispatch(source=%s)", source); + source = $arg1; + prepare = $arg2; + source_timeout = $arg3; + probestr = sprintf("glib.main_after_prepare(source=%p, prepare=%p) -> %u", source, prepare, source_timeout); } /** - * * probe glib.main_after_dispatch - Called after dispatching a GSource - * * @source: name of the source - * * @callback: address of the callback - * */ + * probe glib.main_after_check - Called after checking a GSource + * @source: source pointer + * @check: check function pointer + * @result: result of the check call + */ +probe glib.main_after_check = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__after_check") +{ + source = $arg1; + check = $arg2; + result = $arg3; + probestr = sprintf("glib.main_after_check(source=%p, check=%p) -> %u", source, check, result); +} + +/** + * probe glib.main_before_dispatch - Called before dispatching a GSource + * @source: name of the source + * @source_ptr: source pointer + * @dispatch: dispatch function pointer + * @callback: callback function pointer + * @user_data: user data for @callback + */ +probe glib.main_before_dispatch = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__before_dispatch") +{ + source = user_string2($arg1, "unnamed"); + source_ptr = $arg2; + dispatch = $arg3; + callback = $arg4; + user_data = $arg5; + probestr = sprintf("glib.main_before_dispatch(source=%s(%p), dispatch=%p, callback=%p, user_data=%p)", source, source_ptr, dispatch, callback, user_data); +} + +/** + * probe glib.main_after_dispatch - Called after dispatching a GSource + * @source: name of the source + * @source_ptr: source pointer + * @dispatch: dispatch function pointer + * @need_destroy: whether the source should be destroyed + */ probe glib.main_after_dispatch = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__after_dispatch") { - source = user_string2($arg1, "unnamed"); - probestr = sprintf("glib.main_after_dispatch(source=%s)", source); + source = user_string2($arg1, "unnamed"); + source_ptr = $arg2; + dispatch = $arg3; + need_destroy = $arg4; + probestr = sprintf("glib.main_after_dispatch(source=%s(%p), dispatch=%p) -> %u", source, source_ptr, dispatch, need_destroy); +} + +/** + * probe glib.main_source_attach - Called when a #GSource is attached to a #GMainContext + * @source: name of the source + * @source_ptr: the #GSource + * @context: the #GMainContext the source is being attached to + * @id: the ID of the #GSource in the context + */ +probe glib.main_source_attach = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__source_attach") +{ + source = user_string2($arg1, "unnamed"); + source_ptr = $arg2; + context = $arg3; + id = $arg4; + probestr = sprintf("glib.main_source_attach(source=%s(%p), context=%p) -> %u", source, source_ptr, context, id); +} + +/** + * probe glib.main_source_destroy - Called when a #GSource is destroyed from a #GMainContext + * @source: name of the source + * @source_ptr: the #GSource + * @context: the #GMainContext the source is being destroyed from + */ +probe glib.main_source_destroy = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__source_destroy") +{ + source = user_string2($arg1, "unnamed"); + source_ptr = $arg2; + context = $arg3; + probestr = sprintf("glib.main_source_destroy(source=%s(%p), context=%p)", source, source_ptr, context); +} + +/* + * probe glib.main_context_default - Called when the default #GMainContext is created + * @context: pointer to the new default #GMainContext + */ +probe glib.main_context_default = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_default") +{ + context = $arg1; + probestr = sprintf("glib.main_context_default() -> %p", context); +} + +/** + * probe glib.main_context_new - Called when a #GMainContext is initially created + * @context: pointer to the new #GMainContext + */ +probe glib.main_context_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_new") +{ + context = $arg1; + probestr = sprintf("glib.main_context_new() -> %p", context); +} + +/** + * probe glib.main_context_acquire - Called when a thread tries to acquire a #GMainContext + * @context: the #GMainContext + * @success: TRUE if acquisition was successful; FALSE if there was contention + */ +probe glib.main_context_acquire = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_acquire") +{ + context = $arg1; + success = $arg2; + probestr = sprintf("glib.main_context_acquire(context=%p) -> %u", context, success); +} + +/** + * probe glib.main_context_release - Called when a thread releases a #GMainContext + * @context: the #GMainContext + */ +probe glib.main_context_release = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_release") +{ + context = $arg1; + probestr = sprintf("glib.main_context_release(context=%p)", context); +} + +/** + * probe glib.main_context_free - Called when a #GMainContext is freed + * @context: pointer to the #GMainContext to be freed + */ +probe glib.main_context_free = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_free") +{ + context = $arg1; + probestr = sprintf("glib.main_context_free(context=%p)", context); +} + +/** + * probe glib.main_context_push_thread_default - Called when a #GMainContext is pushed onto the thread default stack + * @context: a #GMainContext + */ +probe glib.main_context_push_thread_default = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_push_thread_default") +{ + context = $arg1; + probestr = sprintf("glib.main_context_push_thread_default(context=%p)", context); +} + +/** + * probe glib.main_context_pop_thread_default - Called when a #GMainContext is popped off the thread default stack + * @context: a #GMainContext + */ +probe glib.main_context_pop_thread_default = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_pop_thread_default") +{ + context = $arg1; + probestr = sprintf("glib.main_context_pop_thread_default(context=%p)", context); +} + +/** + * probe glib.main_context_before_prepare - Called before a #GMainContext calls prepare on all its #GSources + * @context: a #GMainContext + */ +probe glib.main_context_before_prepare = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_before_prepare") +{ + context = $arg1; + probestr = sprintf("glib.main_context_before_prepare(context=%p)", context); +} + +/** + * probe glib.main_context_after_prepare - Called after a #GMainContext calls prepare on all its #GSources + * @context: a #GMainContext + * @priority: priority of the highest priority ready #GSource + * @n_ready: number of #GSources ready + */ +probe glib.main_context_after_prepare = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_after_prepare") +{ + context = $arg1; + priority = $arg2; + n_ready = $arg3; + probestr = sprintf("glib.main_context_after_prepare(context=%p) -> priority=%i,n_ready=%u", context, priority, n_ready); +} + +/** + * probe glib.main_context_before_query - Called before a #GMainContext calls query on all its #GSources + * @context: a #GMainContext + * @max_priority: maximum priority #GSource to check + */ +probe glib.main_context_before_query = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_before_query") +{ + context = $arg1; + max_priority = $arg2; + probestr = sprintf("glib.main_context_before_query(context=%p, max_priority=%i)", context, max_priority); +} + +/** + * probe glib.main_context_after_query - Called after a #GMainContext calls query on all its #GSources + * @context: a #GMainContext + * @timeout: poll timeout to use + * @fds: array of FDs ready to be polled, of length @n_fds + * @n_fds: number of FDs ready to be polled + */ +probe glib.main_context_after_query = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_after_query") +{ + context = $arg1; + timeout = $arg2; + fds = $arg3; + n_fds = $arg4; + probestr = sprintf("glib.main_context_after_query(context=%p) -> timeout=%u,fds=%p,n_fds=%u", context, timeout, fds, n_fds); +} + +/** + * probe glib.main_context_before_check - Called before a #GMainContext calls check on all its #GSources + * @context: a #GMainContext + * @max_priority: maximum priority #GSource to check + * @fds: array of FDs to check, of length @n_fds + * @n_fds: number of FDs to check + */ +probe glib.main_context_before_check = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_before_check") +{ + context = $arg1; + max_priority = $arg2; + fds = $arg3; + n_fds = $arg4; + probestr = sprintf("glib.main_context_before_check(context=%p, max_priority=%i, fds=%p, n_fds=%u)", context, max_priority, fds, n_fds); +} + +/** + * probe glib.main_context_after_check - Called after a #GMainContext calls check on all its #GSources + * @context: a #GMainContext + * @n_ready: number of sources ready to be dispatched + */ +probe glib.main_context_after_check = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_after_check") +{ + context = $arg1; + n_ready = $arg2; + probestr = sprintf("glib.main_context_after_check(context=%p) -> %u", context, n_ready); +} + +/** + * probe glib.main_context_before_dispatch - Called before a #GMainContext calls dispatch on all its #GSources + * @context: a #GMainContext + */ +probe glib.main_context_before_dispatch = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_before_dispatch") +{ + context = $arg1; + probestr = sprintf("glib.main_context_before_dispatch(context=%p)", context); +} + +/** + * probe glib.main_context_after_dispatch - Called after a #GMainContext calls dispatch on all its #GSources + * @context: a #GMainContext + */ +probe glib.main_context_after_dispatch = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_after_dispatch") +{ + context = $arg1; + probestr = sprintf("glib.main_context_after_dispatch(context=%p)", context); +} + +/** + * probe glib.main_context_wakeup - Called when a wakeup call is made for a #GMainContext + * @context: a #GMainContext + */ +probe glib.main_context_wakeup = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_wakeup") +{ + context = $arg1; + probestr = sprintf("glib.main_context_wakeup(context=%p)", context); +} + +/** + * probe glib.main_context_wakeup_acknowledge - Called when a wakeup call is acknowledged by a #GMainContext + * @context: a #GMainContext + */ +probe glib.main_context_wakeup_acknowledge = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__context_wakeup_acknowledge") +{ + context = $arg1; + probestr = sprintf("glib.main_context_wakeup_acknowledge(context=%p)", context); +} + +/** + * probe glib.main_loop_new - Called when a #GMainLoop is initially created + * @loop: pointer to the new #GMainLoop + * @context: pointer to the parent #GMainContext + */ +probe glib.main_loop_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__loop_new") +{ + loop = $arg1; + context = $arg2; + probestr = sprintf("glib.main_loop_new(%p) -> %p", context, loop); +} + +/** + * probe glib.main_context_quit - Called when a #GMainLoop is quit + * @loop: pointer to the #GMainLoop to be quit + */ +probe glib.main_loop_quit = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("main__loop_quit") +{ + loop = $arg1; + probestr = sprintf("glib.main_loop_quit(%p)", loop); +} + +/** + * probe glib.idle_add - Called when g_idle_add() or g_idle_add_full() is called + * @source: the newly created idle #GSource + * @context: the #GMainContext the idle source was added to + * @id: the ID of the #GSource in the main context + * @priority: the priority of the idle source + * @func: the idle callback function + * @data: data to pass to the callback function + */ +probe glib.idle_add = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("idle__add") +{ + source = $arg1; + context = $arg2; + id = $arg3; + priority = $arg4; + func = $arg5; + data = $arg6; + probestr = sprintf("glib.idle_add(%d, %p, %p) -> %p, %p, %u", priority, func, data, source, context, id); +} + +/** + * probe glib.idle_dispatch - Called when an idle #GSource is dispatched + * @source: the idle #GSource + * @context: the #GMainContext the idle source was in + * @func: the idle callback function + * @data: data passed to the callback function + * @again: 1 if the idle function is to be scheduled again, 0 otherwise + */ +probe glib.idle_dispatch = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("idle__dispatch") +{ + source = $arg1; + context = $arg2; + func = $arg3; + data = $arg4; + again = $arg5; + probestr = sprintf("glib.idle_dispatch(%p) -> %p, %p, %p, %u", source, context, func, data, again); +} + +/** + * probe glib.timeout_add - Called when g_timeout_add() or g_timeout_add_full() is called + * @source: the newly created timeout #GSource + * @context: the #GMainContext the timeout source was added to + * @id: the ID of the #GSource in the main context + * @priority: the priority of the timeout source + * @interval: the time between dispatches of the source, in milliseconds + * @func: the timeout callback function + * @data: data to pass to the callback function + */ +probe glib.timeout_add = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("timeout__add") +{ + source = $arg1; + context = $arg2; + id = $arg3; + priority = $arg4; + interval = $arg5; + func = $arg6; + data = $arg7; + probestr = sprintf("glib.timeout_add(%d, %u, %p, %p) -> %p, %p, %u", priority, interval, func, data, source, context, id); +} + +/** + * probe glib.timeout_dispatch - Called when an timeout #GSource is dispatched + * @source: the timeout #GSource + * @context: the #GMainContext the timeout source was in + * @func: the timeout callback function + * @data: data passed to the callback function + * @again: 1 if the timeout is to be scheduled again, 0 otherwise + */ +probe glib.timeout_dispatch = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("timeout__dispatch") +{ + source = $arg1; + context = $arg2; + func = $arg3; + data = $arg4; + again = $arg5; + probestr = sprintf("glib.timeout_dispatch(%p) -> %p, %p, %p, %u", source, context, func, data, again); +} + +/** + * probe glib.source_new - Called when a new #GSource is created + * @source: the new #GSource + * @prepare: the prepare function for the #GSource + * @check: the check function for the #GSource + * @dispatch: the dispatch function for the #GSource + * @finalize: the finalize function for the #GSource + * @struct_size: the size of #GSource structure to allocate + */ +probe glib.source_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("source__new") +{ + source = $arg1; + prepare = $arg2; + check = $arg3; + dispatch = $arg4; + finalize = $arg5; + struct_size = $arg6; + probestr = sprintf("glib.source_new(%p, %p, %p, %p, %u) -> %p", prepare, check, dispatch, finalize, struct_size, source); +} + +/** + * probe glib.source_set_callback - Called when the callback on a #GSource is set + * @source: the #GSource + * @func: the new callback function for the source + * @data: data to pass to @func + * @notify: notify handler for @data + */ +probe glib.source_set_callback = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("source__set_callback") +{ + source = $arg1; + func = $arg2; + data = $arg3; + notify = $arg4; + probestr = sprintf("glib.source_set_callback(%p, %p, %p, %p)", source, func, data, notify); +} + +/** + * probe glib.source_set_callback_indirect - Called when an indirect callback on a #GSource is set + * @source: the #GSource + * @callback_data: data for @callback_funcs + * @ref: the indirect callback ref function + * @unref: the indirect callback unref function + * @get: the indirect callback getter function + */ +probe glib.source_set_callback_indirect = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("source__set_callback_indirect") +{ + source = $arg1; + callback_data = $arg2; + ref = $arg3; + unref = $arg4; + get = $arg5; + probestr = sprintf("glib.source_set_callback_indirect(%p, %p, %p, %p, %p)", source, callback_data, ref, unref, get); +} + +/** + * probe glib.source_set_ready_time - Called when the ready time is set on a #GSource + * @source: the #GSource + * @ready_time: the new ready time + */ +probe glib.source_set_ready_time = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("source__set_ready_time") +{ + source = $arg1; + ready_time = $arg2; + probestr = sprintf("glib.source_set_ready_time(%p, %i)", source, ready_time); +} + +/** + * probe glib.source_set_priority - Called when the priority is set on a #GSource + * @source: the #GSource + * @context: the context the source is attached to + * @priority: the new priority + */ +probe glib.source_set_priority = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("source__set_priority") +{ + source = $arg1; + context = $arg2; + priority = $arg3; + probestr = sprintf("glib.source_set_priority(%p, %p, %i)", source, context, priority); +} + +/** + * probe glib.source_set_name - Called when the name is set for a #GSource + * @source: the #GSource + * @name: the new name + */ +probe glib.source_set_name = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("source__set_name") +{ + source = $arg1; + name = user_string($arg2); + probestr = sprintf("glib.source_set_name(%p, %s)", source, name); +} + +/** + * probe glib.source_before_free - Called before a #GSource is finalised + * @source: the #GSource + * @context: the context the #GSource is attached to, if any + * @finalize: the finalize function about to be called + */ +probe glib.source_before_free = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("source__before_free") +{ + source = $arg1; + context = $arg2; + finalize = $arg3; + probestr = sprintf("glib.source_before_free(%p, %p, %p)", source, context, finalize); +} + +/** + * probe glib.thread_spawned - Called from a newly spawned GThread, before the thread function is called + * @func: the #GThreadFunc about to be executed + * @data: data to be passed to @func + * @name: (nullable): the thread name + */ +probe glib.thread_spawned = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("thread__spawned") +{ + func = $arg1; + data = $arg2; + name = user_string($arg3); + probestr = sprintf("glib.thread_spawned(%p, %p, %s)", func, data, name); } diff --git a/glib/glib_probes.d b/glib/glib_probes.d index ac955e8f0..553f7bdcd 100644 --- a/glib/glib_probes.d +++ b/glib/glib_probes.d @@ -5,8 +5,41 @@ provider glib { probe slice__alloc(void*, unsigned int); probe slice__free(void*, unsigned int); probe quark__new(char *, unsigned int); - probe main__before_dispatch (char *); - probe main__after_dispatch (char *); - probe main__source_attach(char*); - probe main__source_destroy(char*); + probe main__after_prepare(void*, void*, unsigned int); + probe main__after_check(void*, void*, unsigned int); + probe main__before_dispatch(char*, void*, void*, void*, void*); + probe main__after_dispatch(char*, void*, void*, unsigned int); + probe main__source_attach(char*, void*, void*, unsigned int); + probe main__source_destroy(char*, void*, void*); + probe main__context_default(void*); + probe main__context_new(void*); + probe main__context_acquire(void*, void*); + probe main__context_release(void*); + probe main__context_free(void*); + probe main__context_push_thread_default(void*); + probe main__context_pop_thread_default(void*); + probe main__context_before_prepare(void*); + probe main__context_after_prepare(void*, int, unsigned int); + probe main__context_before_query(void*, int); + probe main__context_after_query(void*, unsigned int, void*, unsigned int); + probe main__context_before_check(void*, int, void*, unsigned int); + probe main__context_after_check(void*, unsigned int); + probe main__context_before_dispatch(void*); + probe main__context_after_dispatch(void*); + probe main__context_wakeup(void*); + probe main__context_wakeup_acknowledge(void*); + probe main__loop_new(void*, void*); + probe main__loop_quit(void*); + probe idle__add(void*, void*, unsigned int, int, void*, void*); + probe idle__dispatch(void*, void*, void*, void*, unsigned int); + probe timeout__add(void*, void*, unsigned int, int, unsigned int, void*, void*); + probe timeout__dispatch(void*, void*, void*, void*, unsigned int); + probe source__new(void*, void*, void*, void*, void*, size_t); + probe source__set_callback(void*, void*, void*, void*); + probe source__set_callback_indirect(void*, void*, void*, void*, void*); + probe source__set_ready_time(void*, unsigned int); + probe source__set_priority(void*, void*, unsigned int); + probe source__set_name(void*, const char*); + probe source__before_free(void*, void*, void*); + probe thread__spawned(void*, void*, char*); }; diff --git a/glib/gmain.c b/glib/gmain.c index 345b0e57a..68522b037 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -31,6 +31,7 @@ #include "config.h" #include "glibconfig.h" +#include "glib_trace.h" /* Uncomment the next line (and the corresponding line in gpoll.c) to * enable debugging printouts if the environment variable @@ -628,6 +629,8 @@ g_main_context_new (void) context = g_new0 (GMainContext, 1); + TRACE (GLIB_MAIN_CONTEXT_NEW (context)); + g_mutex_init (&context->mutex); g_cond_init (&context->cond); @@ -687,6 +690,9 @@ g_main_context_default (void) if (!default_main_context) { default_main_context = g_main_context_new (); + + TRACE (GLIB_MAIN_CONTEXT_DEFAULT (default_main_context)); + #ifdef G_MAIN_POLL_DEBUG if (_g_main_poll_debug) g_print ("default context=%p\n", default_main_context); @@ -703,6 +709,8 @@ free_context (gpointer data) { GMainContext *context = data; + TRACE (GLIB_MAIN_CONTEXT_FREE (context)); + g_main_context_release (context); if (context) g_main_context_unref (context); @@ -783,6 +791,8 @@ g_main_context_push_thread_default (GMainContext *context) } g_queue_push_head (stack, context); + + TRACE (GLIB_MAIN_CONTEXT_PUSH_THREAD_DEFAULT (context)); } /** @@ -807,6 +817,8 @@ g_main_context_pop_thread_default (GMainContext *context) g_return_if_fail (stack != NULL); g_return_if_fail (g_queue_peek_head (stack) == context); + TRACE (GLIB_MAIN_CONTEXT_POP_THREAD_DEFAULT (context)); + g_queue_pop_head (stack); g_main_context_release (context); @@ -912,7 +924,11 @@ g_source_new (GSourceFuncs *source_funcs, source->priv->ready_time = -1; /* NULL/0 initialization for all other fields */ - + + TRACE (GLIB_SOURCE_NEW (source, source_funcs->prepare, source_funcs->check, + source_funcs->dispatch, source_funcs->finalize, + struct_size)); + return source; } @@ -1174,8 +1190,6 @@ g_source_attach (GSource *source, g_return_val_if_fail (source->context == NULL, 0); g_return_val_if_fail (!SOURCE_DESTROYED (source), 0); - TRACE (GLIB_MAIN_SOURCE_ATTACH (g_source_get_name (source))); - if (!context) context = g_main_context_default (); @@ -1183,6 +1197,9 @@ g_source_attach (GSource *source, result = g_source_attach_unlocked (source, context, TRUE); + TRACE (GLIB_MAIN_SOURCE_ATTACH (g_source_get_name (source), source, context, + result)); + UNLOCK_CONTEXT (context); return result; @@ -1193,7 +1210,8 @@ g_source_destroy_internal (GSource *source, GMainContext *context, gboolean have_lock) { - TRACE (GLIB_MAIN_SOURCE_DESTROY (g_source_get_name (source))); + TRACE (GLIB_MAIN_SOURCE_DESTROY (g_source_get_name (source), source, + context)); if (!have_lock) LOCK_CONTEXT (context); @@ -1507,6 +1525,46 @@ g_source_remove_child_source (GSource *source, UNLOCK_CONTEXT (context); } +static void +g_source_callback_ref (gpointer cb_data) +{ + GSourceCallback *callback = cb_data; + + callback->ref_count++; +} + +static void +g_source_callback_unref (gpointer cb_data) +{ + GSourceCallback *callback = cb_data; + + callback->ref_count--; + if (callback->ref_count == 0) + { + if (callback->notify) + callback->notify (callback->data); + g_free (callback); + } +} + +static void +g_source_callback_get (gpointer cb_data, + GSource *source, + GSourceFunc *func, + gpointer *data) +{ + GSourceCallback *callback = cb_data; + + *func = callback->func; + *data = callback->data; +} + +static GSourceCallbackFuncs g_source_callback_funcs = { + g_source_callback_ref, + g_source_callback_unref, + g_source_callback_get, +}; + /** * g_source_set_callback_indirect: * @source: the source @@ -1538,6 +1596,12 @@ g_source_set_callback_indirect (GSource *source, if (context) LOCK_CONTEXT (context); + if (callback_funcs != &g_source_callback_funcs) + TRACE (GLIB_SOURCE_SET_CALLBACK_INDIRECT (source, callback_data, + callback_funcs->ref, + callback_funcs->unref, + callback_funcs->get)); + old_cb_data = source->callback_data; old_cb_funcs = source->callback_funcs; @@ -1551,47 +1615,6 @@ g_source_set_callback_indirect (GSource *source, old_cb_funcs->unref (old_cb_data); } -static void -g_source_callback_ref (gpointer cb_data) -{ - GSourceCallback *callback = cb_data; - - callback->ref_count++; -} - - -static void -g_source_callback_unref (gpointer cb_data) -{ - GSourceCallback *callback = cb_data; - - callback->ref_count--; - if (callback->ref_count == 0) - { - if (callback->notify) - callback->notify (callback->data); - g_free (callback); - } -} - -static void -g_source_callback_get (gpointer cb_data, - GSource *source, - GSourceFunc *func, - gpointer *data) -{ - GSourceCallback *callback = cb_data; - - *func = callback->func; - *data = callback->data; -} - -static GSourceCallbackFuncs g_source_callback_funcs = { - g_source_callback_ref, - g_source_callback_unref, - g_source_callback_get, -}; - /** * g_source_set_callback: * @source: the source @@ -1622,6 +1645,8 @@ g_source_set_callback (GSource *source, g_return_if_fail (source != NULL); + TRACE (GLIB_SOURCE_SET_CALLBACK (source, func, data, notify)); + new_callback = g_new (GSourceCallback, 1); new_callback->ref_count = 1; @@ -1665,6 +1690,8 @@ g_source_set_priority_unlocked (GSource *source, g_return_if_fail (source->priv->parent_source == NULL || source->priv->parent_source->priority == priority); + TRACE (GLIB_SOURCE_SET_PRIORITY (source, context, priority)); + if (context) { /* Remove the source from the context's source and then @@ -1804,6 +1831,8 @@ g_source_set_ready_time (GSource *source, source->priv->ready_time = ready_time; + TRACE (GLIB_SOURCE_SET_READY_TIME (source, ready_time)); + if (context) { /* Quite likely that we need to change the timeout on the poll */ @@ -1920,6 +1949,8 @@ g_source_set_name (GSource *source, if (context) LOCK_CONTEXT (context); + TRACE (GLIB_SOURCE_SET_NAME (source, name)); + /* setting back to NULL is allowed, just because it's * weird if get_name can return NULL but you can't * set that. @@ -2037,6 +2068,9 @@ g_source_unref_internal (GSource *source, source->ref_count--; if (source->ref_count == 0) { + TRACE (GLIB_SOURCE_BEFORE_FREE (source, context, + source->source_funcs->finalize)); + old_cb_data = source->callback_data; old_cb_funcs = source->callback_funcs; @@ -3161,9 +3195,11 @@ g_main_dispatch (GMainContext *context) current->source = source; current->depth++; - TRACE( GLIB_MAIN_BEFORE_DISPATCH (g_source_get_name (source))); + 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))); + TRACE (GLIB_MAIN_AFTER_DISPATCH (g_source_get_name (source), source, + dispatch, need_destroy)); current->source = prev_source; current->depth--; @@ -3228,6 +3264,7 @@ g_main_context_acquire (GMainContext *context) { context->owner = self; g_assert (context->owner_count == 0); + TRACE (GLIB_MAIN_CONTEXT_ACQUIRE (context, TRUE /* success */)); } if (context->owner == self) @@ -3235,9 +3272,13 @@ g_main_context_acquire (GMainContext *context) context->owner_count++; result = TRUE; } + else + { + TRACE (GLIB_MAIN_CONTEXT_ACQUIRE (context, FALSE /* failure */)); + } UNLOCK_CONTEXT (context); - + return result; } @@ -3261,6 +3302,8 @@ g_main_context_release (GMainContext *context) context->owner_count--; if (context->owner_count == 0) { + TRACE (GLIB_MAIN_CONTEXT_RELEASE (context)); + context->owner = NULL; if (context->waiters) @@ -3402,6 +3445,8 @@ g_main_context_prepare (GMainContext *context, return FALSE; } + TRACE (GLIB_MAIN_CONTEXT_BEFORE_PREPARE (context)); + #if 0 /* If recursing, finish up current dispatch, before starting over */ if (context->pending_dispatches) @@ -3451,6 +3496,7 @@ g_main_context_prepare (GMainContext *context, UNLOCK_CONTEXT (context); result = (* prepare) (source, &source_timeout); + TRACE (GLIB_MAIN_AFTER_PREPARE (source, prepare, source_timeout)); LOCK_CONTEXT (context); context->in_check_or_prepare--; @@ -3515,6 +3561,8 @@ g_main_context_prepare (GMainContext *context, } g_source_iter_clear (&iter); + TRACE (GLIB_MAIN_CONTEXT_AFTER_PREPARE (context, current_priority, n_ready)); + UNLOCK_CONTEXT (context); if (priority) @@ -3554,6 +3602,8 @@ g_main_context_query (GMainContext *context, LOCK_CONTEXT (context); + TRACE (GLIB_MAIN_CONTEXT_BEFORE_QUERY (context, max_priority)); + n_poll = 0; lastpollrec = NULL; for (pollrec = context->poll_records; pollrec; pollrec = pollrec->next) @@ -3596,7 +3646,10 @@ g_main_context_query (GMainContext *context, if (*timeout != 0) context->time_is_fresh = FALSE; } - + + TRACE (GLIB_MAIN_CONTEXT_AFTER_QUERY (context, context->timeout, + fds, n_poll)); + UNLOCK_CONTEXT (context); return n_poll; @@ -3639,14 +3692,21 @@ g_main_context_check (GMainContext *context, return FALSE; } + TRACE (GLIB_MAIN_CONTEXT_BEFORE_CHECK (context, max_priority, fds, n_fds)); + if (context->wake_up_rec.revents) - g_wakeup_acknowledge (context->wakeup); + { + TRACE (GLIB_MAIN_CONTEXT_WAKEUP_ACKNOWLEDGE (context)); + g_wakeup_acknowledge (context->wakeup); + } /* If the set of poll file descriptors changed, bail out * and let the main loop rerun */ if (context->poll_changed) { + TRACE (GLIB_MAIN_CONTEXT_AFTER_CHECK (context, 0)); + UNLOCK_CONTEXT (context); return FALSE; } @@ -3691,6 +3751,8 @@ g_main_context_check (GMainContext *context, result = (* check) (source); + TRACE (GLIB_MAIN_AFTER_CHECK (source, check, result)); + LOCK_CONTEXT (context); context->in_check_or_prepare--; } @@ -3756,6 +3818,8 @@ g_main_context_check (GMainContext *context, } g_source_iter_clear (&iter); + TRACE (GLIB_MAIN_CONTEXT_AFTER_CHECK (context, n_ready)); + UNLOCK_CONTEXT (context); return n_ready > 0; @@ -3775,11 +3839,15 @@ g_main_context_dispatch (GMainContext *context) { LOCK_CONTEXT (context); + TRACE (GLIB_MAIN_CONTEXT_BEFORE_DISPATCH (context)); + if (context->pending_dispatches->len > 0) { g_main_dispatch (context); } + TRACE (GLIB_MAIN_CONTEXT_AFTER_DISPATCH (context)); + UNLOCK_CONTEXT (context); } @@ -3941,7 +4009,9 @@ g_main_loop_new (GMainContext *context, loop->context = context; loop->is_running = is_running != FALSE; loop->ref_count = 1; - + + TRACE (GLIB_MAIN_LOOP_NEW (loop, context)); + return loop; } @@ -4074,6 +4144,8 @@ g_main_loop_quit (GMainLoop *loop) g_cond_broadcast (&loop->context->cond); UNLOCK_CONTEXT (loop->context); + + TRACE (GLIB_MAIN_LOOP_QUIT (loop)); } /** @@ -4489,6 +4561,8 @@ g_main_context_wakeup (GMainContext *context) g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); + TRACE (GLIB_MAIN_CONTEXT_WAKEUP (context)); + g_wakeup_signal (context->wakeup); } @@ -4587,6 +4661,8 @@ g_timeout_dispatch (GSource *source, again = callback (user_data); + TRACE (GLIB_TIMEOUT_DISPATCH (source, source->context, callback, user_data, again)); + if (again) g_timeout_set_expiration (timeout_source, g_source_get_time (source)); @@ -4711,6 +4787,9 @@ g_timeout_add_full (gint priority, g_source_set_callback (source, function, data, notify); id = g_source_attach (source, NULL); + + TRACE (GLIB_TIMEOUT_ADD (source, g_main_context_default (), id, priority, interval, function, data)); + g_source_unref (source); return id; @@ -5442,14 +5521,20 @@ g_idle_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) { + gboolean again; + if (!callback) { g_warning ("Idle source dispatched without callback\n" "You must call g_source_set_callback()."); return FALSE; } - - return callback (user_data); + + again = callback (user_data); + + TRACE (GLIB_IDLE_DISPATCH (source, source->context, callback, user_data, again)); + + return again; } /** @@ -5517,6 +5602,9 @@ g_idle_add_full (gint priority, g_source_set_callback (source, function, data, notify); id = g_source_attach (source, NULL); + + TRACE (GLIB_IDLE_ADD (source, g_main_context_default (), id, priority, function, data)); + g_source_unref (source); return id; diff --git a/glib/gthread.c b/glib/gthread.c index 88554ebc5..623ac63de 100644 --- a/glib/gthread.c +++ b/glib/gthread.c @@ -57,6 +57,7 @@ #include "gslice.h" #include "gstrfuncs.h" #include "gtestutils.h" +#include "glib_trace.h" /** * SECTION:threads @@ -770,6 +771,9 @@ g_thread_proxy (gpointer data) G_LOCK (g_thread_new); G_UNLOCK (g_thread_new); + TRACE (GLIB_THREAD_SPAWNED (thread->thread.func, thread->thread.data, + thread->name)); + if (thread->name) { g_system_thread_set_name (thread->name);