From 5acf2ae6bdfb2bc6fa88e250a87ccc6ba3546d89 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Wed, 26 Apr 2017 13:18:26 -0400 Subject: [PATCH] Add the concept of a static trace MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit A static trace is a frozen trace with the additional property that you cannot call: * bt_ctf_trace_add_stream_class() * bt_ctf_trace_add_clock_class() * bt_ctf_stream_create() with any stream that belongs to the trace You can make a trace static with bt_ctf_trace_set_is_static(). This is not a reversible operation. You can check if a trace is static with bt_ctf_trace_is_static(). This static property can help a sink/filter component determine when the trace is "finished", in that a static trace guarantees that its streams are complete and there won't be more. It is up to the filter or sink component to know when each stream is considered to be ended. The end of a stream is provided by a notification. For example, a given filter could receive two streams of a given trace on two different ports. In this case, when the component gets both "stream end" notifications, and when their trace is static, it can discard any resource associated with this trace. This feature is essential for a CTF writer sink component to put CTF writer objects which are no longer needed. This is especially true when working with a ctf.lttng-live source which "never ends": the sink resources need to be released when it is known that there won't be more streams for a given trace, otherwise this would be considered a leak. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- include/babeltrace/ctf-ir/trace-internal.h | 1 + include/babeltrace/ctf-ir/trace.h | 42 ++++++++++++++++++++++ lib/ctf-ir/stream-class.c | 7 +++- lib/ctf-ir/stream.c | 10 ++++++ lib/ctf-ir/trace.c | 35 ++++++++++++++++-- 5 files changed, 92 insertions(+), 3 deletions(-) diff --git a/include/babeltrace/ctf-ir/trace-internal.h b/include/babeltrace/ctf-ir/trace-internal.h index eb3e0e27..8b6c1f5a 100644 --- a/include/babeltrace/ctf-ir/trace-internal.h +++ b/include/babeltrace/ctf-ir/trace-internal.h @@ -67,6 +67,7 @@ struct bt_ctf_trace { */ int valid; GPtrArray *listeners; /* Array of struct listener_wrapper */ + bool is_static; }; struct metadata_context { diff --git a/include/babeltrace/ctf-ir/trace.h b/include/babeltrace/ctf-ir/trace.h index 858d9681..a9e4fa89 100644 --- a/include/babeltrace/ctf-ir/trace.h +++ b/include/babeltrace/ctf-ir/trace.h @@ -769,6 +769,48 @@ extern struct bt_ctf_stream *bt_ctf_trace_get_stream( @{ */ +/** +@brief Returns whether or not the CTF IR trace class \p trace_class + is static. + +It is guaranteed that a static trace class will never contain new +streams, stream classes, or clock classes. A static class is always +frozen. + +This function returns \c true if bt_ctf_trace_set_is_static() was +previously called on it. + +@param[in] trace_class Trace class to check. +@returns \c true if \p trace_class is static, + +@sa bt_ctf_trace_set_is_static(): Makes a trace class static. +*/ +extern bool bt_ctf_trace_is_static(struct bt_ctf_trace *trace_class); + +/** +@brief Makes the CTF IR trace class \p trace_class static. + +A static trace class is frozen and you cannot call any modifying +function on it: + +- bt_ctf_trace_add_stream_class() +- bt_ctf_trace_add_clock_class() + +You cannot create a stream with bt_ctf_stream_create() with any of the +stream classes of a static trace class. + +@param[in] trace_class Trace class to make static. +@returns 0 on success, or a negative value on error. + +@prenotnull{trace_class} +@postrefcountsame{trace_class} +@postsuccessfrozen{trace_class} + +@sa bt_ctf_trace_is_static(): Checks whether or not a given trace class + is static. +*/ +extern int bt_ctf_trace_set_is_static(struct bt_ctf_trace *trace_class); + /** @brief Accepts the visitor \p visitor to visit the hierarchy of the CTF IR trace class \p trace_class. diff --git a/lib/ctf-ir/stream-class.c b/lib/ctf-ir/stream-class.c index 4fac7468..0463a119 100644 --- a/lib/ctf-ir/stream-class.c +++ b/lib/ctf-ir/stream-class.c @@ -336,6 +336,12 @@ int bt_ctf_stream_class_add_event_class( goto end; } + trace = bt_ctf_stream_class_get_trace(stream_class); + if (trace && trace->is_static) { + ret = -1; + goto end; + } + event_id = g_new(int64_t, 1); if (!event_id) { ret = -1; @@ -358,7 +364,6 @@ int bt_ctf_stream_class_add_event_class( goto end; } - trace = bt_ctf_stream_class_get_trace(stream_class); if (trace) { /* * If the stream class is associated with a trace, then diff --git a/lib/ctf-ir/stream.c b/lib/ctf-ir/stream.c index 949b11e9..7ab3544a 100644 --- a/lib/ctf-ir/stream.c +++ b/lib/ctf-ir/stream.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -367,6 +368,15 @@ struct bt_ctf_stream *bt_ctf_stream_create( goto error; } + if (bt_ctf_trace_is_static(trace)) { + /* + * A static trace has the property that all its stream + * classes, clock classes, and streams are definitive: + * no more can be added, and each object is also frozen. + */ + goto error; + } + stream = g_new0(struct bt_ctf_stream, 1); if (!stream) { goto error; diff --git a/lib/ctf-ir/trace.c b/lib/ctf-ir/trace.c index b850b4ff..067e7db9 100644 --- a/lib/ctf-ir/trace.c +++ b/lib/ctf-ir/trace.c @@ -389,7 +389,8 @@ int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace, { int ret = 0; - if (!trace || !bt_ctf_clock_class_is_valid(clock_class)) { + if (!trace || trace->is_static || + !bt_ctf_clock_class_is_valid(clock_class)) { ret = -1; goto end; } @@ -457,7 +458,7 @@ int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace, int event_class_count; struct bt_ctf_trace *current_parent_trace = NULL; - if (!trace || !stream_class) { + if (!trace || !stream_class || trace->is_static) { ret = -1; goto end; } @@ -1300,3 +1301,33 @@ end: bt_put(trace_packet_header_type); return ret; } + +bool bt_ctf_trace_is_static(struct bt_ctf_trace *trace) +{ + bool is_static = false; + + if (!trace) { + goto end; + } + + is_static = trace->is_static; + +end: + return is_static; +} + +int bt_ctf_trace_set_is_static(struct bt_ctf_trace *trace) +{ + int ret = 0; + + if (!trace) { + ret = -1; + goto end; + } + + trace->is_static = true; + bt_ctf_trace_freeze(trace); + +end: + return ret; +} -- 2.34.1