From: Mathieu Desnoyers Date: Fri, 17 Feb 2012 19:39:27 +0000 (-0500) Subject: API fix: Move callbacks to CTF plugin X-Git-Tag: v1.0.0-pre1~7 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=634d474be8d4262f5a3e549cdb6891de239f4fe4 API fix: Move callbacks to CTF plugin Signed-off-by: Mathieu Desnoyers --- diff --git a/formats/ctf/Makefile.am b/formats/ctf/Makefile.am index cf01be4b..f9468fcb 100644 --- a/formats/ctf/Makefile.am +++ b/formats/ctf/Makefile.am @@ -6,7 +6,8 @@ lib_LTLIBRARIES = libctf.la libctf_la_SOURCES = \ ctf.c \ - events.c + events.c \ + callbacks.c libctf_la_LIBADD = \ types/libctf-types.la \ diff --git a/formats/ctf/callbacks.c b/formats/ctf/callbacks.c new file mode 100644 index 00000000..f4e0a145 --- /dev/null +++ b/formats/ctf/callbacks.c @@ -0,0 +1,233 @@ +/* + * callbacks.c + * + * Babeltrace Library + * + * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation + * + * Author: Mathieu Desnoyers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static +struct bt_dependencies *_babeltrace_dependencies_create(const char *first, + va_list ap) +{ + const char *iter; + struct bt_dependencies *dep; + + dep = g_new0(struct bt_dependencies, 1); + dep->refcount = 1; + dep->deps = g_array_new(FALSE, TRUE, sizeof(GQuark)); + iter = first; + while (iter) { + GQuark q = g_quark_from_string(iter); + g_array_append_val(dep->deps, q); + iter = va_arg(ap, const char *); + } + return dep; +} + +struct bt_dependencies *babeltrace_dependencies_create(const char *first, ...) +{ + va_list ap; + struct bt_dependencies *deps; + + va_start(ap, first); + deps = _babeltrace_dependencies_create(first, ap); + va_end(ap); + return deps; +} + +/* + * bt_ctf_iter_add_callback: Add a callback to CTF iterator. + */ +int bt_ctf_iter_add_callback(struct bt_ctf_iter *iter, + bt_intern_str event, void *private_data, int flags, + enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data, + void *private_data), + struct bt_dependencies *depends, + struct bt_dependencies *weak_depends, + struct bt_dependencies *provides) +{ + int i, stream_id; + gpointer *event_id_ptr; + unsigned long event_id; + struct trace_collection *tc = iter->parent.ctx->tc; + + for (i = 0; i < tc->array->len; i++) { + struct ctf_trace *tin; + struct trace_descriptor *td_read; + + td_read = g_ptr_array_index(tc->array, i); + tin = container_of(td_read, struct ctf_trace, parent); + + for (stream_id = 0; stream_id < tin->streams->len; stream_id++) { + struct ctf_stream_class *stream; + struct bt_stream_callbacks *bt_stream_cb = NULL; + struct bt_callback_chain *bt_chain = NULL; + struct bt_callback new_callback; + + stream = g_ptr_array_index(tin->streams, stream_id); + + if (stream_id >= iter->callbacks->len) { + g_array_set_size(iter->callbacks, stream->stream_id + 1); + } + bt_stream_cb = &g_array_index(iter->callbacks, + struct bt_stream_callbacks, stream->stream_id); + if (!bt_stream_cb->per_id_callbacks) { + bt_stream_cb->per_id_callbacks = g_array_new(FALSE, TRUE, + sizeof(struct bt_callback_chain)); + } + + if (event) { + /* find the event id */ + event_id_ptr = g_hash_table_lookup(stream->event_quark_to_id, + (gconstpointer) (unsigned long) event); + /* event not found in this stream class */ + if (!event_id_ptr) { + fprintf(stderr, "event not found\n"); + continue; + } + event_id = (uint64_t)(unsigned long) *event_id_ptr; + + /* find or create the bt_callback_chain for this event */ + if (event_id >= bt_stream_cb->per_id_callbacks->len) { + g_array_set_size(bt_stream_cb->per_id_callbacks, event_id + 1); + } + bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks, + struct bt_callback_chain, event_id); + if (!bt_chain->callback) { + bt_chain->callback = g_array_new(FALSE, TRUE, + sizeof(struct bt_callback)); + } + } else { + /* callback for all events */ + if (!iter->main_callbacks.callback) { + iter->main_callbacks.callback = g_array_new(FALSE, TRUE, + sizeof(struct bt_callback)); + } + bt_chain = &iter->main_callbacks; + } + + new_callback.private_data = private_data; + new_callback.flags = flags; + new_callback.callback = callback; + new_callback.depends = depends; + new_callback.weak_depends = weak_depends; + new_callback.provides = provides; + + /* TODO : take care of priority, for now just FIFO */ + g_array_append_val(bt_chain->callback, new_callback); + } + } + + return 0; +} + +static +struct ctf_stream_event *extract_ctf_stream_event(struct ctf_stream *stream) +{ + struct ctf_stream_class *stream_class = stream->stream_class; + struct ctf_event *event_class; + struct ctf_stream_event *event; + uint64_t id = stream->event_id; + + if (id >= stream_class->events_by_id->len) { + fprintf(stderr, "[error] Event id %" PRIu64 " is outside range.\n", id); + return NULL; + } + event = g_ptr_array_index(stream->events_by_id, id); + if (!event) { + fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id); + return NULL; + } + event_class = g_ptr_array_index(stream_class->events_by_id, id); + if (!event_class) { + fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id); + return NULL; + } + + return event; +} + +void process_callbacks(struct bt_ctf_iter *iter, + struct ctf_stream *stream) +{ + struct bt_stream_callbacks *bt_stream_cb; + struct bt_callback_chain *bt_chain; + struct bt_callback *cb; + int i; + enum bt_cb_ret ret; + struct bt_ctf_event ctf_data; + + ctf_data.event = extract_ctf_stream_event(stream); + ctf_data.stream = stream; + + /* process all events callback first */ + if (iter->main_callbacks.callback) { + for (i = 0; i < iter->main_callbacks.callback->len; i++) { + cb = &g_array_index(iter->main_callbacks.callback, struct bt_callback, i); + if (!cb) + goto end; + ret = cb->callback(&ctf_data, cb->private_data); + switch (ret) { + case BT_CB_OK_STOP: + case BT_CB_ERROR_STOP: + goto end; + default: + break; + } + } + } + + /* process per event callbacks */ + bt_stream_cb = &g_array_index(iter->callbacks, + struct bt_stream_callbacks, stream->stream_id); + if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks) + goto end; + + if (stream->event_id >= bt_stream_cb->per_id_callbacks->len) + goto end; + bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks, + struct bt_callback_chain, stream->event_id); + if (!bt_chain || !bt_chain->callback) + goto end; + + for (i = 0; i < bt_chain->callback->len; i++) { + cb = &g_array_index(bt_chain->callback, struct bt_callback, i); + if (!cb) + goto end; + ret = cb->callback(&ctf_data, cb->private_data); + switch (ret) { + case BT_CB_OK_STOP: + case BT_CB_ERROR_STOP: + goto end; + default: + break; + } + } + +end: + return; +} diff --git a/formats/ctf/events.c b/formats/ctf/events.c index 27643fcb..8ecb7c48 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -49,11 +49,39 @@ struct bt_ctf_iter *bt_ctf_iter_create(struct bt_context *ctx, g_free(iter); return NULL; } + iter->callbacks = g_array_new(0, 1, sizeof(struct bt_stream_callbacks)); + iter->recalculate_dep_graph = 0; + iter->main_callbacks.callback = NULL; + iter->dep_gc = g_ptr_array_new(); return iter; } void bt_ctf_iter_destroy(struct bt_ctf_iter *iter) { + struct bt_stream_callbacks *bt_stream_cb; + struct bt_callback_chain *bt_chain; + int i, j; + + /* free all events callbacks */ + if (iter->main_callbacks.callback) + g_array_free(iter->main_callbacks.callback, TRUE); + + /* free per-event callbacks */ + for (i = 0; i < iter->callbacks->len; i++) { + bt_stream_cb = &g_array_index(iter->callbacks, + struct bt_stream_callbacks, i); + if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks) + continue; + for (j = 0; j < bt_stream_cb->per_id_callbacks->len; j++) { + bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks, + struct bt_callback_chain, j); + if (bt_chain->callback) { + g_array_free(bt_chain->callback, TRUE); + } + } + g_array_free(bt_stream_cb->per_id_callbacks, TRUE); + } + bt_iter_fini(&iter->parent); g_free(iter); } @@ -77,10 +105,10 @@ struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter) ret->event = g_ptr_array_index(ret->stream->events_by_id, ret->stream->event_id); - if (ret->stream->stream_id > iter->parent.callbacks->len) + if (ret->stream->stream_id > iter->callbacks->len) goto end; - process_callbacks(&iter->parent, ret->stream); + process_callbacks(iter, ret->stream); end: return ret; diff --git a/include/Makefile.am b/include/Makefile.am index f4e410d5..e675f9e3 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -8,13 +8,13 @@ babeltraceinclude_HEADERS = \ babeltrace/list.h babeltracectfinclude_HEADERS = \ - babeltrace/ctf/events.h + babeltrace/ctf/events.h \ + babeltrace/ctf/callbacks.h noinst_HEADERS = \ babeltrace/align.h \ babeltrace/babeltrace-internal.h \ babeltrace/bitfield.h \ - babeltrace/callbacks-internal.h \ babeltrace/compiler.h \ babeltrace/context-internal.h \ babeltrace/iterator-internal.h \ @@ -25,4 +25,5 @@ noinst_HEADERS = \ babeltrace/ctf/metadata.h \ babeltrace/ctf-text/types.h \ babeltrace/ctf/types.h \ + babeltrace/ctf/callbacks-internal.h \ babeltrace/trace-handle-internal.h diff --git a/include/babeltrace/babeltrace.h b/include/babeltrace/babeltrace.h index e533397c..83917c24 100644 --- a/include/babeltrace/babeltrace.h +++ b/include/babeltrace/babeltrace.h @@ -24,76 +24,4 @@ #include #include -/* Forward declarations */ -struct bt_iter; -struct bt_dependencies; - -enum bt_cb_ret { - BT_CB_OK = 0, - BT_CB_OK_STOP = 1, - BT_CB_ERROR_STOP = 2, - BT_CB_ERROR_CONTINUE = 3, -}; - -/* - * Receives a variable number of strings as parameter, ended with NULL. - */ -struct bt_dependencies *babeltrace_dependencies_create(const char *first, ...); - -/* - * struct bt_dependencies must be destroyed explicitly if not passed as - * parameter to a bt_iter_add_callback(). - */ -void babeltrace_dependencies_destroy(struct bt_dependencies *dep); - -/* - * bt_iter_add_callback: Add a callback to iterator. - * - * @iter: trace collection iterator (input) - * @event: event to target. 0 for all events. - * @private_data: private data pointer to pass to the callback - * @flags: specific flags controlling the behavior of this callback - * (or'd). - * - * @callback: function pointer to call - * @depends: struct bt_dependency detailing the required computation results. - * Ends with 0. - * @weak_depends: struct bt_dependency detailing the optional computation - * results that can be optionally consumed by this - * callback. - * @provides: struct bt_dependency detailing the computation results - * provided by this callback. - * Ends with 0. - * - * "depends", "weak_depends" and "provides" memory is handled by the - * babeltrace library after this call succeeds or fails. These objects - * can still be used by the caller until the babeltrace iterator is - * destroyed, but they belong to the babeltrace library. - * - * (note to implementor: we need to keep a gptrarray of struct - * bt_dependencies to "garbage collect" in struct bt_iter, and - * dependencies need to have a refcount to handle the case where they - * would be passed to more than one iterator. Upon iterator detroy, we - * iterate on all the gc ptrarray and decrement the refcounts, freeing - * if we reach 0.) - * (note to implementor: we calculate the dependency graph when - * bt_iter_read_event() is executed after a - * bt_iter_add_callback(). Beware that it is valid to create/add - * callbacks/read/add more callbacks/read some more.) - */ -int bt_iter_add_callback(struct bt_iter *iter, - bt_intern_str event, void *private_data, int flags, - enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data, - void *caller_data), - struct bt_dependencies *depends, - struct bt_dependencies *weak_depends, - struct bt_dependencies *provides); - -/* - * For flags parameter above. - */ -enum { - BT_FLAGS_FREE_PRIVATE_DATA = (1 << 0), -}; - #endif /* _BABELTRACE_H */ diff --git a/include/babeltrace/callbacks-internal.h b/include/babeltrace/callbacks-internal.h deleted file mode 100644 index c1257065..00000000 --- a/include/babeltrace/callbacks-internal.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _BABELTRACE_CALLBACKS_INTERNAL_H -#define _BABELTRACE_CALLBACKS_INTERNAL_H - -/* - * BabelTrace - * - * Internal callbacks header - * - * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation - * - * Author: Mathieu Desnoyers - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - */ - -#include -#include - -struct bt_callback { - int prio; /* Callback order priority. Lower first. Dynamically assigned from dependency graph. */ - void *private_data; - int flags; - struct bt_dependencies *depends; - struct bt_dependencies *weak_depends; - struct bt_dependencies *provides; - enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data, - void *private_data); -}; - -struct bt_callback_chain { - GArray *callback; /* Array of struct bt_callback, ordered by priority */ -}; - -/* - * per id callbacks need to be per stream class because event ID vs - * event name mapping can vary from stream to stream. - */ -struct bt_stream_callbacks { - GArray *per_id_callbacks; /* Array of struct bt_callback_chain */ -}; - -struct bt_dependencies { - GArray *deps; /* Array of GQuarks */ - int refcount; /* free when decremented to 0 */ -}; - -void process_callbacks(struct bt_iter *iter, - struct ctf_stream *stream); - -#endif /* _BABELTRACE_CALLBACKS_INTERNAL_H */ diff --git a/include/babeltrace/ctf/callbacks-internal.h b/include/babeltrace/ctf/callbacks-internal.h new file mode 100644 index 00000000..611851ae --- /dev/null +++ b/include/babeltrace/ctf/callbacks-internal.h @@ -0,0 +1,57 @@ +#ifndef _BABELTRACE_CALLBACKS_INTERNAL_H +#define _BABELTRACE_CALLBACKS_INTERNAL_H + +/* + * BabelTrace + * + * Internal callbacks header + * + * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation + * + * Author: Mathieu Desnoyers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ + +#include +#include + +struct bt_callback { + int prio; /* Callback order priority. Lower first. Dynamically assigned from dependency graph. */ + void *private_data; + int flags; + struct bt_dependencies *depends; + struct bt_dependencies *weak_depends; + struct bt_dependencies *provides; + enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data, + void *private_data); +}; + +struct bt_callback_chain { + GArray *callback; /* Array of struct bt_callback, ordered by priority */ +}; + +/* + * per id callbacks need to be per stream class because event ID vs + * event name mapping can vary from stream to stream. + */ +struct bt_stream_callbacks { + GArray *per_id_callbacks; /* Array of struct bt_callback_chain */ +}; + +struct bt_dependencies { + GArray *deps; /* Array of GQuarks */ + int refcount; /* free when decremented to 0 */ +}; + +void process_callbacks(struct bt_ctf_iter *iter, struct ctf_stream *stream); + +#endif /* _BABELTRACE_CALLBACKS_INTERNAL_H */ diff --git a/include/babeltrace/ctf/callbacks.h b/include/babeltrace/ctf/callbacks.h new file mode 100644 index 00000000..c0986f9e --- /dev/null +++ b/include/babeltrace/ctf/callbacks.h @@ -0,0 +1,100 @@ +#ifndef _BABELTRACE_CTF_CALLBACKS_H +#define _BABELTRACE_CTF_CALLBACKS_H + +/* + * BabelTrace + * + * CTF events API + * + * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation + * + * Author: Mathieu Desnoyers + * Julien Desfossez + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + */ + +#include + +/* Forward declarations */ +struct bt_ctf_iter; +struct bt_dependencies; + +enum bt_cb_ret { + BT_CB_OK = 0, + BT_CB_OK_STOP = 1, + BT_CB_ERROR_STOP = 2, + BT_CB_ERROR_CONTINUE = 3, +}; + +/* + * Receives a variable number of strings as parameter, ended with NULL. + */ +struct bt_dependencies *babeltrace_dependencies_create(const char *first, ...); + +/* + * struct bt_dependencies must be destroyed explicitly if not passed as + * parameter to a bt_iter_add_callback(). + */ +void babeltrace_dependencies_destroy(struct bt_dependencies *dep); + +/* + * bt_iter_add_callback: Add a callback to iterator. + * + * @iter: trace collection iterator (input) + * @event: event to target. 0 for all events. + * @private_data: private data pointer to pass to the callback + * @flags: specific flags controlling the behavior of this callback + * (or'd). + * + * @callback: function pointer to call + * @depends: struct bt_dependency detailing the required computation results. + * Ends with 0. + * @weak_depends: struct bt_dependency detailing the optional computation + * results that can be optionally consumed by this + * callback. + * @provides: struct bt_dependency detailing the computation results + * provided by this callback. + * Ends with 0. + * + * "depends", "weak_depends" and "provides" memory is handled by the + * babeltrace library after this call succeeds or fails. These objects + * can still be used by the caller until the babeltrace iterator is + * destroyed, but they belong to the babeltrace library. + * + * (note to implementor: we need to keep a gptrarray of struct + * bt_dependencies to "garbage collect" in struct bt_iter, and + * dependencies need to have a refcount to handle the case where they + * would be passed to more than one iterator. Upon iterator detroy, we + * iterate on all the gc ptrarray and decrement the refcounts, freeing + * if we reach 0.) + * (note to implementor: we calculate the dependency graph when + * bt_iter_read_event() is executed after a + * bt_iter_add_callback(). Beware that it is valid to create/add + * callbacks/read/add more callbacks/read some more.) + */ +int bt_ctf_iter_add_callback(struct bt_ctf_iter *iter, + bt_intern_str event, void *private_data, int flags, + enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data, + void *caller_data), + struct bt_dependencies *depends, + struct bt_dependencies *weak_depends, + struct bt_dependencies *provides); + +/* + * For flags parameter above. + */ +enum { + BT_FLAGS_FREE_PRIVATE_DATA = (1 << 0), +}; + +#endif /*_BABELTRACE_CTF_CALLBACKS_H */ diff --git a/include/babeltrace/ctf/events-internal.h b/include/babeltrace/ctf/events-internal.h index deff1058..c78470ec 100644 --- a/include/babeltrace/ctf/events-internal.h +++ b/include/babeltrace/ctf/events-internal.h @@ -24,10 +24,30 @@ */ #include +#include +#include +#include struct bt_ctf_iter { struct bt_iter parent; struct bt_ctf_event current_ctf_event; /* last read event */ + GArray *callbacks; /* Array of struct bt_stream_callbacks */ + struct bt_callback_chain main_callbacks; /* For all events */ + /* + * Flag indicating if dependency graph needs to be recalculated. + * Set by bt_iter_add_callback(), and checked (and + * cleared) by upon entry into bt_iter_read_event(). + * bt_iter_read_event() is responsible for calling dep + * graph calculation if it sees this flag set. + */ + int recalculate_dep_graph; + /* + * Array of pointers to struct bt_dependencies, for garbage + * collection. We're not using a linked list here because each + * struct bt_dependencies can belong to more than one + * bt_iter. + */ + GPtrArray *dep_gc; }; #endif /*_BABELTRACE_CTF_EVENTS_INTERNAL_H */ diff --git a/include/babeltrace/iterator-internal.h b/include/babeltrace/iterator-internal.h index c9b5d607..626a7a00 100644 --- a/include/babeltrace/iterator-internal.h +++ b/include/babeltrace/iterator-internal.h @@ -21,7 +21,6 @@ * all copies or substantial portions of the Software. */ -#include #include /* @@ -32,23 +31,6 @@ struct bt_iter { struct ptr_heap *stream_heap; struct bt_context *ctx; struct bt_iter_pos *end_pos; - GArray *callbacks; /* Array of struct bt_stream_callbacks */ - struct bt_callback_chain main_callbacks; /* For all events */ - /* - * Flag indicating if dependency graph needs to be recalculated. - * Set by bt_iter_add_callback(), and checked (and - * cleared) by upon entry into bt_iter_read_event(). - * bt_iter_read_event() is responsible for calling dep - * graph calculation if it sees this flag set. - */ - int recalculate_dep_graph; - /* - * Array of pointers to struct bt_dependencies, for garbage - * collection. We're not using a linked list here because each - * struct bt_dependencies can belong to more than one - * bt_iter. - */ - GPtrArray *dep_gc; }; int bt_iter_init(struct bt_iter *iter, diff --git a/lib/Makefile.am b/lib/Makefile.am index 5d069a96..db6db398 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -5,7 +5,6 @@ AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include lib_LTLIBRARIES = libbabeltrace.la libbabeltrace_la_SOURCES = babeltrace.c \ - callbacks.c \ iterator.c \ context.c \ trace-handle.c \ diff --git a/lib/callbacks.c b/lib/callbacks.c deleted file mode 100644 index fa212c91..00000000 --- a/lib/callbacks.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * callbacks.c - * - * Babeltrace Library - * - * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation - * - * Author: Mathieu Desnoyers - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static -struct bt_dependencies *_babeltrace_dependencies_create(const char *first, - va_list ap) -{ - const char *iter; - struct bt_dependencies *dep; - - dep = g_new0(struct bt_dependencies, 1); - dep->refcount = 1; - dep->deps = g_array_new(FALSE, TRUE, sizeof(GQuark)); - iter = first; - while (iter) { - GQuark q = g_quark_from_string(iter); - g_array_append_val(dep->deps, q); - iter = va_arg(ap, const char *); - } - return dep; -} - -struct bt_dependencies *babeltrace_dependencies_create(const char *first, ...) -{ - va_list ap; - struct bt_dependencies *deps; - - va_start(ap, first); - deps = _babeltrace_dependencies_create(first, ap); - va_end(ap); - return deps; -} - -/* - * bt_iter_add_callback: Add a callback to iterator. - */ -int bt_iter_add_callback(struct bt_iter *iter, - bt_intern_str event, void *private_data, int flags, - enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data, - void *private_data), - struct bt_dependencies *depends, - struct bt_dependencies *weak_depends, - struct bt_dependencies *provides) -{ - int i, stream_id; - gpointer *event_id_ptr; - unsigned long event_id; - struct trace_collection *tc = iter->ctx->tc; - - for (i = 0; i < tc->array->len; i++) { - struct ctf_trace *tin; - struct trace_descriptor *td_read; - - td_read = g_ptr_array_index(tc->array, i); - tin = container_of(td_read, struct ctf_trace, parent); - - for (stream_id = 0; stream_id < tin->streams->len; stream_id++) { - struct ctf_stream_class *stream; - struct bt_stream_callbacks *bt_stream_cb = NULL; - struct bt_callback_chain *bt_chain = NULL; - struct bt_callback new_callback; - - stream = g_ptr_array_index(tin->streams, stream_id); - - if (stream_id >= iter->callbacks->len) { - g_array_set_size(iter->callbacks, stream->stream_id + 1); - } - bt_stream_cb = &g_array_index(iter->callbacks, - struct bt_stream_callbacks, stream->stream_id); - if (!bt_stream_cb->per_id_callbacks) { - bt_stream_cb->per_id_callbacks = g_array_new(FALSE, TRUE, - sizeof(struct bt_callback_chain)); - } - - if (event) { - /* find the event id */ - event_id_ptr = g_hash_table_lookup(stream->event_quark_to_id, - (gconstpointer) (unsigned long) event); - /* event not found in this stream class */ - if (!event_id_ptr) { - fprintf(stderr, "event not found\n"); - continue; - } - event_id = (uint64_t)(unsigned long) *event_id_ptr; - - /* find or create the bt_callback_chain for this event */ - if (event_id >= bt_stream_cb->per_id_callbacks->len) { - g_array_set_size(bt_stream_cb->per_id_callbacks, event_id + 1); - } - bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks, - struct bt_callback_chain, event_id); - if (!bt_chain->callback) { - bt_chain->callback = g_array_new(FALSE, TRUE, - sizeof(struct bt_callback)); - } - } else { - /* callback for all events */ - if (!iter->main_callbacks.callback) { - iter->main_callbacks.callback = g_array_new(FALSE, TRUE, - sizeof(struct bt_callback)); - } - bt_chain = &iter->main_callbacks; - } - - new_callback.private_data = private_data; - new_callback.flags = flags; - new_callback.callback = callback; - new_callback.depends = depends; - new_callback.weak_depends = weak_depends; - new_callback.provides = provides; - - /* TODO : take care of priority, for now just FIFO */ - g_array_append_val(bt_chain->callback, new_callback); - } - } - - return 0; -} - -static -struct ctf_stream_event *extract_ctf_stream_event(struct ctf_stream *stream) -{ - struct ctf_stream_class *stream_class = stream->stream_class; - struct ctf_event *event_class; - struct ctf_stream_event *event; - uint64_t id = stream->event_id; - - if (id >= stream_class->events_by_id->len) { - fprintf(stderr, "[error] Event id %" PRIu64 " is outside range.\n", id); - return NULL; - } - event = g_ptr_array_index(stream->events_by_id, id); - if (!event) { - fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id); - return NULL; - } - event_class = g_ptr_array_index(stream_class->events_by_id, id); - if (!event_class) { - fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id); - return NULL; - } - - return event; -} - -void process_callbacks(struct bt_iter *iter, - struct ctf_stream *stream) -{ - struct bt_stream_callbacks *bt_stream_cb; - struct bt_callback_chain *bt_chain; - struct bt_callback *cb; - int i; - enum bt_cb_ret ret; - struct bt_ctf_event ctf_data; - - ctf_data.event = extract_ctf_stream_event(stream); - ctf_data.stream = stream; - - /* process all events callback first */ - if (iter->main_callbacks.callback) { - for (i = 0; i < iter->main_callbacks.callback->len; i++) { - cb = &g_array_index(iter->main_callbacks.callback, struct bt_callback, i); - if (!cb) - goto end; - ret = cb->callback(&ctf_data, cb->private_data); - switch (ret) { - case BT_CB_OK_STOP: - case BT_CB_ERROR_STOP: - goto end; - default: - break; - } - } - } - - /* process per event callbacks */ - bt_stream_cb = &g_array_index(iter->callbacks, - struct bt_stream_callbacks, stream->stream_id); - if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks) - goto end; - - if (stream->event_id >= bt_stream_cb->per_id_callbacks->len) - goto end; - bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks, - struct bt_callback_chain, stream->event_id); - if (!bt_chain || !bt_chain->callback) - goto end; - - for (i = 0; i < bt_chain->callback->len; i++) { - cb = &g_array_index(bt_chain->callback, struct bt_callback, i); - if (!cb) - goto end; - ret = cb->callback(&ctf_data, cb->private_data); - switch (ret) { - case BT_CB_OK_STOP: - case BT_CB_ERROR_STOP: - goto end; - default: - break; - } - } - -end: - return; -} diff --git a/lib/iterator.c b/lib/iterator.c index bf87193a..3dbe8788 100644 --- a/lib/iterator.c +++ b/lib/iterator.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -445,10 +444,6 @@ int bt_iter_init(struct bt_iter *iter, iter->stream_heap = g_new(struct ptr_heap, 1); iter->end_pos = end_pos; - iter->callbacks = g_array_new(0, 1, sizeof(struct bt_stream_callbacks)); - iter->recalculate_dep_graph = 0; - iter->main_callbacks.callback = NULL; - iter->dep_gc = g_ptr_array_new(); bt_context_get(ctx); iter->ctx = ctx; @@ -524,35 +519,10 @@ struct bt_iter *bt_iter_create(struct bt_context *ctx, void bt_iter_fini(struct bt_iter *iter) { - struct bt_stream_callbacks *bt_stream_cb; - struct bt_callback_chain *bt_chain; - int i, j; - if (iter->stream_heap) { heap_free(iter->stream_heap); g_free(iter->stream_heap); } - - /* free all events callbacks */ - if (iter->main_callbacks.callback) - g_array_free(iter->main_callbacks.callback, TRUE); - - /* free per-event callbacks */ - for (i = 0; i < iter->callbacks->len; i++) { - bt_stream_cb = &g_array_index(iter->callbacks, - struct bt_stream_callbacks, i); - if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks) - continue; - for (j = 0; j < bt_stream_cb->per_id_callbacks->len; j++) { - bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks, - struct bt_callback_chain, j); - if (bt_chain->callback) { - g_array_free(bt_chain->callback, TRUE); - } - } - g_array_free(bt_stream_cb->per_id_callbacks, TRUE); - } - bt_context_put(iter->ctx); }