From 188edac1113dbbb29030681dbde2de0ada742499 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Thu, 20 Jun 2019 17:14:46 -0400 Subject: [PATCH] lib: remove stream activity messages The stream activity messages were introduced to support eventual use cases where the tracer could indicate when it stopped tracing and started again. To this day, no tracer which produces CTF provides this information, so these messages are not currently useful. Stream activity beginning messages are only ever sent just after stream beginning, and stream activity end messages are only ever sent just before stream end. Given that we will introduce a versioning system for the inter-component communication protocol, which will allow adding new features, we can remove the stream activity messages for now and add them at a latter time, if need be. This will reduce a little bit the amount of boilerplate needed to implement a simple source. So this patch removes the stream activity messages and handles all the fallout. One thing is that the stream activity messages optionally carried a default clock snapshot, which is used by the trimmer component. To compensate for this loss of feature, the stream beginning/end messages now have an optional default clock snapshot. Impacts around the codebase include (on top of simply removing handling of stream activity messages): - sink.text.details: Update to include the default clock snapshot for stream beginning/end. - flt.utils.trimmer: read clock snapshots from stream beginning/end messages (if not unknown). These messages can now trigger the end of the trimming, if their default clock snapshot is greater than the end time of the trimmer. Set the clock snapshot of the generated stream end message if the stream is ended by the trimmer's end bound (see note below for more details). If the stream is ended because of a stream end message that is within the trimmer's bounds, the stream end message is not modified. - iterator: handle stream message clock snapshots when validating clock monotonicity and doing an auto seek. Note about clock snapshot handling ---------------------------------- This patch fixes a bug in trimmer's handle_message_with_stream function, where it currently always returns BT_SELF_MESSAGE_ITERATOR_STATUS_OK, even when something fails. Changing it to return the "status" variable (as I suppose the original intention was) uncovers a latent bug with the clock snapshots of the "stream end" messages we generate (or for stream activity end messages, before this patch). Imagine a clock with a frequency of 1 and offset of 1000s. This means that the raw clock value 0 corresponds to the real time 1000s, 50 is 1050, and so on. This clock is unable to represent real times prior to 1000s. The sequence of messages generated by the source is: 1. Stream beginning, no clock snapshot 2. Packet beginning at 1050s (raw value 50) Here's what happens in the trimmer's mind if we pass --end=200: - Receive message 1, record that a stream is open - Receive message 2, realize its clock snapshot is greater than the end bound. Drop it and end the streams. - Generate a stream end message, use own end bound (200s) as the clock snapshot - Try to convert 200s to a raw value of the clock described above: it fails because 200s can't be represented by that clock. This is fixed by recording whether we have seen a message with a valid clock snapshot associated with the stream (which can therefore be represented by the stream's class' clock class). If we have, it means that the clock snapshot we'll choose for the stream end message we'll generate will be safe to convert to a clock value of that clock class. If we haven't, we are not sure. A similar problem happens in the iterator auto-seek code when using '--begin=200' and the same setup as above. We'll try to generate a stream beginning message with clock snapshot 200s, which is invalid. Note that this approach could be problematic in some corner cases, here's a known one: Once trimmer supports packet beginning/end messages without clock snapshots (remember that whether these messages have a clock snapshot or not is dictated by the stream class, it's not a choice per message), this could happen: - stream class defines that packet beginning messages don't have clock snapshots, but packet end messages do. - get stream beginning message without clock snapshot - get packet beginning message without clock snapshot - get event message with clock snapshot, greater than the end bound of 200s - since the stream class defines that packet end messages must have a clock snapshot, we can't get away by not putting one as is done by this patch. A more complex solution along these lines would probably be needed: - When trimmer receives the stream and packet beginning messages without clock snapshot, don't send them downstream but take a note of the state of the stream - When we do get a first message with a clock snapshot, then send the required stream and packet beginning messages. - If the trimming ends without having sent any content in this stream/packet, just pretend it never existed. Change-Id: I9a30a4c33b3f94497254ef93b24fed3b463e13fa Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/1527 Tested-by: jenkins Reviewed-by: Philippe Proulx --- configure.ac | 1 + include/Makefile.am | 6 +- include/babeltrace2/babeltrace.h | 6 +- include/babeltrace2/graph/message-const.h | 6 +- .../message-stream-activity-beginning-const.h | 52 -- .../graph/message-stream-activity-beginning.h | 56 -- .../graph/message-stream-activity-end-const.h | 52 -- .../graph/message-stream-activity-end.h | 56 -- .../graph/message-stream-beginning-const.h | 11 + .../graph/message-stream-beginning.h | 4 + ...ctivity-const.h => message-stream-const.h} | 17 +- .../graph/message-stream-end-const.h | 11 + .../babeltrace2/graph/message-stream-end.h | 4 + src/bindings/python/bt2/bt2/__init__.py.in | 1 - src/bindings/python/bt2/bt2/clock_snapshot.py | 4 - src/bindings/python/bt2/bt2/message.py | 79 +-- .../python/bt2/bt2/message_iterator.py | 60 +- .../python/bt2/bt2/native_bt_message.i | 6 +- src/lib/graph/iterator.c | 220 +++---- src/lib/graph/message/Makefile.am | 2 - src/lib/graph/message/message.h | 4 - src/lib/graph/message/stream-activity.c | 305 --------- src/lib/graph/message/stream-activity.h | 55 -- src/lib/graph/message/stream.c | 130 +++- src/lib/graph/message/stream.h | 19 + src/lib/lib-logging.c | 23 +- src/plugins/ctf/common/msg-iter/msg-iter.c | 98 +-- src/plugins/ctf/fs-sink/fs-sink.c | 5 - src/plugins/ctf/lttng-live/lttng-live.c | 33 - .../lttng-utils/debug-info/debug-info.c | 112 ---- src/plugins/text/details/write.c | 115 +--- src/plugins/text/dmesg/dmesg.c | 14 - src/plugins/utils/counter/counter.c | 10 - src/plugins/utils/counter/counter.h | 2 - src/plugins/utils/muxer/muxer.c | 21 - src/plugins/utils/trimmer/trimmer.c | 618 +++++++++--------- tests/Makefile.am | 6 + tests/bindings/python/bt2/test_message.py | 319 ++------- .../python/bt2/test_message_iterator.py | 12 +- .../test_trace_collection_message_iterator.py | 8 +- .../bt_plugin_trimmer_test.py | 65 ++ .../sink.ctf.fs/succeed/trace-double.expect | 8 +- .../sink.ctf.fs/succeed/trace-float.expect | 8 +- .../src.ctf.fs/succeed/trace-simple.expect | 8 +- .../succeed/trace-smalltrace.expect | 8 - tests/plugins/Makefile.am | 5 +- tests/plugins/flt.utils.trimmer/Makefile.am | 7 + tests/plugins/flt.utils.trimmer/test_trimming | 400 ++++++++++++ .../flt.utils.trimmer/test_trimming_wrapper | 34 + 49 files changed, 1247 insertions(+), 1859 deletions(-) delete mode 100644 include/babeltrace2/graph/message-stream-activity-beginning-const.h delete mode 100644 include/babeltrace2/graph/message-stream-activity-beginning.h delete mode 100644 include/babeltrace2/graph/message-stream-activity-end-const.h delete mode 100644 include/babeltrace2/graph/message-stream-activity-end.h rename include/babeltrace2/graph/{message-stream-activity-const.h => message-stream-const.h} (68%) delete mode 100644 src/lib/graph/message/stream-activity.c delete mode 100644 src/lib/graph/message/stream-activity.h create mode 100644 tests/data/plugins/flt.utils.trimmer/bt_plugin_trimmer_test.py create mode 100644 tests/plugins/flt.utils.trimmer/Makefile.am create mode 100755 tests/plugins/flt.utils.trimmer/test_trimming create mode 100755 tests/plugins/flt.utils.trimmer/test_trimming_wrapper diff --git a/configure.ac b/configure.ac index 35bf4238..25b8f866 100644 --- a/configure.ac +++ b/configure.ac @@ -781,6 +781,7 @@ AC_CONFIG_FILES([ tests/plugins/sink.ctf.fs/Makefile tests/plugins/sink.ctf.fs/succeed/Makefile tests/plugins/flt.lttng-utils.debug-info/Makefile + tests/plugins/flt.utils.trimmer/Makefile tests/utils/Makefile tests/utils/tap/Makefile ]) diff --git a/include/Makefile.am b/include/Makefile.am index 45071083..325f96d8 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -118,13 +118,9 @@ babeltrace2graphinclude_HEADERS = \ babeltrace2/graph/message-packet-beginning.h \ babeltrace2/graph/message-packet-end-const.h \ babeltrace2/graph/message-packet-end.h \ - babeltrace2/graph/message-stream-activity-beginning-const.h \ - babeltrace2/graph/message-stream-activity-beginning.h \ - babeltrace2/graph/message-stream-activity-const.h \ - babeltrace2/graph/message-stream-activity-end-const.h \ - babeltrace2/graph/message-stream-activity-end.h \ babeltrace2/graph/message-stream-beginning-const.h \ babeltrace2/graph/message-stream-beginning.h \ + babeltrace2/graph/message-stream-const.h \ babeltrace2/graph/message-stream-end-const.h \ babeltrace2/graph/message-stream-end.h \ babeltrace2/graph/port-const.h \ diff --git a/include/babeltrace2/babeltrace.h b/include/babeltrace2/babeltrace.h index 290b47a0..3cf60879 100644 --- a/include/babeltrace2/babeltrace.h +++ b/include/babeltrace2/babeltrace.h @@ -97,13 +97,9 @@ #include #include #include -#include -#include -#include -#include -#include #include #include +#include #include #include #include diff --git a/include/babeltrace2/graph/message-const.h b/include/babeltrace2/graph/message-const.h index 7716de59..889cefa5 100644 --- a/include/babeltrace2/graph/message-const.h +++ b/include/babeltrace2/graph/message-const.h @@ -41,10 +41,8 @@ typedef enum bt_message_type { BT_MESSAGE_TYPE_STREAM_END = 3, BT_MESSAGE_TYPE_PACKET_BEGINNING = 4, BT_MESSAGE_TYPE_PACKET_END = 5, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING = 6, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_END = 7, - BT_MESSAGE_TYPE_DISCARDED_EVENTS = 8, - BT_MESSAGE_TYPE_DISCARDED_PACKETS = 9, + BT_MESSAGE_TYPE_DISCARDED_EVENTS = 6, + BT_MESSAGE_TYPE_DISCARDED_PACKETS = 7, } bt_message_type; /** diff --git a/include/babeltrace2/graph/message-stream-activity-beginning-const.h b/include/babeltrace2/graph/message-stream-activity-beginning-const.h deleted file mode 100644 index 02aac777..00000000 --- a/include/babeltrace2/graph/message-stream-activity-beginning-const.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_BEGINNING_CONST_H -#define BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_BEGINNING_CONST_H - -/* - * Copyright 2019 Philippe Proulx - * - * 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* For bt_message, bt_clock_snapshot, bt_stream, bt_clock_class */ -#include - -/* For bt_message_stream_activity_clock_snapshot_state */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern bt_message_stream_activity_clock_snapshot_state -bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const( - const bt_message *msg, const bt_clock_snapshot **snapshot); - -extern const bt_clock_class * -bt_message_stream_activity_beginning_borrow_stream_class_default_clock_class_const( - const bt_message *msg); - -extern const bt_stream * -bt_message_stream_activity_beginning_borrow_stream_const( - const bt_message *message); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_BEGINNING_CONST_H */ diff --git a/include/babeltrace2/graph/message-stream-activity-beginning.h b/include/babeltrace2/graph/message-stream-activity-beginning.h deleted file mode 100644 index b1c2c3ee..00000000 --- a/include/babeltrace2/graph/message-stream-activity-beginning.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_BEGINNING_H -#define BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_BEGINNING_H - -/* - * Copyright 2019 Philippe Proulx - * - * 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include - -/* For bt_message, bt_self_message_iterator, bt_stream */ -#include - -/* For bt_message_stream_activity_clock_snapshot_state */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern bt_message *bt_message_stream_activity_beginning_create( - bt_self_message_iterator *message_iterator, - const bt_stream *stream); - -extern bt_stream *bt_message_stream_activity_beginning_borrow_stream( - bt_message *message); - -extern void bt_message_stream_activity_beginning_set_default_clock_snapshot_state( - bt_message *msg, - bt_message_stream_activity_clock_snapshot_state state); - -extern void bt_message_stream_activity_beginning_set_default_clock_snapshot( - bt_message *msg, uint64_t raw_value); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_BEGINNING_H */ diff --git a/include/babeltrace2/graph/message-stream-activity-end-const.h b/include/babeltrace2/graph/message-stream-activity-end-const.h deleted file mode 100644 index aaab5844..00000000 --- a/include/babeltrace2/graph/message-stream-activity-end-const.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_END_CONST_H -#define BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_END_CONST_H - -/* - * Copyright 2019 Philippe Proulx - * - * 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* For bt_message, bt_clock_snapshot, bt_stream, bt_clock_class */ -#include - -/* For bt_message_stream_activity_clock_snapshot_state */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern bt_message_stream_activity_clock_snapshot_state -bt_message_stream_activity_end_borrow_default_clock_snapshot_const( - const bt_message *msg, const bt_clock_snapshot **snapshot); - -extern const bt_clock_class * -bt_message_stream_activity_end_borrow_stream_class_default_clock_class_const( - const bt_message *msg); - -extern const bt_stream * -bt_message_stream_activity_end_borrow_stream_const( - const bt_message *message); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_END_CONST_H */ diff --git a/include/babeltrace2/graph/message-stream-activity-end.h b/include/babeltrace2/graph/message-stream-activity-end.h deleted file mode 100644 index b28f21b5..00000000 --- a/include/babeltrace2/graph/message-stream-activity-end.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_END_H -#define BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_END_H - -/* - * Copyright 2019 Philippe Proulx - * - * 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include - -/* For bt_message, bt_self_message_iterator, bt_stream */ -#include - -/* For bt_message_stream_activity_clock_snapshot_state */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern bt_message *bt_message_stream_activity_end_create( - bt_self_message_iterator *message_iterator, - const bt_stream *stream); - -extern void bt_message_stream_activity_end_set_default_clock_snapshot_state( - bt_message *msg, - bt_message_stream_activity_clock_snapshot_state state); - -extern void bt_message_stream_activity_end_set_default_clock_snapshot( - bt_message *msg, uint64_t raw_value); - -extern bt_stream *bt_message_stream_activity_end_borrow_stream( - bt_message *message); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_END_H */ diff --git a/include/babeltrace2/graph/message-stream-beginning-const.h b/include/babeltrace2/graph/message-stream-beginning-const.h index 630c30c1..3227cea1 100644 --- a/include/babeltrace2/graph/message-stream-beginning-const.h +++ b/include/babeltrace2/graph/message-stream-beginning-const.h @@ -27,6 +27,9 @@ /* For bt_message, bt_clock_snapshot, bt_stream */ #include +/* For bt_message_stream_clock_snapshot_state */ +#include + #ifdef __cplusplus extern "C" { #endif @@ -34,6 +37,14 @@ extern "C" { extern const bt_stream *bt_message_stream_beginning_borrow_stream_const( const bt_message *message); +extern enum bt_message_stream_clock_snapshot_state +bt_message_stream_beginning_borrow_default_clock_snapshot_const( + const bt_message *message, const bt_clock_snapshot **snapshot); + +extern const bt_clock_class * +bt_message_stream_beginning_borrow_stream_class_default_clock_class_const( + const bt_message *msg); + #ifdef __cplusplus } #endif diff --git a/include/babeltrace2/graph/message-stream-beginning.h b/include/babeltrace2/graph/message-stream-beginning.h index a5773a72..c2a6b6c8 100644 --- a/include/babeltrace2/graph/message-stream-beginning.h +++ b/include/babeltrace2/graph/message-stream-beginning.h @@ -39,6 +39,10 @@ bt_message *bt_message_stream_beginning_create( extern bt_stream *bt_message_stream_beginning_borrow_stream( bt_message *message); +extern +void bt_message_stream_beginning_set_default_clock_snapshot( + bt_message *message, uint64_t raw_value); + #ifdef __cplusplus } #endif diff --git a/include/babeltrace2/graph/message-stream-activity-const.h b/include/babeltrace2/graph/message-stream-const.h similarity index 68% rename from include/babeltrace2/graph/message-stream-activity-const.h rename to include/babeltrace2/graph/message-stream-const.h index b84e27b1..2c42ed9e 100644 --- a/include/babeltrace2/graph/message-stream-activity-const.h +++ b/include/babeltrace2/graph/message-stream-const.h @@ -1,8 +1,8 @@ -#ifndef BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_CONST_H -#define BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_CONST_H +#ifndef BABELTRACE2_GRAPH_MESSAGE_STREAM_CONST_H +#define BABELTRACE2_GRAPH_MESSAGE_STREAM_CONST_H /* - * Copyright 2019 Philippe Proulx + * Copyright 2019 Simon Marchi * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,14 +27,13 @@ extern "C" { #endif -typedef enum bt_message_stream_activity_clock_snapshot_state { - BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN, - BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN, - BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE, -} bt_message_stream_activity_clock_snapshot_state; +typedef enum bt_message_stream_clock_snapshot_state { + BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_UNKNOWN = 0, + BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN, +} bt_message_stream_clock_snapshot_state; #ifdef __cplusplus } #endif -#endif /* BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_CONST_H */ +#endif /* BABELTRACE2_GRAPH_MESSAGE_STREAM_CONST_H */ diff --git a/include/babeltrace2/graph/message-stream-end-const.h b/include/babeltrace2/graph/message-stream-end-const.h index f4cabd3b..b182ee87 100644 --- a/include/babeltrace2/graph/message-stream-end-const.h +++ b/include/babeltrace2/graph/message-stream-end-const.h @@ -27,6 +27,9 @@ /* For bt_message, bt_clock_snapshot, bt_stream */ #include +/* For bt_message_stream_clock_snapshot_state */ +#include + #ifdef __cplusplus extern "C" { #endif @@ -34,6 +37,14 @@ extern "C" { extern const bt_stream *bt_message_stream_end_borrow_stream_const( const bt_message *message); +extern enum bt_message_stream_clock_snapshot_state +bt_message_stream_end_borrow_default_clock_snapshot_const( + const bt_message *message, const bt_clock_snapshot **snapshot); + +extern const bt_clock_class * +bt_message_stream_end_borrow_stream_class_default_clock_class_const( + const bt_message *msg); + #ifdef __cplusplus } #endif diff --git a/include/babeltrace2/graph/message-stream-end.h b/include/babeltrace2/graph/message-stream-end.h index 4f13eb1c..5077880f 100644 --- a/include/babeltrace2/graph/message-stream-end.h +++ b/include/babeltrace2/graph/message-stream-end.h @@ -39,6 +39,10 @@ bt_message *bt_message_stream_end_create( extern bt_stream *bt_message_stream_end_borrow_stream( bt_message *message); +extern +void bt_message_stream_end_set_default_clock_snapshot( + bt_message *message, uint64_t raw_value); + #ifdef __cplusplus } #endif diff --git a/src/bindings/python/bt2/bt2/__init__.py.in b/src/bindings/python/bt2/bt2/__init__.py.in index 0faede10..b8639978 100644 --- a/src/bindings/python/bt2/bt2/__init__.py.in +++ b/src/bindings/python/bt2/bt2/__init__.py.in @@ -63,7 +63,6 @@ from bt2.value import * from bt2.value import _Value from bt2.value import _IntegerValue from bt2.clock_snapshot import _UnknownClockSnapshot -from bt2.clock_snapshot import _InfiniteClockSnapshot class Error(Exception): diff --git a/src/bindings/python/bt2/bt2/clock_snapshot.py b/src/bindings/python/bt2/bt2/clock_snapshot.py index 46abdc78..adf03e39 100644 --- a/src/bindings/python/bt2/bt2/clock_snapshot.py +++ b/src/bindings/python/bt2/bt2/clock_snapshot.py @@ -60,7 +60,3 @@ class _ClockSnapshot(object._UniqueObject): class _UnknownClockSnapshot: pass - - -class _InfiniteClockSnapshot: - pass diff --git a/src/bindings/python/bt2/bt2/message.py b/src/bindings/python/bt2/bt2/message.py index 15e25f20..e4610191 100644 --- a/src/bindings/python/bt2/bt2/message.py +++ b/src/bindings/python/bt2/bt2/message.py @@ -94,81 +94,42 @@ class _PacketEndMessage(_PacketMessage): _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_packet_end_borrow_default_clock_snapshot_const) -class _StreamMessage(_Message): +class _StreamMessage(_Message, _MessageWithDefaultClockSnapshot): @property def stream(self): stream_ptr = self._borrow_stream_ptr(self._ptr) assert stream_ptr return bt2.stream._Stream._create_from_ptr_and_get_ref(stream_ptr) - -class _StreamBeginningMessage(_StreamMessage): - _borrow_stream_ptr = staticmethod(native_bt.message_stream_beginning_borrow_stream) - - -class _StreamEndMessage(_StreamMessage): - _borrow_stream_ptr = staticmethod(native_bt.message_stream_end_borrow_stream) - - -# Specific type to pass an unknown clock snapshot when creating a stream -# beginning/end message. -class _StreamActivityMessageUnknownClockSnapshot: - pass - - -# Specific type to pass an infinite clock snapshot when creating a -# stream beginning/end message. -class _StreamActivityMessageInfiniteClockSnapshot: - pass - - -class _StreamActivityMessage(_Message): @property def default_clock_snapshot(self): + self._check_has_default_clock_class(self.stream.cls.default_clock_class) + status, snapshot_ptr = self._borrow_default_clock_snapshot_ptr(self._ptr) - if status == native_bt.MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN: - cs_type = bt2.clock_snapshot._ClockSnapshot - assert snapshot_ptr is not None - return cs_type._create_from_ptr_and_get_ref(snapshot_ptr, self._ptr, - self._get_ref, self._put_ref) - elif status == native_bt.MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN: + if status == native_bt.MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_UNKNOWN: return bt2.clock_snapshot._UnknownClockSnapshot() - elif status == native_bt.MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE: - return bt2.clock_snapshot._InfiniteClockSnapshot() - else: - raise bt2.Error('cannot borrow default clock snapshot from message') - - def _default_clock_snapshot(self, value): - if type(value) is _StreamActivityMessageUnknownClockSnapshot: - self._set_default_clock_snapshot_state(self._ptr, native_bt.MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN) - elif type(value) is _StreamActivityMessageInfiniteClockSnapshot: - self._set_default_clock_snapshot_state(self._ptr, native_bt.MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE) - else: - assert utils._is_uint64(value) - self._set_default_clock_snapshot(self._ptr, value) - _default_clock_snapshot = property(fset=_default_clock_snapshot) + return bt2.clock_snapshot._ClockSnapshot._create_from_ptr_and_get_ref( + snapshot_ptr, self._ptr, self._get_ref, self._put_ref) - @property - def stream(self): - stream_ptr = self._borrow_stream_ptr(self._ptr) - assert stream_ptr - return bt2.stream._Stream._create_from_ptr_and_get_ref(stream_ptr) + def _default_clock_snapshot(self, raw_value): + utils._check_uint64(raw_value) + self._set_default_clock_snapshot(self._ptr, raw_value) + _default_clock_snapshot = property(fset=_default_clock_snapshot) -class _StreamActivityBeginningMessage(_StreamActivityMessage): - _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_stream_activity_beginning_borrow_default_clock_snapshot_const) - _set_default_clock_snapshot = staticmethod(native_bt.message_stream_activity_beginning_set_default_clock_snapshot) - _set_default_clock_snapshot_state = staticmethod(native_bt.message_stream_activity_beginning_set_default_clock_snapshot_state) - _borrow_stream_ptr = staticmethod(native_bt.message_stream_activity_beginning_borrow_stream) +class _StreamBeginningMessage(_StreamMessage): + _borrow_stream_ptr = staticmethod(native_bt.message_stream_beginning_borrow_stream) + _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_stream_beginning_borrow_default_clock_snapshot_const) + _set_default_clock_snapshot = staticmethod(native_bt.message_stream_beginning_set_default_clock_snapshot) -class _StreamActivityEndMessage(_StreamActivityMessage): - _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_stream_activity_end_borrow_default_clock_snapshot_const) - _set_default_clock_snapshot = staticmethod(native_bt.message_stream_activity_end_set_default_clock_snapshot) - _set_default_clock_snapshot_state = staticmethod(native_bt.message_stream_activity_end_set_default_clock_snapshot_state) - _borrow_stream_ptr = staticmethod(native_bt.message_stream_activity_end_borrow_stream) + +class _StreamEndMessage(_StreamMessage): + _borrow_stream_ptr = staticmethod(native_bt.message_stream_end_borrow_stream) + _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_stream_end_borrow_default_clock_snapshot_const) + _set_default_clock_snapshot = staticmethod(native_bt.message_stream_end_set_default_clock_snapshot) class _MessageIteratorInactivityMessage(_Message, _MessageWithDefaultClockSnapshot): @@ -246,8 +207,6 @@ _MESSAGE_TYPE_TO_CLS = { native_bt.MESSAGE_TYPE_STREAM_END: _StreamEndMessage, native_bt.MESSAGE_TYPE_PACKET_BEGINNING: _PacketBeginningMessage, native_bt.MESSAGE_TYPE_PACKET_END: _PacketEndMessage, - native_bt.MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: _StreamActivityBeginningMessage, - native_bt.MESSAGE_TYPE_STREAM_ACTIVITY_END: _StreamActivityEndMessage, native_bt.MESSAGE_TYPE_DISCARDED_EVENTS: _DiscardedEventsMessage, native_bt.MESSAGE_TYPE_DISCARDED_PACKETS: _DiscardedPacketsMessage, } diff --git a/src/bindings/python/bt2/bt2/message_iterator.py b/src/bindings/python/bt2/bt2/message_iterator.py index 379e9ab9..ebf0619c 100644 --- a/src/bindings/python/bt2/bt2/message_iterator.py +++ b/src/bindings/python/bt2/bt2/message_iterator.py @@ -198,71 +198,33 @@ class _UserMessageIterator(_MessageIterator): return bt2.message._MessageIteratorInactivityMessage(ptr) - _unknown_clock_snapshot = bt2.message._StreamActivityMessageUnknownClockSnapshot() - _infinite_clock_snapshot = bt2.message._StreamActivityMessageInfiniteClockSnapshot() - - @staticmethod - def _bt_validate_stream_activity_message_default_clock_snapshot(stream, default_cs): - isinst_infinite = isinstance(default_cs, bt2.message._StreamActivityMessageInfiniteClockSnapshot) - isinst_unknown = isinstance(default_cs, bt2.message._StreamActivityMessageUnknownClockSnapshot) - - if utils._is_uint64(default_cs): - pass - elif isinst_infinite or isinst_unknown: - if default_cs is not _UserMessageIterator._unknown_clock_snapshot and default_cs is not _UserMessageIterator._infinite_clock_snapshot: - raise ValueError('unexpected value for default clock snapshot') - else: - raise TypeError("unexpected type '{}' for default clock snapshot".format(default_cs.__class__.__name__)) - - if stream.cls.default_clock_class is None: - if utils._is_uint64(default_cs): - raise ValueError('stream activity messages in this stream cannot have a known default clock snapshot') - - def _create_stream_beginning_message(self, stream): + def _create_stream_beginning_message(self, stream, default_clock_snapshot=None): utils._check_type(stream, bt2.stream._Stream) ptr = native_bt.message_stream_beginning_create(self._bt_ptr, stream._ptr) if ptr is None: raise bt2.CreationError('cannot create stream beginning message object') - return bt2.message._StreamBeginningMessage(ptr) - - def _create_stream_activity_beginning_message(self, stream, - default_clock_snapshot=_unknown_clock_snapshot): - utils._check_type(stream, bt2.stream._Stream) - self._bt_validate_stream_activity_message_default_clock_snapshot(stream, default_clock_snapshot) - ptr = native_bt.message_stream_activity_beginning_create(self._bt_ptr, stream._ptr) - - if ptr is None: - raise bt2.CreationError( - 'cannot create stream activity beginning message object') - - msg = bt2.message._StreamActivityBeginningMessage(ptr) - msg._default_clock_snapshot = default_clock_snapshot - return msg + msg = bt2.message._StreamBeginningMessage(ptr) - def _create_stream_activity_end_message(self, stream, - default_clock_snapshot=_unknown_clock_snapshot): - utils._check_type(stream, bt2.stream._Stream) - self._bt_validate_stream_activity_message_default_clock_snapshot(stream, default_clock_snapshot) - ptr = native_bt.message_stream_activity_end_create(self._bt_ptr, stream._ptr) - - if ptr is None: - raise bt2.CreationError( - 'cannot create stream activity end message object') + if default_clock_snapshot is not None: + msg._default_clock_snapshot = default_clock_snapshot - msg = bt2.message._StreamActivityEndMessage(ptr) - msg._default_clock_snapshot = default_clock_snapshot return msg - def _create_stream_end_message(self, stream): + def _create_stream_end_message(self, stream, default_clock_snapshot=None): utils._check_type(stream, bt2.stream._Stream) ptr = native_bt.message_stream_end_create(self._bt_ptr, stream._ptr) if ptr is None: raise bt2.CreationError('cannot create stream end message object') - return bt2.message._StreamEndMessage(ptr) + msg = bt2.message._StreamEndMessage(ptr) + + if default_clock_snapshot is not None: + msg._default_clock_snapshot = default_clock_snapshot + + return msg def _create_packet_beginning_message(self, packet, default_clock_snapshot=None): utils._check_type(packet, bt2.packet._Packet) diff --git a/src/bindings/python/bt2/bt2/native_bt_message.i b/src/bindings/python/bt2/bt2/native_bt_message.i index b56a6d27..06726f42 100644 --- a/src/bindings/python/bt2/bt2/native_bt_message.i +++ b/src/bindings/python/bt2/bt2/native_bt_message.i @@ -57,11 +57,7 @@ %include %include %include -%include -%include -%include -%include -%include +%include %include %include %include diff --git a/src/lib/graph/iterator.c b/src/lib/graph/iterator.c index 2e2ab405..048daaf1 100644 --- a/src/lib/graph/iterator.c +++ b/src/lib/graph/iterator.c @@ -49,9 +49,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -80,7 +77,6 @@ #include "message/message-iterator-inactivity.h" #include "message/stream.h" #include "message/packet.h" -#include "message/stream-activity.h" #include "lib/func-status.h" /* @@ -589,21 +585,17 @@ bool clock_snapshots_are_monotonic_one( clock_snapshot = packet_msg->default_cs; break; } - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: + case BT_MESSAGE_TYPE_STREAM_BEGINNING: + case BT_MESSAGE_TYPE_STREAM_END: { - struct bt_message_stream_activity *str_act_msg = - (struct bt_message_stream_activity *) msg; - - if (str_act_msg->default_cs_state == BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN) { - clock_snapshot = str_act_msg->default_cs; + struct bt_message_stream *stream_msg = (struct bt_message_stream *) msg; + if (stream_msg->default_cs_state != BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) { + goto end; } + + clock_snapshot = stream_msg->default_cs; break; } - case BT_MESSAGE_TYPE_STREAM_BEGINNING: - case BT_MESSAGE_TYPE_STREAM_END: - /* These messages don't have clock snapshots. */ - goto end; case BT_MESSAGE_TYPE_DISCARDED_EVENTS: case BT_MESSAGE_TYPE_DISCARDED_PACKETS: { @@ -1297,20 +1289,18 @@ struct auto_seek_stream_state { * Value representing which step of this timeline we are at. * * time ---> - * [SB] 1 [SAB] 2 [PB] 3 [PE] 2 [SAE] 1 [SE] + * [SB] 1 [PB] 2 [PE] 1 [SE] * * At each point in the timeline, the messages we need to replicate are: * * 1: Stream beginning - * 2: Stream beginning, stream activity beginning - * 3: Stream beginning, stream activity beginning, packet beginning + * 2: Stream beginning, packet beginning * * Before "Stream beginning" and after "Stream end", we don't need to * replicate anything as the stream doesn't exist. */ enum { AUTO_SEEK_STREAM_STATE_STREAM_BEGAN, - AUTO_SEEK_STREAM_STATE_STREAM_ACTIVITY_BEGAN, AUTO_SEEK_STREAM_STATE_PACKET_BEGAN, } state; @@ -1320,6 +1310,9 @@ struct auto_seek_stream_state { * alive by the time we use it. */ struct bt_packet *packet; + + /* Have we see a message with a clock snapshot yet? */ + bool seen_clock_snapshot; }; static @@ -1472,63 +1465,20 @@ int auto_seek_handle_message( goto skip_msg; } } - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: + case BT_MESSAGE_TYPE_STREAM_BEGINNING: + case BT_MESSAGE_TYPE_STREAM_END: { - const struct bt_message_stream_activity *stream_act_msg = - (const void *) msg; + struct bt_message_stream *stream_msg = + (struct bt_message_stream *) msg; - switch (stream_act_msg->default_cs_state) { - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN: - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE: - /* - * -inf is always less than any requested time, - * and we can't assume any specific time for an - * unknown clock snapshot, so skip this. - */ + if (stream_msg->default_cs_state != BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) { + /* Ignore */ goto skip_msg; - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN: - clk_snapshot = stream_act_msg->default_cs; - BT_ASSERT(clk_snapshot); - break; - default: - abort(); } + clk_snapshot = stream_msg->default_cs; break; } - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - { - const struct bt_message_stream_activity *stream_act_msg = - (const void *) msg; - - switch (stream_act_msg->default_cs_state) { - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN: - /* - * We can't assume any specific time for an - * unknown clock snapshot, so skip this. - */ - goto skip_msg; - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE: - /* - * +inf is always greater than any requested - * time. - */ - *got_first = true; - goto push_msg; - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN: - clk_snapshot = stream_act_msg->default_cs; - BT_ASSERT(clk_snapshot); - break; - default: - abort(); - } - - break; - } - case BT_MESSAGE_TYPE_STREAM_BEGINNING: - case BT_MESSAGE_TYPE_STREAM_END: - /* Ignore */ - goto skip_msg; default: abort(); } @@ -1563,39 +1513,47 @@ skip_msg: stream_state->state = AUTO_SEEK_STREAM_STATE_STREAM_BEGAN; + if (stream_msg->default_cs_state == BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) { + stream_state->seen_clock_snapshot = true; + } + BT_ASSERT(!bt_g_hash_table_contains(stream_states, stream_msg->stream)); g_hash_table_insert(stream_states, stream_msg->stream, stream_state); break; } - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: + case BT_MESSAGE_TYPE_PACKET_BEGINNING: { - const struct bt_message_stream_activity *stream_act_msg = + const struct bt_message_packet *packet_msg = (const void *) msg; struct auto_seek_stream_state *stream_state; - /* Update stream's state: stream activity began. */ - stream_state = g_hash_table_lookup(stream_states, stream_act_msg->stream); + /* Update stream's state: packet began. */ + stream_state = g_hash_table_lookup(stream_states, packet_msg->packet->stream); BT_ASSERT(stream_state); BT_ASSERT(stream_state->state == AUTO_SEEK_STREAM_STATE_STREAM_BEGAN); - stream_state->state = AUTO_SEEK_STREAM_STATE_STREAM_ACTIVITY_BEGAN; + stream_state->state = AUTO_SEEK_STREAM_STATE_PACKET_BEGAN; BT_ASSERT(!stream_state->packet); + stream_state->packet = packet_msg->packet; + + if (packet_msg->packet->stream->class->packets_have_beginning_default_clock_snapshot) { + stream_state->seen_clock_snapshot = true; + } + break; } - case BT_MESSAGE_TYPE_PACKET_BEGINNING: + case BT_MESSAGE_TYPE_EVENT: { - const struct bt_message_packet *packet_msg = - (const void *) msg; + const struct bt_message_event *event_msg = (const void *) msg; struct auto_seek_stream_state *stream_state; - /* Update stream's state: packet began. */ - stream_state = g_hash_table_lookup(stream_states, packet_msg->packet->stream); + stream_state = g_hash_table_lookup(stream_states, + event_msg->event->packet->stream); BT_ASSERT(stream_state); - BT_ASSERT(stream_state->state == AUTO_SEEK_STREAM_STATE_STREAM_ACTIVITY_BEGAN); - stream_state->state = AUTO_SEEK_STREAM_STATE_PACKET_BEGAN; - BT_ASSERT(!stream_state->packet); - stream_state->packet = packet_msg->packet; + // HELPME: are we sure that event messages have clock snapshots at this point? + stream_state->seen_clock_snapshot = true; + break; } case BT_MESSAGE_TYPE_PACKET_END: @@ -1609,24 +1567,14 @@ skip_msg: BT_ASSERT(stream_state); BT_ASSERT(stream_state->state == AUTO_SEEK_STREAM_STATE_PACKET_BEGAN); - stream_state->state = AUTO_SEEK_STREAM_STATE_STREAM_ACTIVITY_BEGAN; + stream_state->state = AUTO_SEEK_STREAM_STATE_STREAM_BEGAN; BT_ASSERT(stream_state->packet); stream_state->packet = NULL; - break; - } - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - { - const struct bt_message_stream_activity *stream_act_msg = - (const void *) msg; - struct auto_seek_stream_state *stream_state; - /* Update stream's state: stream activity ended. */ - stream_state = g_hash_table_lookup(stream_states, stream_act_msg->stream); - BT_ASSERT(stream_state); + if (packet_msg->packet->stream->class->packets_have_end_default_clock_snapshot) { + stream_state->seen_clock_snapshot = true; + } - BT_ASSERT(stream_state->state == AUTO_SEEK_STREAM_STATE_STREAM_ACTIVITY_BEGAN); - stream_state->state = AUTO_SEEK_STREAM_STATE_STREAM_BEGAN; - BT_ASSERT(!stream_state->packet); break; } case BT_MESSAGE_TYPE_STREAM_END: @@ -1643,6 +1591,23 @@ skip_msg: g_hash_table_remove(stream_states, stream_msg->stream); break; } + case BT_MESSAGE_TYPE_DISCARDED_EVENTS: + case BT_MESSAGE_TYPE_DISCARDED_PACKETS: + { + const struct bt_message_discarded_items *discarded_msg = + (const void *) msg; + struct auto_seek_stream_state *stream_state; + + stream_state = g_hash_table_lookup(stream_states, discarded_msg->stream); + BT_ASSERT(stream_state); + + if ((msg->type == BT_MESSAGE_TYPE_DISCARDED_EVENTS && discarded_msg->stream->class->discarded_events_have_default_clock_snapshots) || + (msg->type == BT_MESSAGE_TYPE_DISCARDED_PACKETS && discarded_msg->stream->class->discarded_packets_have_default_clock_snapshots)) { + stream_state->seen_clock_snapshot = true; + } + + break; + } default: break; } @@ -1934,44 +1899,57 @@ bt_self_component_port_input_message_iterator_seek_ns_from_origin( bt_message *msg; const bt_clock_class *clock_class = bt_stream_class_borrow_default_clock_class_const( bt_stream_borrow_class_const(stream)); - uint64_t raw_value; - - if (clock_raw_value_from_ns_from_origin(clock_class, ns_from_origin, &raw_value) != 0) { - BT_LIB_LOGW_APPEND_CAUSE( - "Could not convert nanoseconds from origin to clock value: " - "ns-from-origin=%" PRId64 ", %![cc-]+K", - ns_from_origin, clock_class); - status = BT_FUNC_STATUS_ERROR; - goto end; + /* Initialize to silence maybe-uninitialized warning. */ + uint64_t raw_value = 0; + + /* + * If we haven't seen a message with a clock snapshot, we don't know if our seek time is within + * the clock's range, so it wouldn't be safe to try to convert ns_from_origin to a clock value. + * + * Also, it would be a bit of a lie to generate a stream begin message with the seek time as its + * clock snapshot, because we don't really know if the stream existed at that time. If we have + * seen a message with a clock snapshot in our seeking, then we are sure that the + * seek time is not below the clock range, and we know the stream was active at that + * time (and that we cut it short). + */ + if (stream_state->seen_clock_snapshot) { + if (clock_raw_value_from_ns_from_origin(clock_class, ns_from_origin, &raw_value) != 0) { + BT_LIB_LOGW("Could not convert nanoseconds from origin to clock value: ns-from-origin=%" PRId64 ", %![cc-]+K", + ns_from_origin, clock_class); + status = BT_FUNC_STATUS_ERROR; + goto end; + } } switch (stream_state->state) { case AUTO_SEEK_STREAM_STATE_PACKET_BEGAN: BT_ASSERT(stream_state->packet); BT_LIB_LOGD("Creating packet message: %![packet-]+a", stream_state->packet); - msg = bt_message_packet_beginning_create_with_default_clock_snapshot( - (bt_self_message_iterator *) iterator, stream_state->packet, raw_value); - if (!msg) { - status = BT_FUNC_STATUS_MEMORY_ERROR; - goto end; + + if (stream->class->packets_have_beginning_default_clock_snapshot) { + /* + * If we are in the PACKET_BEGAN state, it means we have seen a "packet beginning" + * message. If "packet beginning" packets have clock snapshots, then we must have + * seen a clock snapshot. + */ + BT_ASSERT(stream_state->seen_clock_snapshot); + + msg = bt_message_packet_beginning_create_with_default_clock_snapshot( + (bt_self_message_iterator *) iterator, stream_state->packet, raw_value); + } else { + msg = bt_message_packet_beginning_create((bt_self_message_iterator *) iterator, + stream_state->packet); } - g_queue_push_head(iterator->auto_seek.msgs, msg); - msg = NULL; - /* fall-thru */ - case AUTO_SEEK_STREAM_STATE_STREAM_ACTIVITY_BEGAN: - msg = bt_message_stream_activity_beginning_create( - (bt_self_message_iterator *) iterator, stream); if (!msg) { status = BT_FUNC_STATUS_MEMORY_ERROR; goto end; } - bt_message_stream_activity_beginning_set_default_clock_snapshot(msg, raw_value); - g_queue_push_head(iterator->auto_seek.msgs, msg); msg = NULL; /* fall-thru */ + case AUTO_SEEK_STREAM_STATE_STREAM_BEGAN: msg = bt_message_stream_beginning_create( (bt_self_message_iterator *) iterator, stream); @@ -1980,6 +1958,10 @@ bt_self_component_port_input_message_iterator_seek_ns_from_origin( goto end; } + if (stream_state->seen_clock_snapshot) { + bt_message_stream_beginning_set_default_clock_snapshot(msg, raw_value); + } + g_queue_push_head(iterator->auto_seek.msgs, msg); msg = NULL; break; diff --git a/src/lib/graph/message/Makefile.am b/src/lib/graph/message/Makefile.am index b0053ceb..c23e5a56 100644 --- a/src/lib/graph/message/Makefile.am +++ b/src/lib/graph/message/Makefile.am @@ -12,7 +12,5 @@ libgraph_message_la_SOURCES = \ message-iterator-inactivity.h \ packet.c \ packet.h \ - stream-activity.c \ - stream-activity.h \ stream.c \ stream.h diff --git a/src/lib/graph/message/message.h b/src/lib/graph/message/message.h index 1df9c520..a1e52997 100644 --- a/src/lib/graph/message/message.h +++ b/src/lib/graph/message/message.h @@ -133,10 +133,6 @@ const char *bt_message_type_string(enum bt_message_type type) return "BT_MESSAGE_TYPE_PACKET_BEGINNING"; case BT_MESSAGE_TYPE_PACKET_END: return "BT_MESSAGE_TYPE_PACKET_END"; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - return "BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING"; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - return "BT_MESSAGE_TYPE_STREAM_ACTIVITY_END"; case BT_MESSAGE_TYPE_DISCARDED_EVENTS: return "BT_MESSAGE_TYPE_DISCARDED_EVENTS"; default: diff --git a/src/lib/graph/message/stream-activity.c b/src/lib/graph/message/stream-activity.c deleted file mode 100644 index d9ef3e6b..00000000 --- a/src/lib/graph/message/stream-activity.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright 2019 Philippe Proulx - * - * 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#define BT_LOG_TAG "LIB/MSG-STREAM-ACTIVITY" -#include "lib/logging.h" - -#include "lib/assert-pre.h" -#include "lib/object.h" -#include "compat/compiler.h" -#include -#include "lib/trace-ir/clock-snapshot.h" -#include "lib/trace-ir/stream-class.h" -#include "lib/trace-ir/stream.h" -#include "lib/graph/message/message.h" -#include -#include -#include -#include - -#include "stream-activity.h" - -static -void destroy_stream_activity_message(struct bt_object *obj) -{ - struct bt_message_stream_activity *message = (void *) obj; - - BT_LIB_LOGD("Destroying stream activity message: %!+n", message); - BT_LIB_LOGD("Putting stream: %!+s", message->stream); - BT_OBJECT_PUT_REF_AND_RESET(message->stream); - - if (message->default_cs) { - bt_clock_snapshot_recycle(message->default_cs); - message->default_cs = NULL; - } - - g_free(message); -} - -static inline -struct bt_message *create_stream_activity_message( - struct bt_self_message_iterator *self_msg_iter, - struct bt_stream *stream, enum bt_message_type type) -{ - struct bt_message_stream_activity *message; - struct bt_stream_class *stream_class; - - BT_ASSERT_PRE_NON_NULL(self_msg_iter, "Message iterator"); - BT_ASSERT_PRE_NON_NULL(stream, "Stream"); - stream_class = bt_stream_borrow_class(stream); - BT_ASSERT(stream_class); - BT_LIB_LOGD("Creating stream activity message object: " - "type=%s, %![stream-]+s, %![sc-]+S", - bt_message_type_string(type), stream, stream_class); - message = g_new0(struct bt_message_stream_activity, 1); - if (!message) { - BT_LIB_LOGE_APPEND_CAUSE( - "Failed to allocate one stream activity message."); - goto error; - } - - bt_message_init(&message->parent, type, - destroy_stream_activity_message, NULL); - message->stream = stream; - bt_object_get_no_null_check(message->stream); - - if (stream_class->default_clock_class) { - message->default_cs = bt_clock_snapshot_create( - stream_class->default_clock_class); - if (!message->default_cs) { - goto error; - } - } - - message->default_cs_state = - BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN; - BT_LIB_LOGD("Created stream activity message object: " - "%![msg-]+n, %![stream-]+s, %![sc-]+S", message, - stream, stream_class); - - return (void *) &message->parent; - -error: - return NULL; -} - -struct bt_message *bt_message_stream_activity_beginning_create( - struct bt_self_message_iterator *self_msg_iter, - const struct bt_stream *stream) -{ - return create_stream_activity_message(self_msg_iter, (void *) stream, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING); -} - -struct bt_message *bt_message_stream_activity_end_create( - struct bt_self_message_iterator *self_msg_iter, - const struct bt_stream *stream) -{ - return create_stream_activity_message(self_msg_iter, (void *) stream, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_END); -} - -static inline -struct bt_stream *borrow_stream_activity_message_stream( - struct bt_message *message) -{ - struct bt_message_stream_activity *stream_act_msg = (void *) message; - - BT_ASSERT(message); - return stream_act_msg->stream; -} - -struct bt_stream *bt_message_stream_activity_beginning_borrow_stream( - struct bt_message *message) -{ - BT_ASSERT_PRE_NON_NULL(message, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(message, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING); - return borrow_stream_activity_message_stream(message); -} - -struct bt_stream *bt_message_stream_activity_end_borrow_stream( - struct bt_message *message) -{ - BT_ASSERT_PRE_NON_NULL(message, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(message, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_END); - return borrow_stream_activity_message_stream(message); -} - -const struct bt_stream *bt_message_stream_activity_beginning_borrow_stream_const( - const struct bt_message *message) -{ - return bt_message_stream_activity_beginning_borrow_stream( - (void *) message); -} - -const struct bt_stream *bt_message_stream_activity_end_borrow_stream_const( - const struct bt_message *message) -{ - return bt_message_stream_activity_end_borrow_stream((void *) message); -} - -static inline -void set_stream_activity_message_default_clock_snapshot( - struct bt_message *msg, uint64_t value_cycles) -{ - struct bt_message_stream_activity *stream_act_msg = (void *) msg; - struct bt_stream_class *sc; - - BT_ASSERT(msg); - BT_ASSERT_PRE_HOT(msg, "Message", ": %!+n", msg); - sc = stream_act_msg->stream->class; - BT_ASSERT(sc); - BT_ASSERT_PRE(sc->default_clock_class, - "Message's stream's class has no default clock class: " - "%![msg-]+n, %![sc-]+S", msg, sc); - bt_clock_snapshot_set_raw_value(stream_act_msg->default_cs, - value_cycles); - stream_act_msg->default_cs_state = - BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN; - BT_LIB_LOGD("Set stream activity message's default clock snapshot: " - "%![msg-]+n, value=%" PRIu64, msg, value_cycles); -} - -void bt_message_stream_activity_beginning_set_default_clock_snapshot( - struct bt_message *msg, uint64_t raw_value) -{ - BT_ASSERT_PRE_NON_NULL(msg, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(msg, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING); - set_stream_activity_message_default_clock_snapshot(msg, raw_value); -} - -void bt_message_stream_activity_end_set_default_clock_snapshot( - struct bt_message *msg, uint64_t raw_value) -{ - BT_ASSERT_PRE_NON_NULL(msg, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(msg, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_END); - set_stream_activity_message_default_clock_snapshot(msg, raw_value); -} - -static inline -enum bt_message_stream_activity_clock_snapshot_state -borrow_stream_activity_message_default_clock_snapshot_const( - const bt_message *msg, const bt_clock_snapshot **snapshot) -{ - const struct bt_message_stream_activity *stream_act_msg = - (const void *) msg; - - BT_ASSERT_PRE_NON_NULL(snapshot, "Clock snapshot (output)"); - *snapshot = stream_act_msg->default_cs; - return stream_act_msg->default_cs_state; -} - -enum bt_message_stream_activity_clock_snapshot_state -bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const( - const bt_message *msg, const bt_clock_snapshot **snapshot) -{ - BT_ASSERT_PRE_NON_NULL(msg, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(msg, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING); - return borrow_stream_activity_message_default_clock_snapshot_const(msg, - snapshot); -} - -enum bt_message_stream_activity_clock_snapshot_state -bt_message_stream_activity_end_borrow_default_clock_snapshot_const( - const bt_message *msg, const bt_clock_snapshot **snapshot) -{ - BT_ASSERT_PRE_NON_NULL(msg, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(msg, BT_MESSAGE_TYPE_STREAM_ACTIVITY_END); - return borrow_stream_activity_message_default_clock_snapshot_const(msg, - snapshot); -} - -static inline -void set_stream_activity_message_default_clock_snapshot_state( - struct bt_message *msg, - enum bt_message_stream_activity_clock_snapshot_state state) -{ - struct bt_message_stream_activity *stream_act_msg = (void *) msg; - - BT_ASSERT(msg); - BT_ASSERT_PRE_HOT(msg, "Message", ": %!+n", msg); - BT_ASSERT_PRE(state != BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN, - "Invalid clock snapshot state: %![msg-]+n, state=%s", - msg, - bt_message_stream_activity_clock_snapshot_state_string(state)); - stream_act_msg->default_cs_state = state; - BT_LIB_LOGD("Set stream activity message's default clock snapshot state: " - "%![msg-]+n, state=%s", msg, - bt_message_stream_activity_clock_snapshot_state_string(state)); -} - -void bt_message_stream_activity_beginning_set_default_clock_snapshot_state( - struct bt_message *msg, - enum bt_message_stream_activity_clock_snapshot_state state) -{ - BT_ASSERT_PRE_NON_NULL(msg, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(msg, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING); - set_stream_activity_message_default_clock_snapshot_state(msg, state); -} - -void bt_message_stream_activity_end_set_default_clock_snapshot_state( - struct bt_message *msg, - enum bt_message_stream_activity_clock_snapshot_state state) -{ - BT_ASSERT_PRE_NON_NULL(msg, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(msg, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_END); - set_stream_activity_message_default_clock_snapshot_state(msg, state); -} - -static inline -const struct bt_clock_class * -borrow_stream_activity_message_stream_class_default_clock_class( - const struct bt_message *msg) -{ - struct bt_message_stream_activity *stream_act_msg = (void *) msg; - - BT_ASSERT(msg); - return stream_act_msg->stream->class->default_clock_class; -} - -const struct bt_clock_class * -bt_message_stream_activity_beginning_borrow_stream_class_default_clock_class_const( - const struct bt_message *msg) -{ - BT_ASSERT_PRE_NON_NULL(msg, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(msg, - BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING); - return borrow_stream_activity_message_stream_class_default_clock_class( - msg); -} - -const struct bt_clock_class * -bt_message_stream_activity_end_borrow_stream_class_default_clock_class_const( - const struct bt_message *msg) -{ - BT_ASSERT_PRE_NON_NULL(msg, "Message"); - BT_ASSERT_PRE_MSG_IS_TYPE(msg, BT_MESSAGE_TYPE_STREAM_ACTIVITY_END); - return borrow_stream_activity_message_stream_class_default_clock_class( - msg); -} diff --git a/src/lib/graph/message/stream-activity.h b/src/lib/graph/message/stream-activity.h deleted file mode 100644 index 9199d43b..00000000 --- a/src/lib/graph/message/stream-activity.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_INTERNAL_H -#define BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_INTERNAL_H - -/* - * Copyright 2019 Philippe Proulx - * - * 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include "lib/trace-ir/clock-snapshot.h" -#include "lib/trace-ir/stream.h" -#include -#include - -struct bt_message_stream_activity { - struct bt_message parent; - struct bt_stream *stream; - struct bt_clock_snapshot *default_cs; - enum bt_message_stream_activity_clock_snapshot_state default_cs_state; -}; - -static inline -const char *bt_message_stream_activity_clock_snapshot_state_string( - enum bt_message_stream_activity_clock_snapshot_state state) -{ - switch (state) { - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN: - return "BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN"; - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN: - return "BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN"; - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE: - return "BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE"; - default: - return "(unknown)"; - } -} - -#endif /* BABELTRACE_GRAPH_MESSAGE_STREAM_ACTIVITY_INTERNAL_H */ diff --git a/src/lib/graph/message/stream.c b/src/lib/graph/message/stream.c index ff7d1c83..ecab2c29 100644 --- a/src/lib/graph/message/stream.c +++ b/src/lib/graph/message/stream.c @@ -76,14 +76,29 @@ struct bt_message *create_stream_message( destroy_stream_message, NULL); message->stream = stream; bt_object_get_no_null_check(message->stream); + + if (stream_class->default_clock_class) { + message->default_cs = bt_clock_snapshot_create( + stream_class->default_clock_class); + if (!message->default_cs) { + goto error; + } + } + BT_LIB_LOGD("Created stream message object: " "%![msg-]+n, %![stream-]+s, %![sc-]+S", message, stream, stream_class); - return (void *) &message->parent; + goto end; error: - return NULL; + if (message) { + g_free(message); + message = NULL; + } + +end: + return &message->parent; } struct bt_message *bt_message_stream_beginning_create( @@ -141,3 +156,114 @@ const struct bt_stream *bt_message_stream_end_borrow_stream_const( return bt_message_stream_end_borrow_stream( (void *) message); } + +static +void bt_message_stream_set_default_clock_snapshot( + struct bt_message *msg, uint64_t raw_value) +{ + struct bt_message_stream *stream_msg = (void *) msg; + struct bt_stream_class *sc; + + BT_ASSERT(msg); + BT_ASSERT_PRE_HOT(msg, "Message", ": %!+n", msg); + sc = stream_msg->stream->class; + BT_ASSERT(sc); + BT_ASSERT_PRE(sc->default_clock_class, + "Message's stream's class has no default clock class: " + "%![msg-]+n, %![sc-]+S", msg, sc); + BT_ASSERT(stream_msg->default_cs); + bt_clock_snapshot_set_raw_value(stream_msg->default_cs, raw_value); + stream_msg->default_cs_state = BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN; + BT_LIB_LOGD("Set stream message's default clock snapshot: " + "%![msg-]+n, value=%" PRIu64, msg, raw_value); +} + +void bt_message_stream_beginning_set_default_clock_snapshot( + struct bt_message *message, uint64_t raw_value) +{ + BT_ASSERT_PRE_NON_NULL(message, "Message"); + BT_ASSERT_PRE_MSG_IS_TYPE(message, BT_MESSAGE_TYPE_STREAM_BEGINNING); + + bt_message_stream_set_default_clock_snapshot(message, raw_value); +} + +void bt_message_stream_end_set_default_clock_snapshot( + struct bt_message *message, uint64_t raw_value) +{ + BT_ASSERT_PRE_NON_NULL(message, "Message"); + BT_ASSERT_PRE_MSG_IS_TYPE(message, BT_MESSAGE_TYPE_STREAM_END); + + return bt_message_stream_set_default_clock_snapshot(message, raw_value); +} + +static enum bt_message_stream_clock_snapshot_state +bt_message_stream_borrow_default_clock_snapshot_const( + const bt_message *msg, const bt_clock_snapshot **snapshot) +{ + struct bt_message_stream *stream_msg = (void *) msg; + struct bt_stream_class *sc; + + BT_ASSERT(msg); + sc = stream_msg->stream->class; + BT_ASSERT(sc); + BT_ASSERT_PRE(sc->default_clock_class, + "Message's stream's class has no default clock class: " + "%![msg-]+n, %![sc-]+S", msg, sc); + BT_ASSERT(stream_msg->default_cs); + + *snapshot = stream_msg->default_cs; + + return stream_msg->default_cs_state; +} + +enum bt_message_stream_clock_snapshot_state +bt_message_stream_beginning_borrow_default_clock_snapshot_const( + const bt_message *message, const bt_clock_snapshot **snapshot) +{ + BT_ASSERT_PRE_NON_NULL(message, "Message"); + BT_ASSERT_PRE_MSG_IS_TYPE(message, BT_MESSAGE_TYPE_STREAM_BEGINNING); + + return bt_message_stream_borrow_default_clock_snapshot_const( + message, snapshot); +} + +enum bt_message_stream_clock_snapshot_state +bt_message_stream_end_borrow_default_clock_snapshot_const( + const bt_message *message, const bt_clock_snapshot **snapshot) +{ + BT_ASSERT_PRE_NON_NULL(message, "Message"); + BT_ASSERT_PRE_MSG_IS_TYPE(message, BT_MESSAGE_TYPE_STREAM_END); + + return bt_message_stream_borrow_default_clock_snapshot_const( + message, snapshot); +} + +static inline +const struct bt_clock_class * +borrow_stream_message_stream_class_default_clock_class( + const struct bt_message *msg) +{ + struct bt_message_stream *stream_msg = (void *) msg; + + BT_ASSERT(msg); + return stream_msg->stream->class->default_clock_class; +} + +const struct bt_clock_class * +bt_message_stream_beginning_borrow_stream_class_default_clock_class_const( + const struct bt_message *msg) +{ + BT_ASSERT_PRE_NON_NULL(msg, "Message"); + BT_ASSERT_PRE_MSG_IS_TYPE(msg, + BT_MESSAGE_TYPE_STREAM_BEGINNING); + return borrow_stream_message_stream_class_default_clock_class(msg); +} + +const struct bt_clock_class * +bt_message_stream_end_borrow_stream_class_default_clock_class_const( + const struct bt_message *msg) +{ + BT_ASSERT_PRE_NON_NULL(msg, "Message"); + BT_ASSERT_PRE_MSG_IS_TYPE(msg, BT_MESSAGE_TYPE_STREAM_END); + return borrow_stream_message_stream_class_default_clock_class(msg); +} diff --git a/src/lib/graph/message/stream.h b/src/lib/graph/message/stream.h index 7cca4bc2..4de74c5e 100644 --- a/src/lib/graph/message/stream.h +++ b/src/lib/graph/message/stream.h @@ -24,6 +24,8 @@ * SOFTWARE. */ +#include + #include "compat/compiler.h" #include "lib/trace-ir/stream.h" #include "lib/trace-ir/clock-snapshot.h" @@ -34,6 +36,23 @@ struct bt_message_stream { struct bt_message parent; struct bt_stream *stream; + struct bt_clock_snapshot *default_cs; + enum bt_message_stream_clock_snapshot_state default_cs_state; }; +static inline +const char *bt_message_stream_clock_snapshot_state_string( + enum bt_message_stream_clock_snapshot_state state) +{ + switch (state) { + case BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN: + return "BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN"; + case BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_UNKNOWN: + return "BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN"; + default: + return "(unknown)"; + } +} + + #endif /* BABELTRACE_GRAPH_MESSAGE_STREAM_INTERNAL_H */ diff --git a/src/lib/lib-logging.c b/src/lib/lib-logging.c index 4c69d62f..dcfee70f 100644 --- a/src/lib/lib-logging.c +++ b/src/lib/lib-logging.c @@ -56,7 +56,6 @@ #include "graph/message/message.h" #include "graph/message/message-iterator-inactivity.h" #include "graph/message/packet.h" -#include "graph/message/stream-activity.h" #include "graph/message/stream.h" #include "graph/port.h" #include "plugin/plugin.h" @@ -925,28 +924,14 @@ static inline void format_message(char **buf_ch, bool extended, msg_stream->stream); } - break; - } - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - { - const struct bt_message_stream_activity *msg_stream_activity = - (const void *) msg; - - if (msg_stream_activity->stream) { - SET_TMP_PREFIX("stream-"); - format_stream(buf_ch, true, tmp_prefix, - msg_stream_activity->stream); - } - BUF_APPEND(", %sdefault-cs-state=%s", - PRFIELD(bt_message_stream_activity_clock_snapshot_state_string( - msg_stream_activity->default_cs_state))); + PRFIELD(bt_message_stream_clock_snapshot_state_string( + msg_stream->default_cs_state))); - if (msg_stream_activity->default_cs) { + if (msg_stream->default_cs_state == BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) { SET_TMP_PREFIX("default-cs-"); format_clock_snapshot(buf_ch, true, tmp_prefix, - msg_stream_activity->default_cs); + msg_stream->default_cs); } break; diff --git a/src/plugins/ctf/common/msg-iter/msg-iter.c b/src/plugins/ctf/common/msg-iter/msg-iter.c index fe1d160d..d71d00e9 100644 --- a/src/plugins/ctf/common/msg-iter/msg-iter.c +++ b/src/plugins/ctf/common/msg-iter/msg-iter.c @@ -88,7 +88,6 @@ enum state { STATE_AFTER_STREAM_PACKET_CONTEXT, STATE_CHECK_EMIT_MSG_STREAM_BEGINNING, STATE_EMIT_MSG_STREAM_BEGINNING, - STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING, STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS, STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS, STATE_EMIT_MSG_DISCARDED_EVENTS, @@ -107,8 +106,7 @@ enum state { STATE_SKIP_PACKET_PADDING, STATE_EMIT_MSG_PACKET_END_MULTI, STATE_EMIT_MSG_PACKET_END_SINGLE, - STATE_CHECK_EMIT_MSG_STREAM_ACTIVITY_END, - STATE_EMIT_MSG_STREAM_ACTIVITY_END, + STATE_CHECK_EMIT_MSG_STREAM_END, STATE_EMIT_MSG_STREAM_END, STATE_DONE, }; @@ -128,13 +126,10 @@ struct bt_msg_iter { /* Current message iterator to create messages (weak) */ bt_self_message_iterator *msg_iter; - /* - * True to emit stream beginning and stream activity beginning - * messages. - */ + /* True to emit a stream beginning message. */ bool emit_stream_begin_msg; - /* True to emit stream end and stream activity end messages */ + /* True to emit a stream end message. */ bool emit_stream_end_msg; /* True to set the stream */ @@ -278,8 +273,6 @@ const char *state_string(enum state state) return "STATE_AFTER_STREAM_PACKET_CONTEXT"; case STATE_EMIT_MSG_STREAM_BEGINNING: return "STATE_EMIT_MSG_STREAM_BEGINNING"; - case STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING: - return "STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING"; case STATE_EMIT_MSG_PACKET_BEGINNING: return "STATE_EMIT_MSG_PACKET_BEGINNING"; case STATE_EMIT_MSG_DISCARDED_EVENTS: @@ -312,8 +305,6 @@ const char *state_string(enum state state) return "STATE_EMIT_MSG_PACKET_END_MULTI"; case STATE_EMIT_MSG_PACKET_END_SINGLE: return "STATE_EMIT_MSG_PACKET_END_SINGLE"; - case STATE_EMIT_MSG_STREAM_ACTIVITY_END: - return "STATE_EMIT_MSG_STREAM_ACTIVITY_END"; case STATE_EMIT_MSG_STREAM_END: return "STATE_EMIT_MSG_STREAM_END"; case STATE_DONE: @@ -710,7 +701,7 @@ enum bt_msg_iter_status read_packet_header_begin_state( break; case BT_MSG_ITER_STATUS_EOF: ret = BT_MSG_ITER_STATUS_OK; - notit->state = STATE_CHECK_EMIT_MSG_STREAM_ACTIVITY_END; + notit->state = STATE_CHECK_EMIT_MSG_STREAM_END; goto end; default: goto end; @@ -1570,11 +1561,11 @@ end: } static -enum bt_msg_iter_status check_emit_msg_stream_activity_end( +enum bt_msg_iter_status check_emit_msg_stream_end( struct bt_msg_iter *notit) { if (notit->emit_stream_end_msg) { - notit->state = STATE_EMIT_MSG_STREAM_ACTIVITY_END; + notit->state = STATE_EMIT_MSG_STREAM_END; } else { notit->state = STATE_DONE; } @@ -1618,9 +1609,6 @@ enum bt_msg_iter_status handle_state(struct bt_msg_iter *notit) status = check_emit_msg_stream_beginning_state(notit); break; case STATE_EMIT_MSG_STREAM_BEGINNING: - notit->state = STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING; - break; - case STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING: notit->state = STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS; break; case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS: @@ -1675,13 +1663,10 @@ enum bt_msg_iter_status handle_state(struct bt_msg_iter *notit) notit->state = STATE_SKIP_PACKET_PADDING; break; case STATE_EMIT_MSG_PACKET_END_SINGLE: - notit->state = STATE_CHECK_EMIT_MSG_STREAM_ACTIVITY_END; + notit->state = STATE_CHECK_EMIT_MSG_STREAM_END; break; - case STATE_CHECK_EMIT_MSG_STREAM_ACTIVITY_END: - status = check_emit_msg_stream_activity_end(notit); - break; - case STATE_EMIT_MSG_STREAM_ACTIVITY_END: - notit->state = STATE_EMIT_MSG_STREAM_END; + case STATE_CHECK_EMIT_MSG_STREAM_END: + status = check_emit_msg_stream_end(notit); break; case STATE_EMIT_MSG_STREAM_END: notit->state = STATE_DONE; @@ -2437,52 +2422,6 @@ void create_msg_stream_beginning(struct bt_msg_iter *notit, *message = ret; } -static -void create_msg_stream_activity_beginning(struct bt_msg_iter *notit, - bt_message **message) -{ - bt_message *ret = NULL; - - BT_ASSERT(notit->stream); - BT_ASSERT(notit->msg_iter); - ret = bt_message_stream_activity_beginning_create(notit->msg_iter, - notit->stream); - if (!ret) { - BT_COMP_LOGE("Cannot create stream activity beginning message: " - "notit-addr=%p, stream-addr=%p", - notit, notit->stream); - return; - } - - *message = ret; -} - -static -void create_msg_stream_activity_end(struct bt_msg_iter *notit, - bt_message **message) -{ - bt_message *ret = NULL; - - if (!notit->stream) { - BT_COMP_LOGE("Cannot create stream for stream message: " - "notit-addr=%p", notit); - return; - } - - BT_ASSERT(notit->stream); - BT_ASSERT(notit->msg_iter); - ret = bt_message_stream_activity_end_create(notit->msg_iter, - notit->stream); - if (!ret) { - BT_COMP_LOGE("Cannot create stream activity end message: " - "notit-addr=%p, stream-addr=%p", - notit, notit->stream); - return; - } - - *message = ret; -} - static void create_msg_stream_end(struct bt_msg_iter *notit, bt_message **message) { @@ -2862,24 +2801,6 @@ enum bt_msg_iter_status bt_msg_iter_get_next_message( status = BT_MSG_ITER_STATUS_ERROR; } - goto end; - case STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING: - /* create_msg_stream_activity_beginning() logs errors */ - create_msg_stream_activity_beginning(notit, message); - - if (!*message) { - status = BT_MSG_ITER_STATUS_ERROR; - } - - goto end; - case STATE_EMIT_MSG_STREAM_ACTIVITY_END: - /* create_msg_stream_activity_end() logs errors */ - create_msg_stream_activity_end(notit, message); - - if (!*message) { - status = BT_MSG_ITER_STATUS_ERROR; - } - goto end; case STATE_EMIT_MSG_STREAM_BEGINNING: /* create_msg_stream_beginning() logs errors */ @@ -2954,7 +2875,6 @@ enum bt_msg_iter_status read_packet_header_context_fields( case STATE_AFTER_STREAM_PACKET_CONTEXT: case STATE_CHECK_EMIT_MSG_STREAM_BEGINNING: case STATE_EMIT_MSG_STREAM_BEGINNING: - case STATE_EMIT_MSG_STREAM_ACTIVITY_BEGINNING: case STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS: case STATE_EMIT_MSG_DISCARDED_EVENTS: case STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS: diff --git a/src/plugins/ctf/fs-sink/fs-sink.c b/src/plugins/ctf/fs-sink/fs-sink.c index 7fabc65c..3a08c71e 100644 --- a/src/plugins/ctf/fs-sink/fs-sink.c +++ b/src/plugins/ctf/fs-sink/fs-sink.c @@ -972,11 +972,6 @@ bt_component_class_sink_consume_method_status ctf_fs_sink_consume( status = handle_stream_end_msg( fs_sink, msg); break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - /* Not supported by CTF 1.8 */ - BT_COMP_LOGD_STR("Ignoring stream activity message."); - break; case BT_MESSAGE_TYPE_DISCARDED_EVENTS: status = handle_discarded_events_msg( fs_sink, msg); diff --git a/src/plugins/ctf/lttng-live/lttng-live.c b/src/plugins/ctf/lttng-live/lttng-live.c index 09442307..9ec7f5d0 100644 --- a/src/plugins/ctf/lttng-live/lttng-live.c +++ b/src/plugins/ctf/lttng-live/lttng-live.c @@ -633,7 +633,6 @@ int live_get_msg_ts_ns(struct lttng_live_stream_iterator *stream_iter, const bt_clock_class *clock_class = NULL; const bt_clock_snapshot *clock_snapshot = NULL; int ret = 0; - bt_message_stream_activity_clock_snapshot_state sa_cs_state; bt_logging_level log_level = lttng_live_msg_iter->log_level; bt_self_component *self_comp = lttng_live_msg_iter->self_comp; @@ -690,32 +689,6 @@ int live_get_msg_ts_ns(struct lttng_live_stream_iterator *stream_iter, clock_snapshot = bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const( msg); break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - clock_class = - bt_message_stream_activity_beginning_borrow_stream_class_default_clock_class_const( - msg); - BT_ASSERT(clock_class); - - sa_cs_state = bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const( - msg, &clock_snapshot); - if (sa_cs_state != BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN) { - goto no_clock_snapshot; - } - - break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - clock_class = - bt_message_stream_activity_end_borrow_stream_class_default_clock_class_const( - msg); - BT_ASSERT(clock_class); - - sa_cs_state = bt_message_stream_activity_end_borrow_default_clock_snapshot_const( - msg, &clock_snapshot); - if (sa_cs_state != BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN) { - goto no_clock_snapshot; - } - - break; case BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: clock_snapshot = bt_message_message_iterator_inactivity_borrow_default_clock_snapshot_const( @@ -740,12 +713,6 @@ int live_get_msg_ts_ns(struct lttng_live_stream_iterator *stream_iter, goto end; -no_clock_snapshot: - BT_COMP_LOGD_STR("Message's default clock snapshot is missing: " - "using the last message timestamp."); - *ts_ns = last_msg_ts_ns; - goto end; - error: ret = -1; diff --git a/src/plugins/lttng-utils/debug-info/debug-info.c b/src/plugins/lttng-utils/debug-info/debug-info.c index ef76225b..c994b264 100644 --- a/src/plugins/lttng-utils/debug-info/debug-info.c +++ b/src/plugins/lttng-utils/debug-info/debug-info.c @@ -1502,110 +1502,6 @@ bt_message *handle_msg_iterator_inactivity(struct debug_info_msg_iter *debug_it, return (bt_message*) in_message; } -static -bt_message *handle_stream_act_begin_message(struct debug_info_msg_iter *debug_it, - const bt_message *in_message) -{ - const bt_clock_snapshot *cs; - const bt_clock_class *default_cc; - bt_message *out_message = NULL; - bt_stream *out_stream; - uint64_t cs_value; - bt_message_stream_activity_clock_snapshot_state cs_state; - bt_logging_level log_level = debug_it->log_level; - bt_self_component *self_comp = debug_it->self_comp; - - const bt_stream *in_stream = - bt_message_stream_activity_beginning_borrow_stream_const( - in_message); - BT_ASSERT(in_stream); - - out_stream = trace_ir_mapping_borrow_mapped_stream(debug_it->ir_maps, - in_stream); - BT_ASSERT(out_stream); - - out_message = bt_message_stream_activity_beginning_create( - debug_it->input_iterator, out_stream); - if (!out_message) { - BT_COMP_LOGE("Error creating output stream activity beginning " - "message: out-s-addr=%p", out_stream); - goto error; - } - - default_cc = bt_stream_class_borrow_default_clock_class_const( - bt_stream_borrow_class_const(in_stream)); - if (default_cc) { - /* Borrow clock snapshot. */ - cs_state = - bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const( - in_message, &cs); - - if (cs_state == BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN) { - cs_value = bt_clock_snapshot_get_value(cs); - bt_message_stream_activity_beginning_set_default_clock_snapshot( - out_message, cs_value); - } else { - bt_message_stream_activity_beginning_set_default_clock_snapshot_state( - out_message, cs_state); - } - } - -error: - return out_message; -} - -static -bt_message *handle_stream_act_end_message(struct debug_info_msg_iter *debug_it, - const bt_message *in_message) -{ - const bt_clock_snapshot *cs; - const bt_clock_class *default_cc; - const bt_stream *in_stream; - bt_message *out_message; - bt_stream *out_stream; - uint64_t cs_value; - bt_message_stream_activity_clock_snapshot_state cs_state; - bt_logging_level log_level = debug_it->log_level; - bt_self_component *self_comp = debug_it->self_comp; - - in_stream = bt_message_stream_activity_end_borrow_stream_const( - in_message); - BT_ASSERT(in_stream); - - out_stream = trace_ir_mapping_borrow_mapped_stream(debug_it->ir_maps, - in_stream); - BT_ASSERT(out_stream); - - out_message = bt_message_stream_activity_end_create( - debug_it->input_iterator, out_stream); - if (!out_message) { - BT_COMP_LOGE("Error creating output stream activity end message: " - "out-s-addr=%p", out_stream); - goto error; - } - - default_cc = bt_stream_class_borrow_default_clock_class_const( - bt_stream_borrow_class_const(in_stream)); - - if (default_cc) { - cs_state = - bt_message_stream_activity_end_borrow_default_clock_snapshot_const( - in_message, &cs); - - if (cs_state == BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN ) { - cs_value = bt_clock_snapshot_get_value(cs); - bt_message_stream_activity_end_set_default_clock_snapshot( - out_message, cs_value); - } else { - bt_message_stream_activity_end_set_default_clock_snapshot_state( - out_message, cs_state); - } - } - -error: - return out_message; -} - static bt_message *handle_discarded_events_message(struct debug_info_msg_iter *debug_it, const bt_message *in_message) @@ -1760,14 +1656,6 @@ const bt_message *handle_message(struct debug_info_msg_iter *debug_it, out_message = handle_msg_iterator_inactivity(debug_it, in_message); break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - out_message = handle_stream_act_begin_message(debug_it, - in_message); - break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - out_message = handle_stream_act_end_message(debug_it, - in_message); - break; case BT_MESSAGE_TYPE_DISCARDED_EVENTS: out_message = handle_discarded_events_message(debug_it, in_message); diff --git a/src/plugins/text/details/write.c b/src/plugins/text/details/write.c index b102485b..e79e7e03 100644 --- a/src/plugins/text/details/write.c +++ b/src/plugins/text/details/write.c @@ -1769,6 +1769,7 @@ int write_stream_beginning_message(struct details_write_ctx *ctx, bt_message_stream_beginning_borrow_stream_const(msg); const bt_trace *trace = bt_stream_borrow_trace_const(stream); const bt_stream_class *sc = bt_stream_borrow_class_const(stream); + const bt_clock_class *cc = bt_stream_class_borrow_default_clock_class_const(sc); const bt_trace_class *tc = bt_stream_class_borrow_trace_class_const(sc); const char *name; @@ -1777,6 +1778,19 @@ int write_stream_beginning_message(struct details_write_ctx *ctx, goto end; } + /* Write time */ + if (cc) { + const bt_clock_snapshot *cs; + bt_message_stream_clock_snapshot_state cs_state = + bt_message_stream_beginning_borrow_default_clock_snapshot_const(msg, &cs); + + if (cs_state == BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) { + write_time(ctx, cs); + } else { + write_time_str(ctx, "Unknown"); + } + } + /* Write follow tag for message */ ret = write_message_follow_tag(ctx, stream); if (ret) { @@ -1822,87 +1836,22 @@ int write_stream_end_message(struct details_write_ctx *ctx, int ret = 0; const bt_stream *stream = bt_message_stream_end_borrow_stream_const(msg); - - /* Write follow tag for message */ - ret = write_message_follow_tag(ctx, stream); - if (ret) { - goto end; - } - - /* Write stream properties */ - write_obj_type_name(ctx, "Stream end\n"); - -end: - return ret; -} - -static -int write_stream_activity_beginning_message(struct details_write_ctx *ctx, - const bt_message *msg) -{ - int ret = 0; - const bt_stream *stream = - bt_message_stream_activity_beginning_borrow_stream_const(msg); - bt_message_stream_activity_clock_snapshot_state cs_state; - const bt_clock_snapshot *cs = NULL; + const bt_stream_class *sc = + bt_stream_borrow_class_const(stream); + const bt_clock_class *cc = + bt_stream_class_borrow_default_clock_class_const(sc); /* Write time */ - cs_state = bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const( - msg, &cs); - switch (cs_state) { - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN: - BT_ASSERT(cs); - write_time(ctx, cs); - break; - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN: - write_time_str(ctx, "Unknown"); - break; - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE: - write_time_str(ctx, "-Infinity"); - break; - default: - abort(); - } + if (cc) { + const bt_clock_snapshot *cs; + bt_message_stream_clock_snapshot_state cs_state = + bt_message_stream_end_borrow_default_clock_snapshot_const(msg, &cs); - /* Write follow tag for message */ - ret = write_message_follow_tag(ctx, stream); - if (ret) { - goto end; - } - - write_obj_type_name(ctx, "Stream activity beginning"); - write_nl(ctx); - -end: - return ret; -} - -static -int write_stream_activity_end_message(struct details_write_ctx *ctx, - const bt_message *msg) -{ - int ret = 0; - const bt_stream *stream = - bt_message_stream_activity_end_borrow_stream_const(msg); - bt_message_stream_activity_clock_snapshot_state cs_state; - const bt_clock_snapshot *cs = NULL; - - /* Write time */ - cs_state = bt_message_stream_activity_end_borrow_default_clock_snapshot_const( - msg, &cs); - switch (cs_state) { - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN: - BT_ASSERT(cs); - write_time(ctx, cs); - break; - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN: - write_time_str(ctx, "Unknown"); - break; - case BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE: - write_time_str(ctx, "+Infinity"); - break; - default: - abort(); + if (cs_state == BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) { + write_time(ctx, cs); + } else { + write_time_str(ctx, "Unknown"); + } } /* Write follow tag for message */ @@ -1911,8 +1860,8 @@ int write_stream_activity_end_message(struct details_write_ctx *ctx, goto end; } - write_obj_type_name(ctx, "Stream activity end"); - write_nl(ctx); + /* Write stream properties */ + write_obj_type_name(ctx, "Stream end\n"); end: return ret; @@ -2160,12 +2109,6 @@ int details_write_message(struct details_comp *details_comp, case BT_MESSAGE_TYPE_PACKET_END: ret = write_packet_end_message(&ctx, msg); break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - ret = write_stream_activity_beginning_message(&ctx, msg); - break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - ret = write_stream_activity_end_message(&ctx, msg); - break; case BT_MESSAGE_TYPE_DISCARDED_EVENTS: ret = write_discarded_events_message(&ctx, msg); break; diff --git a/src/plugins/text/dmesg/dmesg.c b/src/plugins/text/dmesg/dmesg.c index 12413b38..f08f83d2 100644 --- a/src/plugins/text/dmesg/dmesg.c +++ b/src/plugins/text/dmesg/dmesg.c @@ -55,11 +55,9 @@ struct dmesg_msg_iter { enum { STATE_EMIT_STREAM_BEGINNING, - STATE_EMIT_STREAM_ACTIVITY_BEGINNING, STATE_EMIT_PACKET_BEGINNING, STATE_EMIT_EVENT, STATE_EMIT_PACKET_END, - STATE_EMIT_STREAM_ACTIVITY_END, STATE_EMIT_STREAM_END, STATE_DONE, } state; @@ -750,7 +748,6 @@ bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next_one( if (dmesg_msg_iter->tmp_event_msg || dmesg_msg_iter->state == STATE_EMIT_PACKET_END || - dmesg_msg_iter->state == STATE_EMIT_STREAM_ACTIVITY_END || dmesg_msg_iter->state == STATE_EMIT_STREAM_END) { goto handle_state; } @@ -814,12 +811,6 @@ handle_state: BT_ASSERT(dmesg_msg_iter->tmp_event_msg); *msg = bt_message_stream_beginning_create( dmesg_msg_iter->pc_msg_iter, dmesg_comp->stream); - dmesg_msg_iter->state = STATE_EMIT_STREAM_ACTIVITY_BEGINNING; - break; - case STATE_EMIT_STREAM_ACTIVITY_BEGINNING: - BT_ASSERT(dmesg_msg_iter->tmp_event_msg); - *msg = bt_message_stream_activity_beginning_create( - dmesg_msg_iter->pc_msg_iter, dmesg_comp->stream); dmesg_msg_iter->state = STATE_EMIT_PACKET_BEGINNING; break; case STATE_EMIT_PACKET_BEGINNING: @@ -851,11 +842,6 @@ handle_state: dmesg_msg_iter->pc_msg_iter, dmesg_comp->packet); } - dmesg_msg_iter->state = STATE_EMIT_STREAM_ACTIVITY_END; - break; - case STATE_EMIT_STREAM_ACTIVITY_END: - *msg = bt_message_stream_activity_end_create( - dmesg_msg_iter->pc_msg_iter, dmesg_comp->stream); dmesg_msg_iter->state = STATE_EMIT_STREAM_END; break; case STATE_EMIT_STREAM_END: diff --git a/src/plugins/utils/counter/counter.c b/src/plugins/utils/counter/counter.c index db269e78..97f35365 100644 --- a/src/plugins/utils/counter/counter.c +++ b/src/plugins/utils/counter/counter.c @@ -53,8 +53,6 @@ uint64_t get_total_count(struct counter *counter) return counter->count.event + counter->count.stream_begin + counter->count.stream_end + - counter->count.stream_activity_begin + - counter->count.stream_activity_end + counter->count.packet_begin + counter->count.packet_end + counter->count.disc_events + @@ -71,8 +69,6 @@ void print_count(struct counter *counter) PRINTF_COUNT("Event", event); PRINTF_COUNT("Stream beginning", stream_begin); PRINTF_COUNT("Stream end", stream_end); - PRINTF_COUNT("Stream activity beginning", stream_activity_begin); - PRINTF_COUNT("Stream activity end", stream_activity_end); PRINTF_COUNT("Packet beginning", packet_begin); PRINTF_COUNT("Packet end", packet_end); PRINTF_COUNT("Discarded event", disc_events); @@ -298,12 +294,6 @@ bt_component_class_sink_consume_method_status counter_consume( case BT_MESSAGE_TYPE_STREAM_END: counter->count.stream_end++; break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - counter->count.stream_activity_begin++; - break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - counter->count.stream_activity_end++; - break; case BT_MESSAGE_TYPE_DISCARDED_EVENTS: counter->count.disc_events++; break; diff --git a/src/plugins/utils/counter/counter.h b/src/plugins/utils/counter/counter.h index 3d8b8b6e..f47eb3b1 100644 --- a/src/plugins/utils/counter/counter.h +++ b/src/plugins/utils/counter/counter.h @@ -35,8 +35,6 @@ struct counter { uint64_t event; uint64_t stream_begin; uint64_t stream_end; - uint64_t stream_activity_begin; - uint64_t stream_activity_end; uint64_t packet_begin; uint64_t packet_end; uint64_t disc_events; diff --git a/src/plugins/utils/muxer/muxer.c b/src/plugins/utils/muxer/muxer.c index d47ad6e0..37d00608 100644 --- a/src/plugins/utils/muxer/muxer.c +++ b/src/plugins/utils/muxer/muxer.c @@ -538,7 +538,6 @@ int get_msg_ts_ns(struct muxer_comp *muxer_comp, { const bt_clock_snapshot *clock_snapshot = NULL; int ret = 0; - bt_message_stream_activity_clock_snapshot_state sa_cs_state; const bt_stream_class *stream_class = NULL; bt_message_type msg_type; @@ -621,26 +620,6 @@ int get_msg_ts_ns(struct muxer_comp *muxer_comp, goto no_clock_snapshot; } - break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - BT_ASSERT(bt_message_stream_activity_beginning_borrow_stream_class_default_clock_class_const( - msg)); - sa_cs_state = bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const( - msg, &clock_snapshot); - if (sa_cs_state != BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN) { - goto no_clock_snapshot; - } - - break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - BT_ASSERT(bt_message_stream_activity_end_borrow_stream_class_default_clock_class_const( - msg)); - sa_cs_state = bt_message_stream_activity_end_borrow_default_clock_snapshot_const( - msg, &clock_snapshot); - if (sa_cs_state != BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN) { - goto no_clock_snapshot; - } - break; case BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: clock_snapshot = bt_message_message_iterator_inactivity_borrow_default_clock_snapshot_const( diff --git a/src/plugins/utils/trimmer/trimmer.c b/src/plugins/utils/trimmer/trimmer.c index 85c8917d..763c8986 100644 --- a/src/plugins/utils/trimmer/trimmer.c +++ b/src/plugins/utils/trimmer/trimmer.c @@ -34,6 +34,7 @@ #include #include #include +#include "compat/glib.h" #include "trimmer.h" @@ -130,21 +131,12 @@ struct trimmer_iterator { }; struct trimmer_iterator_stream_state { - /* - * True if the last pushed message for this stream was a stream - * activity end message. - */ - bool last_msg_is_stream_activity_end; - - /* - * Time to use for a generated stream end activity message when - * ending the stream. - */ - int64_t stream_act_end_ns_from_origin; - /* Weak */ const bt_stream *stream; + /* Have we seen a message with clock_snapshot going through this stream? */ + bool seen_clock_snapshot; + /* Owned by this (`NULL` initially and between packets) */ const bt_packet *cur_packet; }; @@ -728,16 +720,15 @@ end: static inline int get_msg_ns_from_origin(const bt_message *msg, int64_t *ns_from_origin, - bool *skip) + bool *has_clock_snapshot) { const bt_clock_class *clock_class = NULL; const bt_clock_snapshot *clock_snapshot = NULL; - bt_message_stream_activity_clock_snapshot_state sa_cs_state; int ret = 0; BT_ASSERT(msg); BT_ASSERT(ns_from_origin); - BT_ASSERT(skip); + BT_ASSERT(has_clock_snapshot); switch (bt_message_get_type(msg)) { case BT_MESSAGE_TYPE_EVENT: @@ -773,66 +764,61 @@ int get_msg_ns_from_origin(const bt_message *msg, int64_t *ns_from_origin, clock_snapshot = bt_message_packet_end_borrow_default_clock_snapshot_const( msg); break; - case BT_MESSAGE_TYPE_DISCARDED_EVENTS: + case BT_MESSAGE_TYPE_STREAM_BEGINNING: + { + enum bt_message_stream_clock_snapshot_state cs_state; + clock_class = - bt_message_discarded_events_borrow_stream_class_default_clock_class_const( - msg); + bt_message_stream_beginning_borrow_stream_class_default_clock_class_const(msg); if (G_UNLIKELY(!clock_class)) { goto error; } - clock_snapshot = bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const( - msg); - break; - case BT_MESSAGE_TYPE_DISCARDED_PACKETS: - clock_class = - bt_message_discarded_packets_borrow_stream_class_default_clock_class_const( - msg); - if (G_UNLIKELY(!clock_class)) { - goto error; + cs_state = bt_message_stream_beginning_borrow_default_clock_snapshot_const(msg, &clock_snapshot); + if (cs_state != BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) { + goto no_clock_snapshot; } - clock_snapshot = bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const( - msg); break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: + } + case BT_MESSAGE_TYPE_STREAM_END: + { + enum bt_message_stream_clock_snapshot_state cs_state; + clock_class = - bt_message_stream_activity_beginning_borrow_stream_class_default_clock_class_const( - msg); + bt_message_stream_end_borrow_stream_class_default_clock_class_const(msg); if (G_UNLIKELY(!clock_class)) { goto error; } - sa_cs_state = bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const( - msg, &clock_snapshot); - if (sa_cs_state == BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN || - sa_cs_state == BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE) { - /* Lowest possible time to always include them */ - *ns_from_origin = INT64_MIN; + cs_state = bt_message_stream_end_borrow_default_clock_snapshot_const(msg, &clock_snapshot); + if (cs_state != BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) { goto no_clock_snapshot; } break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: + } + case BT_MESSAGE_TYPE_DISCARDED_EVENTS: clock_class = - bt_message_stream_activity_end_borrow_stream_class_default_clock_class_const( + bt_message_discarded_events_borrow_stream_class_default_clock_class_const( msg); if (G_UNLIKELY(!clock_class)) { goto error; } - sa_cs_state = bt_message_stream_activity_end_borrow_default_clock_snapshot_const( - msg, &clock_snapshot); - if (sa_cs_state == BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN) { - /* Lowest time to always include it */ - *ns_from_origin = INT64_MIN; - goto no_clock_snapshot; - } else if (sa_cs_state == BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE) { - /* Greatest time to always exclude it */ - *ns_from_origin = INT64_MAX; - goto no_clock_snapshot; + clock_snapshot = bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const( + msg); + break; + case BT_MESSAGE_TYPE_DISCARDED_PACKETS: + clock_class = + bt_message_discarded_packets_borrow_stream_class_default_clock_class_const( + msg); + if (G_UNLIKELY(!clock_class)) { + goto error; } + clock_snapshot = bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const( + msg); break; case BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY: clock_snapshot = @@ -849,10 +835,11 @@ int get_msg_ns_from_origin(const bt_message *msg, int64_t *ns_from_origin, goto error; } + *has_clock_snapshot = true; goto end; no_clock_snapshot: - *skip = true; + *has_clock_snapshot = false; goto end; error: @@ -934,16 +921,16 @@ state_set_trimmer_iterator_bounds( for (i = 0; i < count; i++) { const bt_message *msg = msgs[i]; - bool skip = false; + bool has_ns_from_origin; int ret; ret = get_msg_ns_from_origin(msg, &ns_from_origin, - &skip); + &has_ns_from_origin); if (ret) { goto error; } - if (skip) { + if (!has_ns_from_origin) { continue; } @@ -1068,28 +1055,27 @@ end_stream(struct trimmer_iterator *trimmer_it, { bt_component_class_message_iterator_next_method_status status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; - uint64_t raw_value; - const bt_clock_class *clock_class; - int ret; + /* Initialize to silence maybe-uninitialized warning. */ + uint64_t raw_value = 0; bt_message *msg = NULL; BT_ASSERT(!trimmer_it->end.is_infinite); + BT_ASSERT(sstate->stream); - if (!sstate->stream) { - goto end; - } - - if (sstate->cur_packet) { - /* - * The last message could not have been a stream - * activity end message if we have a current packet. - */ - BT_ASSERT(!sstate->last_msg_is_stream_activity_end); + /* + * If we haven't seen a message with a clock snapshot, we don't know if the trimmer's end bound is within + * the clock's range, so it wouldn't be safe to try to convert ns_from_origin to a clock value. + * + * Also, it would be a bit of a lie to generate a stream end message with the end bound as its + * clock snapshot, because we don't really know if the stream existed at that time. If we have + * seen a message with a clock snapshot and the stream is cut short by another message with a + * clock snapshot, then we are sure that the the end bound time is not below the clock range, + * and we know the stream was active at that time (and that we cut it short). + */ + if (sstate->seen_clock_snapshot) { + const bt_clock_class *clock_class; + int ret; - /* - * Create and push a packet end message, making its time - * the trimming range's end time. - */ clock_class = bt_stream_class_borrow_default_clock_class_const( bt_stream_borrow_class_const(sstate->stream)); BT_ASSERT(clock_class); @@ -1099,6 +1085,19 @@ end_stream(struct trimmer_iterator *trimmer_it, status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; goto end; } + } + + if (sstate->cur_packet) { + /* + * Create and push a packet end message, making its time + * the trimming range's end time. + * + * We know that we must have seen a clock snapshot, the one in + * the packet beginning message, since trimmer currently + * requires packet messages to have clock snapshots (see comment + * in create_stream_state_entry). + */ + BT_ASSERT(sstate->seen_clock_snapshot); msg = bt_message_packet_end_create_with_default_clock_snapshot( trimmer_it->self_msg_iter, sstate->cur_packet, @@ -1111,56 +1110,9 @@ end_stream(struct trimmer_iterator *trimmer_it, push_message(trimmer_it, msg); msg = NULL; BT_PACKET_PUT_REF_AND_RESET(sstate->cur_packet); - - /* - * Because we generated a packet end message, set the - * stream activity end message's time to use to the - * trimming range's end time (this packet end message's - * time). - */ - sstate->stream_act_end_ns_from_origin = - trimmer_it->end.ns_from_origin; } - if (!sstate->last_msg_is_stream_activity_end) { - /* Create and push a stream activity end message */ - msg = bt_message_stream_activity_end_create( - trimmer_it->self_msg_iter, sstate->stream); - if (!msg) { - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_MEMORY_ERROR; - goto end; - } - - clock_class = bt_stream_class_borrow_default_clock_class_const( - bt_stream_borrow_class_const(sstate->stream)); - BT_ASSERT(clock_class); - - if (sstate->stream_act_end_ns_from_origin == INT64_MIN) { - /* - * We received at least what is necessary to - * have a stream state (stream beginning and - * stream activity beginning messages), but - * nothing else: use the trimmer range's end - * time. - */ - sstate->stream_act_end_ns_from_origin = - trimmer_it->end.ns_from_origin; - } - - ret = clock_raw_value_from_ns_from_origin(clock_class, - sstate->stream_act_end_ns_from_origin, &raw_value); - if (ret) { - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; - goto end; - } - - bt_message_stream_activity_end_set_default_clock_snapshot( - msg, raw_value); - push_message(trimmer_it, msg); - msg = NULL; - } - - /* Create and push a stream end message */ + /* Create and push a stream end message. */ msg = bt_message_stream_end_create(trimmer_it->self_msg_iter, sstate->stream); if (!msg) { @@ -1168,6 +1120,10 @@ end_stream(struct trimmer_iterator *trimmer_it, goto end; } + if (sstate->seen_clock_snapshot) { + bt_message_stream_end_set_default_clock_snapshot(msg, raw_value); + } + push_message(trimmer_it, msg); msg = NULL; @@ -1220,6 +1176,134 @@ end: return status; } +static +bt_component_class_message_iterator_next_method_status +create_stream_state_entry( + struct trimmer_iterator *trimmer_it, + const struct bt_stream *stream, + struct trimmer_iterator_stream_state **stream_state) +{ + struct trimmer_comp *trimmer_comp = trimmer_it->trimmer_comp; + bt_component_class_message_iterator_next_method_status status; + struct trimmer_iterator_stream_state *sstate; + const bt_stream_class *sc; + + BT_ASSERT(!bt_g_hash_table_contains(trimmer_it->stream_states, stream)); + + /* + * Validate right now that the stream's class + * has a registered default clock class so that + * an existing stream state guarantees existing + * default clock snapshots for its associated + * messages. + * + * Also check that clock snapshots are always + * known. + */ + sc = bt_stream_borrow_class_const(stream); + if (!bt_stream_class_borrow_default_clock_class_const(sc)) { + BT_COMP_LOGE("Unsupported stream: stream class does " + "not have a default clock class: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + stream, bt_stream_get_id(stream), + bt_stream_get_name(stream)); + status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; + goto end; + } + + /* + * Temporary: make sure packet beginning, packet + * end, discarded events, and discarded packets + * messages have default clock snapshots until + * the support for not having them is + * implemented. + */ + if (!bt_stream_class_packets_have_beginning_default_clock_snapshot( + sc)) { + BT_COMP_LOGE("Unsupported stream: packets have " + "no beginning clock snapshot: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + stream, bt_stream_get_id(stream), + bt_stream_get_name(stream)); + status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; + goto end; + } + + if (!bt_stream_class_packets_have_end_default_clock_snapshot( + sc)) { + BT_COMP_LOGE("Unsupported stream: packets have " + "no end clock snapshot: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + stream, bt_stream_get_id(stream), + bt_stream_get_name(stream)); + status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; + goto end; + } + + if (bt_stream_class_supports_discarded_events(sc) && + !bt_stream_class_discarded_events_have_default_clock_snapshots(sc)) { + BT_COMP_LOGE("Unsupported stream: discarded events " + "have no clock snapshots: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + stream, bt_stream_get_id(stream), + bt_stream_get_name(stream)); + status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; + goto end; + } + + if (bt_stream_class_supports_discarded_packets(sc) && + !bt_stream_class_discarded_packets_have_default_clock_snapshots(sc)) { + BT_COMP_LOGE("Unsupported stream: discarded packets " + "have no clock snapshots: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + stream, bt_stream_get_id(stream), + bt_stream_get_name(stream)); + status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; + goto end; + } + + sstate = g_new0(struct trimmer_iterator_stream_state, 1); + if (!sstate) { + status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_MEMORY_ERROR; + goto end; + } + + sstate->stream = stream; + + g_hash_table_insert(trimmer_it->stream_states, (void *) stream, sstate); + + *stream_state = sstate; + + status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; + +end: + return status; +} + +static +struct trimmer_iterator_stream_state *get_stream_state_entry( + struct trimmer_iterator *trimmer_it, + const struct bt_stream *stream) +{ + struct trimmer_iterator_stream_state *sstate; + + BT_ASSERT(stream); + sstate = g_hash_table_lookup(trimmer_it->stream_states, stream); + BT_ASSERT(sstate); + + return sstate; +} + /* * Handles a message which is associated to a given stream state. This * _could_ make the iterator's output message queue grow; this could @@ -1228,69 +1312,108 @@ end: * * This function consumes the `msg` reference, _whatever the outcome_. * - * `ns_from_origin` is the message's time, as given by - * get_msg_ns_from_origin(). + * If non-NULL, `ns_from_origin` is the message's time, as given by + * get_msg_ns_from_origin(). If NULL, the message doesn't have a time. * * This function sets `reached_end` if handling this message made the * iterator reach the end of the trimming range. Note that the output * message queue could contain messages even if this function sets * `reached_end`. */ -static inline +static bt_component_class_message_iterator_next_method_status -handle_message_with_stream_state( +handle_message_with_stream( struct trimmer_iterator *trimmer_it, const bt_message *msg, - struct trimmer_iterator_stream_state *sstate, - int64_t ns_from_origin, bool *reached_end) + const struct bt_stream *stream, const int64_t *ns_from_origin, + bool *reached_end) { bt_component_class_message_iterator_next_method_status status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; bt_message_type msg_type = bt_message_get_type(msg); int ret; + struct trimmer_iterator_stream_state *sstate = NULL; + + /* + * Retrieve the stream's state - except if the message is stream + * beginning, in which case we don't know about about this stream yet. + */ + if (msg_type != BT_MESSAGE_TYPE_STREAM_BEGINNING) { + sstate = get_stream_state_entry(trimmer_it, stream); + } switch (msg_type) { case BT_MESSAGE_TYPE_EVENT: + /* + * Event messages always have a clock snapshot if the stream + * class has a clock class. And we know it has, otherwise we + * couldn't be using the trimmer component. + */ + BT_ASSERT(ns_from_origin); + BT_ASSERT(sstate->cur_packet); + if (G_UNLIKELY(!trimmer_it->end.is_infinite && - ns_from_origin > trimmer_it->end.ns_from_origin)) { + *ns_from_origin > trimmer_it->end.ns_from_origin)) { status = end_iterator_streams(trimmer_it); *reached_end = true; break; } - BT_ASSERT(sstate->cur_packet); + sstate->seen_clock_snapshot = true; + push_message(trimmer_it, msg); msg = NULL; break; + case BT_MESSAGE_TYPE_PACKET_BEGINNING: + /* + * Packet beginning messages won't have a clock snapshot if + * stream_class->packets_have_beginning_default_clock_snapshot + * is false. But for now, assume they always do. + */ + BT_ASSERT(ns_from_origin); + BT_ASSERT(!sstate->cur_packet); + if (G_UNLIKELY(!trimmer_it->end.is_infinite && - ns_from_origin > trimmer_it->end.ns_from_origin)) { + *ns_from_origin > trimmer_it->end.ns_from_origin)) { status = end_iterator_streams(trimmer_it); *reached_end = true; break; } - BT_ASSERT(!sstate->cur_packet); sstate->cur_packet = bt_message_packet_beginning_borrow_packet_const(msg); bt_packet_get_ref(sstate->cur_packet); + + sstate->seen_clock_snapshot = true; + push_message(trimmer_it, msg); msg = NULL; break; + case BT_MESSAGE_TYPE_PACKET_END: - sstate->stream_act_end_ns_from_origin = ns_from_origin; + /* + * Packet end messages won't have a clock snapshot if + * stream_class->packets_have_end_default_clock_snapshot + * is false. But for now, assume they always do. + */ + BT_ASSERT(ns_from_origin); + BT_ASSERT(sstate->cur_packet); if (G_UNLIKELY(!trimmer_it->end.is_infinite && - ns_from_origin > trimmer_it->end.ns_from_origin)) { + *ns_from_origin > trimmer_it->end.ns_from_origin)) { status = end_iterator_streams(trimmer_it); *reached_end = true; break; } - BT_ASSERT(sstate->cur_packet); BT_PACKET_PUT_REF_AND_RESET(sstate->cur_packet); + + sstate->seen_clock_snapshot = true; + push_message(trimmer_it, msg); msg = NULL; break; + case BT_MESSAGE_TYPE_DISCARDED_EVENTS: case BT_MESSAGE_TYPE_DISCARDED_PACKETS: { @@ -1301,6 +1424,10 @@ handle_message_with_stream_state( int64_t end_ns_from_origin; const bt_clock_snapshot *end_cs; + BT_ASSERT(ns_from_origin); + + sstate->seen_clock_snapshot = true; + if (bt_message_get_type(msg) == BT_MESSAGE_TYPE_DISCARDED_EVENTS) { /* @@ -1326,10 +1453,8 @@ handle_message_with_stream_state( goto end; } - sstate->stream_act_end_ns_from_origin = end_ns_from_origin; - if (!trimmer_it->end.is_infinite && - ns_from_origin > trimmer_it->end.ns_from_origin) { + *ns_from_origin > trimmer_it->end.ns_from_origin) { status = end_iterator_streams(trimmer_it); *reached_end = true; break; @@ -1389,87 +1514,60 @@ handle_message_with_stream_state( msg = NULL; break; } - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - if (!trimmer_it->end.is_infinite && - ns_from_origin > trimmer_it->end.ns_from_origin) { - /* - * This only happens when the message's time is - * known and is greater than the trimming - * range's end time. Unknown and -inf times are - * always less than - * `trimmer_it->end.ns_from_origin`. - */ + + case BT_MESSAGE_TYPE_STREAM_BEGINNING: + /* + * If this message has a time and this time is greater than the + * trimmer's end bound, it triggers the end of the trim window. + */ + if (G_UNLIKELY(ns_from_origin && !trimmer_it->end.is_infinite && + *ns_from_origin > trimmer_it->end.ns_from_origin)) { status = end_iterator_streams(trimmer_it); *reached_end = true; break; } - push_message(trimmer_it, msg); - msg = NULL; - break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - if (trimmer_it->end.is_infinite) { - push_message(trimmer_it, msg); - msg = NULL; - break; + /* Learn about this stream. */ + status = create_stream_state_entry(trimmer_it, stream, &sstate); + if (status != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK) { + goto end; } - if (ns_from_origin == INT64_MIN) { - /* Unknown: consider it to be in the trimmer window. */ - push_message(trimmer_it, msg); - msg = NULL; - sstate->last_msg_is_stream_activity_end = true; - } else if (ns_from_origin == INT64_MAX) { - /* Infinite: use trimming range's end time */ - sstate->stream_act_end_ns_from_origin = - trimmer_it->end.ns_from_origin; - } else { - /* Known: check if outside of trimming range */ - if (ns_from_origin > trimmer_it->end.ns_from_origin) { - sstate->stream_act_end_ns_from_origin = - trimmer_it->end.ns_from_origin; - status = end_iterator_streams(trimmer_it); - *reached_end = true; - break; - } - - push_message(trimmer_it, msg); - msg = NULL; - sstate->last_msg_is_stream_activity_end = true; - sstate->stream_act_end_ns_from_origin = ns_from_origin; + if (ns_from_origin) { + sstate->seen_clock_snapshot = true; } - break; - case BT_MESSAGE_TYPE_STREAM_BEGINNING: push_message(trimmer_it, msg); msg = NULL; break; case BT_MESSAGE_TYPE_STREAM_END: + { + gboolean removed; + /* - * This is the end of a stream: end this - * stream if its stream activity end message - * time is not the trimming range's end time - * (which means the final stream activity end - * message had an infinite time). end_stream() - * will generate its own stream end message. + * If this message has a time and this time is greater than the + * trimmer's end bound, it triggers the end of the trim window. */ - if (trimmer_it->end.is_infinite) { - push_message(trimmer_it, msg); - msg = NULL; + if (G_UNLIKELY(ns_from_origin && !trimmer_it->end.is_infinite && + *ns_from_origin > trimmer_it->end.ns_from_origin)) { + status = end_iterator_streams(trimmer_it); + *reached_end = true; + break; + } - /* We won't need this stream state again */ - g_hash_table_remove(trimmer_it->stream_states, sstate->stream); - } else if (sstate->stream_act_end_ns_from_origin < - trimmer_it->end.ns_from_origin) { - status = end_stream(trimmer_it, sstate); - if (status != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK) { - goto end; - } + /* + * Either the stream end message's time is within the trimmer's + * bounds, or it doesn't have a time. In both cases, pass + * the message unmodified. + */ + push_message(trimmer_it, msg); + msg = NULL; - /* We won't need this stream state again */ - g_hash_table_remove(trimmer_it->stream_states, sstate->stream); - } + /* Forget about this stream. */ + removed = g_hash_table_remove(trimmer_it->stream_states, sstate->stream); + BT_ASSERT(removed); break; + } default: break; } @@ -1477,7 +1575,7 @@ handle_message_with_stream_state( end: /* We release the message's reference whatever the outcome */ bt_message_put_ref(msg); - return BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; + return status; } /* @@ -1500,10 +1598,8 @@ bt_component_class_message_iterator_next_method_status handle_message( bt_component_class_message_iterator_next_method_status status; const bt_stream *stream = NULL; int64_t ns_from_origin = INT64_MIN; - bool skip; + bool has_ns_from_origin; int ret; - struct trimmer_iterator_stream_state *sstate = NULL; - struct trimmer_comp *trimmer_comp = trimmer_it->trimmer_comp; /* Find message's associated stream */ switch (bt_message_get_type(msg)) { @@ -1525,12 +1621,6 @@ bt_component_class_message_iterator_next_method_status handle_message( case BT_MESSAGE_TYPE_DISCARDED_PACKETS: stream = bt_message_discarded_packets_borrow_stream_const(msg); break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: - stream = bt_message_stream_activity_beginning_borrow_stream_const(msg); - break; - case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END: - stream = bt_message_stream_activity_end_borrow_stream_const(msg); - break; case BT_MESSAGE_TYPE_STREAM_BEGINNING: stream = bt_message_stream_beginning_borrow_stream_const(msg); break; @@ -1541,121 +1631,17 @@ bt_component_class_message_iterator_next_method_status handle_message( break; } - if (G_LIKELY(stream)) { - /* Find stream state */ - sstate = g_hash_table_lookup(trimmer_it->stream_states, - stream); - if (G_UNLIKELY(!sstate)) { - /* No stream state yet: create one now */ - const bt_stream_class *sc; - - /* - * Validate right now that the stream's class - * has a registered default clock class so that - * an existing stream state guarantees existing - * default clock snapshots for its associated - * messages. - * - * Also check that clock snapshots are always - * known. - */ - sc = bt_stream_borrow_class_const(stream); - if (!bt_stream_class_borrow_default_clock_class_const(sc)) { - BT_COMP_LOGE("Unsupported stream: stream class does " - "not have a default clock class: " - "stream-addr=%p, " - "stream-id=%" PRIu64 ", " - "stream-name=\"%s\"", - stream, bt_stream_get_id(stream), - bt_stream_get_name(stream)); - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; - goto end; - } - - /* - * Temporary: make sure packet beginning, packet - * end, discarded events, and discarded packets - * messages have default clock snapshots until - * the support for not having them is - * implemented. - */ - if (!bt_stream_class_packets_have_beginning_default_clock_snapshot( - sc)) { - BT_COMP_LOGE("Unsupported stream: packets have " - "no beginning clock snapshot: " - "stream-addr=%p, " - "stream-id=%" PRIu64 ", " - "stream-name=\"%s\"", - stream, bt_stream_get_id(stream), - bt_stream_get_name(stream)); - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; - goto end; - } - - if (!bt_stream_class_packets_have_end_default_clock_snapshot( - sc)) { - BT_COMP_LOGE("Unsupported stream: packets have " - "no end clock snapshot: " - "stream-addr=%p, " - "stream-id=%" PRIu64 ", " - "stream-name=\"%s\"", - stream, bt_stream_get_id(stream), - bt_stream_get_name(stream)); - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; - goto end; - } - - if (bt_stream_class_supports_discarded_events(sc) && - !bt_stream_class_discarded_events_have_default_clock_snapshots(sc)) { - BT_COMP_LOGE("Unsupported stream: discarded events " - "have no clock snapshots: " - "stream-addr=%p, " - "stream-id=%" PRIu64 ", " - "stream-name=\"%s\"", - stream, bt_stream_get_id(stream), - bt_stream_get_name(stream)); - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; - goto end; - } - - if (bt_stream_class_supports_discarded_packets(sc) && - !bt_stream_class_discarded_packets_have_default_clock_snapshots(sc)) { - BT_COMP_LOGE("Unsupported stream: discarded packets " - "have no clock snapshots: " - "stream-addr=%p, " - "stream-id=%" PRIu64 ", " - "stream-name=\"%s\"", - stream, bt_stream_get_id(stream), - bt_stream_get_name(stream)); - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; - goto end; - } - - sstate = g_new0(struct trimmer_iterator_stream_state, - 1); - if (!sstate) { - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_MEMORY_ERROR; - goto end; - } - - sstate->stream = stream; - sstate->stream_act_end_ns_from_origin = INT64_MIN; - g_hash_table_insert(trimmer_it->stream_states, - (void *) stream, sstate); - } - } - /* Retrieve the message's time */ - ret = get_msg_ns_from_origin(msg, &ns_from_origin, &skip); + ret = get_msg_ns_from_origin(msg, &ns_from_origin, &has_ns_from_origin); if (G_UNLIKELY(ret)) { status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; goto end; } - if (G_LIKELY(sstate)) { + if (G_LIKELY(stream)) { /* Message associated to a stream */ - status = handle_message_with_stream_state(trimmer_it, msg, - sstate, ns_from_origin, reached_end); + status = handle_message_with_stream(trimmer_it, msg, + stream, has_ns_from_origin ? &ns_from_origin : NULL, reached_end); /* * handle_message_with_stream_state() unconditionally diff --git a/tests/Makefile.am b/tests/Makefile.am index 36b0ab93..00f69f51 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -93,6 +93,12 @@ TESTS_PLUGINS += \ plugins/flt.lttng-utils.debug-info/test_bin_info_x86_64-linux-gnu endif +if ENABLE_PYTHON_PLUGINS +if ENABLE_PYTHON_BINDINGS +TESTS_PLUGINS += plugins/flt.utils.trimmer/test_trimming_wrapper +endif +endif + TESTS_PYTHON_PLUGIN_PROVIDER = if ENABLE_PYTHON_PLUGINS diff --git a/tests/bindings/python/bt2/test_message.py b/tests/bindings/python/bt2/test_message.py index 18154663..c98edea7 100644 --- a/tests/bindings/python/bt2/test_message.py +++ b/tests/bindings/python/bt2/test_message.py @@ -27,51 +27,50 @@ class AllMessagesTestCase(unittest.TestCase): class MyIter(bt2._UserMessageIterator): def __init__(self, self_port_output): self._at = 0 + self._with_stream_msgs_clock_snapshots = self_port_output.user_data.get('with_stream_msgs_clock_snapshots', False) def __next__(self): if test_obj._clock_class: if self._at == 0: - msg = self._create_stream_beginning_message(test_obj._stream) + if self._with_stream_msgs_clock_snapshots: + msg = self._create_stream_beginning_message(test_obj._stream, default_clock_snapshot=self._at) + else: + msg = self._create_stream_beginning_message(test_obj._stream) elif self._at == 1: - msg = self._create_stream_activity_beginning_message(test_obj._stream, default_clock_snapshot=self._at) - elif self._at == 2: msg = self._create_packet_beginning_message(test_obj._packet, self._at) - elif self._at == 3: + elif self._at == 2: msg = self._create_event_message(test_obj._event_class, test_obj._packet, self._at) - elif self._at == 4: + elif self._at == 3: msg = self._create_message_iterator_inactivity_message(test_obj._clock_class, self._at) - elif self._at == 5: + elif self._at == 4: msg = self._create_discarded_events_message(test_obj._stream, 890, self._at, self._at) - elif self._at == 6: + elif self._at == 5: msg = self._create_packet_end_message(test_obj._packet, self._at) - elif self._at == 7: + elif self._at == 6: msg = self._create_discarded_packets_message(test_obj._stream, 678, self._at, self._at) - elif self._at == 8: - msg = self._create_stream_activity_end_message(test_obj._stream, default_clock_snapshot=self._at) - elif self._at == 9: - msg = self._create_stream_end_message(test_obj._stream) - elif self._at >= 10: + elif self._at == 7: + if self._with_stream_msgs_clock_snapshots: + msg = self._create_stream_end_message(test_obj._stream, default_clock_snapshot=self._at) + else: + msg = self._create_stream_end_message(test_obj._stream) + elif self._at >= 8: raise bt2.Stop else: if self._at == 0: msg = self._create_stream_beginning_message(test_obj._stream) elif self._at == 1: - msg = self._create_stream_activity_beginning_message(test_obj._stream) - elif self._at == 2: msg = self._create_packet_beginning_message(test_obj._packet) - elif self._at == 3: + elif self._at == 2: msg = self._create_event_message(test_obj._event_class, test_obj._packet) - elif self._at == 4: + elif self._at == 3: msg = self._create_discarded_events_message(test_obj._stream, 890) - elif self._at == 5: + elif self._at == 4: msg = self._create_packet_end_message(test_obj._packet) - elif self._at == 6: + elif self._at == 5: msg = self._create_discarded_packets_message(test_obj._stream, 678) - elif self._at == 7: - msg = self._create_stream_activity_end_message(test_obj._stream) - elif self._at == 8: + elif self._at == 6: msg = self._create_stream_end_message(test_obj._stream) - elif self._at >= 9: + elif self._at >= 7: raise bt2.Stop self._at += 1 @@ -79,7 +78,7 @@ class AllMessagesTestCase(unittest.TestCase): class MySrc(bt2._UserSourceComponent, message_iterator_class=MyIter): def __init__(self, params): - self._add_output_port('out') + self._add_output_port('out', params) with_cc = bool(params['with_cc']) tc = self._create_trace_class() @@ -129,45 +128,40 @@ class AllMessagesTestCase(unittest.TestCase): if i == 0: self.assertIsInstance(msg, bt2.message._StreamBeginningMessage) self.assertEqual(msg.stream.addr, self._stream.addr) + self.assertIsInstance(msg.default_clock_snapshot, bt2.clock_snapshot._UnknownClockSnapshot) elif i == 1: - self.assertIsInstance(msg, bt2.message._StreamActivityBeginningMessage) - self.assertEqual(msg.default_clock_snapshot.value, i) - elif i == 2: self.assertIsInstance(msg, bt2.message._PacketBeginningMessage) self.assertEqual(msg.packet.addr, self._packet.addr) self.assertEqual(msg.default_clock_snapshot.value, i) - elif i == 3: + elif i == 2: self.assertIsInstance(msg, bt2.message._EventMessage) self.assertEqual(msg.event.cls.addr, self._event_class.addr) self.assertEqual(msg.default_clock_snapshot.value, i) - elif i == 4: + elif i == 3: self.assertIsInstance(msg, bt2.message._MessageIteratorInactivityMessage) self.assertEqual(msg.default_clock_snapshot.value, i) - elif i == 5: + elif i == 4: self.assertIsInstance(msg, bt2.message._DiscardedEventsMessage) self.assertEqual(msg.stream.addr, self._stream.addr) self.assertEqual(msg.count, 890) self.assertEqual(msg.stream.cls.default_clock_class.addr, self._clock_class.addr) self.assertEqual(msg.beginning_default_clock_snapshot.value, i) self.assertEqual(msg.end_default_clock_snapshot.value, i) - elif i == 6: + elif i == 5: self.assertIsInstance(msg, bt2.message._PacketEndMessage) self.assertEqual(msg.packet.addr, self._packet.addr) self.assertEqual(msg.default_clock_snapshot.value, i) - elif i == 7: + elif i == 6: self.assertIsInstance(msg, bt2.message._DiscardedPacketsMessage) self.assertEqual(msg.stream.addr, self._stream.addr) self.assertEqual(msg.count, 678) self.assertEqual(msg.stream.cls.default_clock_class.addr, self._clock_class.addr) self.assertEqual(msg.beginning_default_clock_snapshot.value, i) self.assertEqual(msg.end_default_clock_snapshot.value, i) - elif i == 8: - self.assertIsInstance(msg, bt2.message._StreamActivityEndMessage) - self.assertEqual(msg.stream.addr, self._stream.addr) - self.assertEqual(msg.default_clock_snapshot.value, i) - elif i == 9: + elif i == 7: self.assertIsInstance(msg, bt2.message._StreamEndMessage) self.assertEqual(msg.stream.addr, self._stream.addr) + self.assertIsInstance(msg.default_clock_snapshot, bt2.clock_snapshot._UnknownClockSnapshot) else: raise Exception @@ -180,19 +174,17 @@ class AllMessagesTestCase(unittest.TestCase): if i == 0: self.assertIsInstance(msg, bt2.message._StreamBeginningMessage) self.assertEqual(msg.stream.addr, self._stream.addr) + with self.assertRaises(bt2.NonexistentClockSnapshot): + msg.default_clock_snapshot elif i == 1: - self.assertIsInstance(msg, bt2.message._StreamActivityBeginningMessage) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._UnknownClockSnapshot) - elif i == 2: self.assertIsInstance(msg, bt2.message._PacketBeginningMessage) self.assertEqual(msg.packet.addr, self._packet.addr) - elif i == 3: + elif i == 2: self.assertIsInstance(msg, bt2.message._EventMessage) self.assertEqual(msg.event.cls.addr, self._event_class.addr) with self.assertRaises(bt2.NonexistentClockSnapshot): msg.default_clock_snapshot - elif i == 4: + elif i == 3: self.assertIsInstance(msg, bt2.message._DiscardedEventsMessage) self.assertEqual(msg.stream.addr, self._stream.addr) self.assertEqual(msg.count, 890) @@ -201,10 +193,10 @@ class AllMessagesTestCase(unittest.TestCase): msg.beginning_default_clock_snapshot with self.assertRaises(bt2.NonexistentClockSnapshot): msg.end_default_clock_snapshot - elif i == 5: + elif i == 4: self.assertIsInstance(msg, bt2.message._PacketEndMessage) self.assertEqual(msg.packet.addr, self._packet.addr) - elif i == 6: + elif i == 5: self.assertIsInstance(msg, bt2.message._DiscardedPacketsMessage) self.assertEqual(msg.stream.addr, self._stream.addr) self.assertEqual(msg.count, 678) @@ -213,231 +205,28 @@ class AllMessagesTestCase(unittest.TestCase): msg.beginning_default_clock_snapshot with self.assertRaises(bt2.NonexistentClockSnapshot): msg.end_default_clock_snapshot - elif i == 7: - self.assertIsInstance(msg, bt2.message._StreamActivityEndMessage) - self.assertEqual(msg.stream.addr, self._stream.addr) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._UnknownClockSnapshot) - elif i == 8: + elif i == 6: self.assertIsInstance(msg, bt2.message._StreamEndMessage) self.assertEqual(msg.stream.addr, self._stream.addr) + with self.assertRaises(bt2.NonexistentClockSnapshot): + msg.default_clock_snapshot else: raise Exception + def test_msg_stream_with_clock_snapshots(self): + params = { + 'with_cc': True, + 'with_stream_msgs_clock_snapshots': True, + } -class StreamActivityMessagesTestCase(unittest.TestCase): - def _test_create_msg(self, with_cc, test_create_beginning_func, test_create_end_func): - class MyIter(bt2._UserMessageIterator): - def __init__(self, self_port_output): - self._at = 0 - - def __next__(self): - if self._at == 0: - msg = self._create_stream_beginning_message(self._component._stream) - elif self._at == 1: - msg = test_create_beginning_func(self, self._component._stream) - elif self._at == 2: - msg = test_create_end_func(self, self._component._stream) - elif self._at == 3: - msg = self._create_stream_end_message(self._component._stream) - elif self._at >= 4: - raise bt2.Stop - - self._at += 1 - return msg - - class MySrc(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): - self._add_output_port('out') - tc = self._create_trace_class() - - if with_cc: - cc = self._create_clock_class() - sc = tc.create_stream_class(default_clock_class=cc) - else: - sc = tc.create_stream_class() - - # Create payload field class - trace = tc() - self._stream = trace.create_stream(sc) - - graph = bt2.Graph() - src_comp = graph.add_component(MySrc, 'src') - msg_iter = graph.create_output_port_message_iterator(src_comp.output_ports['out']) - - for msg in msg_iter: - pass - - def test_create_beginning_with_cc_with_known_default_cs(self): - def create_beginning(msg_iter, stream): - msg = msg_iter._create_stream_activity_beginning_message(stream, 172) - self.assertEqual(msg.default_clock_snapshot.value, 172) - return msg - - def create_end(msg_iter, stream): - return msg_iter._create_stream_activity_end_message(stream, 199) - - self._test_create_msg(True, create_beginning, create_end) - - def test_create_end_with_cc_with_known_default_cs(self): - def create_beginning(msg_iter, stream): - return msg_iter._create_stream_activity_beginning_message(stream, 172) - - def create_end(msg_iter, stream): - msg = msg_iter._create_stream_activity_end_message(stream, 199) - self.assertEqual(msg.default_clock_snapshot.value, 199) - return msg - - self._test_create_msg(True, create_beginning, create_end) - - def test_create_beginning_with_cc_with_unknown_default_cs(self): - def create_beginning(msg_iter, stream): - msg = msg_iter._create_stream_activity_beginning_message(stream, - msg_iter._unknown_clock_snapshot) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._UnknownClockSnapshot) - return msg - - def create_end(msg_iter, stream): - return msg_iter._create_stream_activity_end_message(stream, 199) - - self._test_create_msg(True, create_beginning, create_end) - - def test_create_end_with_cc_with_unknown_default_cs(self): - def create_beginning(msg_iter, stream): - return msg_iter._create_stream_activity_beginning_message(stream, 172) - - def create_end(msg_iter, stream): - msg = msg_iter._create_stream_activity_end_message(stream, - msg_iter._unknown_clock_snapshot) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._UnknownClockSnapshot) - return msg - - self._test_create_msg(True, create_beginning, create_end) - - def test_create_beginning_with_cc_with_infinite_default_cs(self): - def create_beginning(msg_iter, stream): - msg = msg_iter._create_stream_activity_beginning_message(stream, - msg_iter._infinite_clock_snapshot) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._InfiniteClockSnapshot) - return msg - - def create_end(msg_iter, stream): - return msg_iter._create_stream_activity_end_message(stream, 199) - - self._test_create_msg(True, create_beginning, create_end) - - def test_create_end_with_cc_with_infinite_default_cs(self): - def create_beginning(msg_iter, stream): - return msg_iter._create_stream_activity_beginning_message(stream, 172) - - def create_end(msg_iter, stream): - msg = msg_iter._create_stream_activity_end_message(stream, - msg_iter._infinite_clock_snapshot) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._InfiniteClockSnapshot) - return msg - - self._test_create_msg(True, create_beginning, create_end) - - def test_create_beginning_without_cc_with_known_default_cs(self): - def create_beginning(msg_iter, stream): - with self.assertRaises(ValueError): - msg_iter._create_stream_activity_beginning_message(stream, 172) - - return msg_iter._create_stream_activity_beginning_message(stream) - - def create_end(msg_iter, stream): - return msg_iter._create_stream_activity_end_message(stream) - - self._test_create_msg(False, create_beginning, create_end) - - def test_create_end_without_cc_with_known_default_cs(self): - def create_beginning(msg_iter, stream): - return msg_iter._create_stream_activity_beginning_message(stream) - - def create_end(msg_iter, stream): - with self.assertRaises(ValueError): - msg_iter._create_stream_activity_end_message(stream, 199) - - return msg_iter._create_stream_activity_end_message(stream) - - self._test_create_msg(False, create_beginning, create_end) - - def test_create_beginning_without_cc_with_unknown_default_cs(self): - def create_beginning(msg_iter, stream): - msg = msg_iter._create_stream_activity_beginning_message(stream, - msg_iter._unknown_clock_snapshot) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._UnknownClockSnapshot) - return msg - - def create_end(msg_iter, stream): - return msg_iter._create_stream_activity_end_message(stream) - - self._test_create_msg(False, create_beginning, create_end) - - def test_create_end_without_cc_with_unknown_default_cs(self): - def create_beginning(msg_iter, stream): - return msg_iter._create_stream_activity_beginning_message(stream) - - def create_end(msg_iter, stream): - msg = msg_iter._create_stream_activity_end_message(stream, - msg_iter._unknown_clock_snapshot) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._UnknownClockSnapshot) - return msg - - self._test_create_msg(False, create_beginning, create_end) - - def test_create_beginning_without_cc_with_infinite_default_cs(self): - def create_beginning(msg_iter, stream): - msg = msg_iter._create_stream_activity_beginning_message(stream, - msg_iter._infinite_clock_snapshot) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._InfiniteClockSnapshot) - return msg - - def create_end(msg_iter, stream): - return msg_iter._create_stream_activity_end_message(stream) - - self._test_create_msg(False, create_beginning, create_end) - - def test_create_end_without_cc_with_infinite_default_cs(self): - def create_beginning(msg_iter, stream): - return msg_iter._create_stream_activity_beginning_message(stream) - - def create_end(msg_iter, stream): - msg = msg_iter._create_stream_activity_end_message(stream, - msg_iter._infinite_clock_snapshot) - self.assertIsInstance(msg.default_clock_snapshot, - bt2._InfiniteClockSnapshot) - return msg - - self._test_create_msg(False, create_beginning, create_end) - - def test_create_beginning_default_cs_wrong_type(self): - def create_beginning(msg_iter, stream): - with self.assertRaises(TypeError): - msg_iter._create_stream_activity_beginning_message(stream, 'infinite') - - return msg_iter._create_stream_activity_beginning_message(stream) - - def create_end(msg_iter, stream): - return msg_iter._create_stream_activity_end_message(stream) - - self._test_create_msg(False, create_beginning, create_end) - - def test_create_end_without_default_cs_wrong_type(self): - def create_beginning(msg_iter, stream): - return msg_iter._create_stream_activity_beginning_message(stream) - - def create_end(msg_iter, stream): - with self.assertRaises(TypeError): - msg_iter._create_stream_activity_end_message(stream, 'unknown') + self._src_comp = self._graph.add_component(self._src, 'my_source', params) + self._msg_iter = self._graph.create_output_port_message_iterator(self._src_comp.output_ports['out']) + msgs = list(self._msg_iter) - return msg_iter._create_stream_activity_end_message(stream) + msg_stream_beg = msgs[0] + self.assertIsInstance(msg_stream_beg, bt2.message._StreamBeginningMessage) + self.assertEqual(msg_stream_beg.default_clock_snapshot.value, 0) - self._test_create_msg(False, create_beginning, create_end) + msg_stream_end = msgs[7] + self.assertIsInstance(msg_stream_end, bt2.message._StreamEndMessage) + self.assertEqual(msg_stream_end.default_clock_snapshot.value, 7) diff --git a/tests/bindings/python/bt2/test_message_iterator.py b/tests/bindings/python/bt2/test_message_iterator.py index a9762976..a716ce01 100644 --- a/tests/bindings/python/bt2/test_message_iterator.py +++ b/tests/bindings/python/bt2/test_message_iterator.py @@ -134,7 +134,6 @@ class UserMessageIteratorTestCase(unittest.TestCase): self._msgs = [ self._create_stream_beginning_message(stream), - self._create_stream_activity_beginning_message(stream), self._create_packet_beginning_message(packet), event_message, event_message, @@ -155,9 +154,10 @@ class UserMessageIteratorTestCase(unittest.TestCase): it = graph.create_output_port_message_iterator(src.output_ports['out']) # Skip beginning messages. - next(it) - next(it) - next(it) + msg = next(it) + self.assertIsInstance(msg, bt2.message._StreamBeginningMessage) + msg = next(it) + self.assertIsInstance(msg, bt2.message._PacketBeginningMessage) msg_ev1 = next(it) msg_ev2 = next(it) @@ -182,12 +182,10 @@ class UserMessageIteratorTestCase(unittest.TestCase): self._msgs = [ self._create_stream_beginning_message(stream), - self._create_stream_activity_beginning_message(stream), self._create_packet_beginning_message(packet), self._create_event_message(ec, packet), self._create_event_message(ec, packet), self._create_packet_end_message(packet), - self._create_stream_activity_end_message(stream), self._create_stream_end_message(stream), ] self._at = 0 @@ -274,7 +272,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): msg = next(it) self.assertIsInstance(msg, bt2.message._StreamBeginningMessage) msg = next(it) - self.assertIsInstance(msg, bt2.message._StreamActivityBeginningMessage) + self.assertIsInstance(msg, bt2.message._PacketBeginningMessage) it.seek_beginning() diff --git a/tests/bindings/python/bt2/test_trace_collection_message_iterator.py b/tests/bindings/python/bt2/test_trace_collection_message_iterator.py index c50b1af0..e804a4f2 100644 --- a/tests/bindings/python/bt2/test_trace_collection_message_iterator.py +++ b/tests/bindings/python/bt2/test_trace_collection_message_iterator.py @@ -111,7 +111,7 @@ class TraceCollectionMessageIteratorTestCase(unittest.TestCase): specs = [bt2.ComponentSpec('ctf', 'fs', _3EVENTS_INTERSECT_TRACE_PATH)] msg_iter = bt2.TraceCollectionMessageIterator(specs) msgs = list(msg_iter) - self.assertEqual(len(msgs), 32) + self.assertEqual(len(msgs), 28) hist = _count_msgs_by_type(msgs) self.assertEqual(hist[bt2.message._EventMessage], 8) @@ -120,7 +120,7 @@ class TraceCollectionMessageIteratorTestCase(unittest.TestCase): spec = bt2.ComponentSpec('ctf', 'fs', _3EVENTS_INTERSECT_TRACE_PATH) msg_iter = bt2.TraceCollectionMessageIterator(spec) msgs = list(msg_iter) - self.assertEqual(len(msgs), 32) + self.assertEqual(len(msgs), 28) hist = _count_msgs_by_type(msgs) self.assertEqual(hist[bt2.message._EventMessage], 8) @@ -137,7 +137,7 @@ class TraceCollectionMessageIteratorTestCase(unittest.TestCase): specs = [bt2.ComponentSpec('ctf', 'fs', _3EVENTS_INTERSECT_TRACE_PATH)] msg_iter = bt2.TraceCollectionMessageIterator(specs, stream_intersection_mode=True) msgs = list(msg_iter) - self.assertEqual(len(msgs), 19) + self.assertEqual(len(msgs), 15) hist = _count_msgs_by_type(msgs) self.assertEqual(hist[bt2.message._EventMessage], 3) @@ -152,7 +152,7 @@ class TraceCollectionMessageIteratorTestCase(unittest.TestCase): specs = [spec, spec] msg_iter = bt2.TraceCollectionMessageIterator(specs) msgs = list(msg_iter) - self.assertEqual(len(msgs), 64) + self.assertEqual(len(msgs), 56) hist = _count_msgs_by_type(msgs) self.assertEqual(hist[bt2.message._EventMessage], 16) diff --git a/tests/data/plugins/flt.utils.trimmer/bt_plugin_trimmer_test.py b/tests/data/plugins/flt.utils.trimmer/bt_plugin_trimmer_test.py new file mode 100644 index 00000000..140dd54c --- /dev/null +++ b/tests/data/plugins/flt.utils.trimmer/bt_plugin_trimmer_test.py @@ -0,0 +1,65 @@ +import bt2 + + +class TheIteratorOfAllEvil(bt2._UserMessageIterator): + def __init__(self, port): + tc, sc, ec1, ec2, params = port.user_data + trace = tc() + stream = trace.create_stream(sc) + + # Test with and without packets, once packets are optional. + packet = stream.create_packet() + + if params['with-stream-msgs-cs']: + sb_msg = self._create_stream_beginning_message(stream, 100) + else: + sb_msg = self._create_stream_beginning_message(stream) + + ev_msg1 = self._create_event_message(ec1, packet, 300) + ev_msg2 = self._create_event_message(ec2, packet, 400) + + if params['with-stream-msgs-cs']: + se_msg = self._create_stream_end_message(stream, 1000) + else: + se_msg = self._create_stream_end_message(stream) + + self._msgs = [ + sb_msg, + self._create_packet_beginning_message(packet, 200), + ev_msg1, + ev_msg2, + self._create_packet_end_message(packet, 900), + se_msg, + ] + self._at = 0 + + def _seek_beginning(self): + self._at = 0 + + def __next__(self): + if self._at < len(self._msgs): + msg = self._msgs[self._at] + self._at += 1 + return msg + else: + raise StopIteration + +@bt2.plugin_component_class +class TheSourceOfAllEvil(bt2._UserSourceComponent, + message_iterator_class=TheIteratorOfAllEvil): + def __init__(self, params): + tc = self._create_trace_class() + + # Use a clock class with an offset, so we can test with --begin or --end + # smaller than this offset (in other words, a time that it's not + # possible to represent with this clock class). + cc = self._create_clock_class(frequency=1, offset=bt2.ClockClassOffset(10000)) + sc = tc.create_stream_class(default_clock_class=cc, + packets_have_beginning_default_clock_snapshot=True, + packets_have_end_default_clock_snapshot=True) + ec1 = sc.create_event_class(name='event 1') + ec2 = sc.create_event_class(name='event 2') + self._add_output_port('out', (tc, sc, ec1, ec2, params)) + + +bt2.register_plugin(__name__, 'test-trimmer') diff --git a/tests/data/plugins/sink.ctf.fs/succeed/trace-double.expect b/tests/data/plugins/sink.ctf.fs/succeed/trace-double.expect index 3db72bb2..41384961 100644 --- a/tests/data/plugins/sink.ctf.fs/succeed/trace-double.expect +++ b/tests/data/plugins/sink.ctf.fs/succeed/trace-double.expect @@ -17,15 +17,12 @@ Trace class: Payload field class: Structure (1 member): dbl: Real (Double precision) +[Unknown] {Trace 0, Stream class ID 0, Stream ID 0} Stream beginning: Trace: Stream (ID 0, Class ID 0) -[Unknown] -{Trace 0, Stream class ID 0, Stream ID 0} -Stream activity beginning - [0 cycles, 0 ns from origin] {Trace 0, Stream class ID 0, Stream ID 0} Packet beginning: @@ -41,8 +38,5 @@ Event `ev` (Class ID 0): Packet end [Unknown] -{Trace 0, Stream class ID 0, Stream ID 0} -Stream activity end - {Trace 0, Stream class ID 0, Stream ID 0} Stream end diff --git a/tests/data/plugins/sink.ctf.fs/succeed/trace-float.expect b/tests/data/plugins/sink.ctf.fs/succeed/trace-float.expect index 33f8f18c..17c915db 100644 --- a/tests/data/plugins/sink.ctf.fs/succeed/trace-float.expect +++ b/tests/data/plugins/sink.ctf.fs/succeed/trace-float.expect @@ -17,15 +17,12 @@ Trace class: Payload field class: Structure (1 member): flt: Real (Single precision) +[Unknown] {Trace 0, Stream class ID 0, Stream ID 0} Stream beginning: Trace: Stream (ID 0, Class ID 0) -[Unknown] -{Trace 0, Stream class ID 0, Stream ID 0} -Stream activity beginning - [0 cycles, 0 ns from origin] {Trace 0, Stream class ID 0, Stream ID 0} Packet beginning: @@ -41,8 +38,5 @@ Event `ev` (Class ID 0): Packet end [Unknown] -{Trace 0, Stream class ID 0, Stream ID 0} -Stream activity end - {Trace 0, Stream class ID 0, Stream ID 0} Stream end diff --git a/tests/data/plugins/src.ctf.fs/succeed/trace-simple.expect b/tests/data/plugins/src.ctf.fs/succeed/trace-simple.expect index 90218c2c..c5923ca1 100644 --- a/tests/data/plugins/src.ctf.fs/succeed/trace-simple.expect +++ b/tests/data/plugins/src.ctf.fs/succeed/trace-simple.expect @@ -18,15 +18,12 @@ Trace class: first: Signed integer (8-bit, Base 10) second: String +[Unknown] {Trace 0, Stream class ID 0, Stream ID 0} Stream beginning: Trace: Stream (ID 0, Class ID 0) -[Unknown] -{Trace 0, Stream class ID 0, Stream ID 0} -Stream activity beginning - [0 cycles, 0 ns from origin] {Trace 0, Stream class ID 0, Stream ID 0} Packet beginning: @@ -211,8 +208,5 @@ Event `ev` (Class ID 0): Packet end [Unknown] -{Trace 0, Stream class ID 0, Stream ID 0} -Stream activity end - {Trace 0, Stream class ID 0, Stream ID 0} Stream end diff --git a/tests/data/plugins/src.ctf.fs/succeed/trace-smalltrace.expect b/tests/data/plugins/src.ctf.fs/succeed/trace-smalltrace.expect index a22778fa..7aad423a 100644 --- a/tests/data/plugins/src.ctf.fs/succeed/trace-smalltrace.expect +++ b/tests/data/plugins/src.ctf.fs/succeed/trace-smalltrace.expect @@ -16,10 +16,6 @@ Stream beginning: UUID: 2a6422d0-6cee-11e0-8c08-cb07d7b3a564 Stream (ID 0, Class ID 0) -[Unknown] -{Trace 0, Stream class ID 0, Stream ID 0} -Stream activity beginning - {Trace 0, Stream class ID 0, Stream ID 0} Packet beginning: @@ -36,9 +32,5 @@ Event `string` (Class ID 0): {Trace 0, Stream class ID 0, Stream ID 0} Packet end -[Unknown] -{Trace 0, Stream class ID 0, Stream ID 0} -Stream activity end - {Trace 0, Stream class ID 0, Stream ID 0} Stream end diff --git a/tests/plugins/Makefile.am b/tests/plugins/Makefile.am index 073766f1..998f57a5 100644 --- a/tests/plugins/Makefile.am +++ b/tests/plugins/Makefile.am @@ -1,4 +1,5 @@ SUBDIRS = \ - src.ctf.fs \ sink.ctf.fs \ - flt.lttng-utils.debug-info + src.ctf.fs \ + flt.lttng-utils.debug-info \ + flt.utils.trimmer diff --git a/tests/plugins/flt.utils.trimmer/Makefile.am b/tests/plugins/flt.utils.trimmer/Makefile.am new file mode 100644 index 00000000..92ca5fb6 --- /dev/null +++ b/tests/plugins/flt.utils.trimmer/Makefile.am @@ -0,0 +1,7 @@ +if HAVE_PYTHON + +dist_check_SCRIPTS = \ + test_trimming \ + test_trimming_wrapper + +endif # ENABLE_DEBUG_INFO diff --git a/tests/plugins/flt.utils.trimmer/test_trimming b/tests/plugins/flt.utils.trimmer/test_trimming new file mode 100755 index 00000000..28c3fd2d --- /dev/null +++ b/tests/plugins/flt.utils.trimmer/test_trimming @@ -0,0 +1,400 @@ +#!/bin/bash +# +# Copyright (C) 2019 Simon Marchi +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; only version 2 +# of the License. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# This file tests what happens when we trim at different points in the message +# flow. + +SH_TAP=1 + +if [ "x${BT_TESTS_SRCDIR:-}" != "x" ]; then + UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh" +else + UTILSSH="$(dirname "$0")/../../utils/utils.sh" +fi + +# shellcheck source=../../../utils/utils.sh +source "$UTILSSH" + +data_dir="$BT_TESTS_SRCDIR/data/plugins/flt.utils.trimmer" +temp_expected=$(mktemp) + +plan_tests 32 + +function run_test +{ + local begin_time="$1" + local end_time="$2" + + if [ -n "$begin_time" ]; then + begin="--begin=$begin_time" + test_name="with $begin" + else + begin="" + test_name="without --begin" + fi + + if [ -n "$end_time" ]; then + end="--end=$end_time" + test_name="$test_name, with $end" + else + end="" + test_name="$test_name, without --end" + fi + + # with_stream_msgs_cs is set to "true" or "false" by the tests. + + cli_args="-c src.test-trimmer.TheSourceOfAllEvil -p 'with-stream-msgs-cs=$with_stream_msgs_cs' -c sink.text.details '--params=compact=true,with-metadata=false' '--plugin-path=$data_dir' $begin $end" + + bt_diff_cli "$cli_args" "$temp_expected" + ok $? "$test_name" +} + +function test_with_stream_msg_cs { + with_stream_msgs_cs="true" + + # Baseline (without trimming) + cat <<- 'END' > $temp_expected + [100 10,100,000,000,000] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [1000 11,000,000,000,000] {0 0 0} Stream end + END + run_test "" "" + + # Trim begin at a time before what the clock class can represent + cat <<- 'END' > $temp_expected + [100 10,100,000,000,000] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [1000 11,000,000,000,000] {0 0 0} Stream end + END + run_test 50 "" + + # Trim begin before stream beginning + cat <<- 'END' > $temp_expected + [100 10,100,000,000,000] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [1000 11,000,000,000,000] {0 0 0} Stream end + END + run_test 10050 "" + + # Trim begin before packet beginning + cat <<- 'END' > $temp_expected + [150 10,150,000,000,000] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [1000 11,000,000,000,000] {0 0 0} Stream end + END + run_test 10150 "" + + # Trim begin before first event + cat <<- 'END' > $temp_expected + [250 10,250,000,000,000] {0 0 0} Stream beginning + [250 10,250,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [1000 11,000,000,000,000] {0 0 0} Stream end + END + run_test 10250 "" + + # Trim begin before second event + cat <<- 'END' > $temp_expected + [350 10,350,000,000,000] {0 0 0} Stream beginning + [350 10,350,000,000,000] {0 0 0} Packet beginning + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [1000 11,000,000,000,000] {0 0 0} Stream end + END + + run_test 10350 "" + + # Trim begin before packet end + cat <<- 'END' > $temp_expected + [850 10,850,000,000,000] {0 0 0} Stream beginning + [850 10,850,000,000,000] {0 0 0} Packet beginning + [900 10,900,000,000,000] {0 0 0} Packet end + [1000 11,000,000,000,000] {0 0 0} Stream end + END + + run_test 10850 "" + + # Trim begin after everything + cat <<- 'END' > $temp_expected + END + + run_test 11050 "" + + # Trim end after stream end + cat <<- 'END' > $temp_expected + [100 10,100,000,000,000] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [1000 11,000,000,000,000] {0 0 0} Stream end + END + + run_test "" 11050 + + # Trim end after packet end + cat <<- 'END' > $temp_expected + [100 10,100,000,000,000] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [950 10,950,000,000,000] {0 0 0} Stream end + END + + run_test "" 10950 + + # Trim end after second event + cat <<- 'END' > $temp_expected + [100 10,100,000,000,000] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [450 10,450,000,000,000] {0 0 0} Packet end + [450 10,450,000,000,000] {0 0 0} Stream end + END + + run_test "" 10450 + + # Trim end after first event + cat <<- 'END' > $temp_expected + [100 10,100,000,000,000] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [350 10,350,000,000,000] {0 0 0} Packet end + [350 10,350,000,000,000] {0 0 0} Stream end + END + + run_test "" 10350 + + # Trim end after packet beginning + cat <<- 'END' > $temp_expected + [100 10,100,000,000,000] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [250 10,250,000,000,000] {0 0 0} Packet end + [250 10,250,000,000,000] {0 0 0} Stream end + END + + run_test "" 10250 + + # Trim end after stream beginning + cat <<- 'END' > $temp_expected + [100 10,100,000,000,000] {0 0 0} Stream beginning + [150 10,150,000,000,000] {0 0 0} Stream end + END + + run_test "" 10150 + + # Trim end before everything + cat <<- 'END' > $temp_expected + END + + run_test "" 10050 + + # Trim end at a time before what the clock class can represent + cat <<- 'END' > $temp_expected + END + + run_test "" 50 +} + +function test_without_stream_msg_cs { + with_stream_msgs_cs="false" + + # Baseline (without trimming) + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [Unknown] {0 0 0} Stream end + END + run_test "" "" + + # Trim begin at a time before what the clock class can represent + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [Unknown] {0 0 0} Stream end + END + run_test 50 "" + + # Trim begin before stream beginning + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [Unknown] {0 0 0} Stream end + END + run_test 10050 "" + + # Trim begin before packet beginning + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [Unknown] {0 0 0} Stream end + END + run_test 10150 "" + + # Trim begin before first event + cat <<- 'END' > $temp_expected + [250 10,250,000,000,000] {0 0 0} Stream beginning + [250 10,250,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [Unknown] {0 0 0} Stream end + END + run_test 10250 "" + + # Trim begin before second event + cat <<- 'END' > $temp_expected + [350 10,350,000,000,000] {0 0 0} Stream beginning + [350 10,350,000,000,000] {0 0 0} Packet beginning + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [Unknown] {0 0 0} Stream end + END + + run_test 10350 "" + + # Trim begin before packet end + cat <<- 'END' > $temp_expected + [850 10,850,000,000,000] {0 0 0} Stream beginning + [850 10,850,000,000,000] {0 0 0} Packet beginning + [900 10,900,000,000,000] {0 0 0} Packet end + [Unknown] {0 0 0} Stream end + END + + run_test 10850 "" + + # Trim begin after everything + cat <<- 'END' > $temp_expected + END + + run_test 11050 "" + + # Trim end after stream end + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [Unknown] {0 0 0} Stream end + END + + run_test "" 11050 + + # Trim end after packet end + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [900 10,900,000,000,000] {0 0 0} Packet end + [Unknown] {0 0 0} Stream end + END + + run_test "" 10950 + + # Trim end after second event + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [400 10,400,000,000,000] {0 0 0} Event `event 2` (1) + [450 10,450,000,000,000] {0 0 0} Packet end + [450 10,450,000,000,000] {0 0 0} Stream end + END + + run_test "" 10450 + + # Trim end after first event + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [300 10,300,000,000,000] {0 0 0} Event `event 1` (0) + [350 10,350,000,000,000] {0 0 0} Packet end + [350 10,350,000,000,000] {0 0 0} Stream end + END + + run_test "" 10350 + + # Trim end after packet beginning + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [200 10,200,000,000,000] {0 0 0} Packet beginning + [250 10,250,000,000,000] {0 0 0} Packet end + [250 10,250,000,000,000] {0 0 0} Stream end + END + + run_test "" 10250 + + # Trim end after stream beginning + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [Unknown] {0 0 0} Stream end + END + + run_test "" 10150 + + # Trim end before everything + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [Unknown] {0 0 0} Stream end + END + + run_test "" 10050 + + # Trim end at a time before what the clock class can represent + cat <<- 'END' > $temp_expected + [Unknown] {0 0 0} Stream beginning + [Unknown] {0 0 0} Stream end + END + + run_test "" 50 +} + +test_with_stream_msg_cs +test_without_stream_msg_cs + +rm -f "$temp_expected" diff --git a/tests/plugins/flt.utils.trimmer/test_trimming_wrapper b/tests/plugins/flt.utils.trimmer/test_trimming_wrapper new file mode 100755 index 00000000..09817847 --- /dev/null +++ b/tests/plugins/flt.utils.trimmer/test_trimming_wrapper @@ -0,0 +1,34 @@ +#!/bin/bash +# +# Copyright (C) 2019 Simon Marchi +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; only version 2 +# of the License. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# This test validates that a `src.ctf.fs` component successfully reads +# specific CTF traces and creates the expected messages. +# +# Such CTF traces to open either exist (in `tests/ctf-traces/succeed`) +# or are generated by this test using local trace generators. + +if [ "x${BT_TESTS_SRCDIR:-}" != "x" ]; then + UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh" +else + UTILSSH="$(dirname "$0")/../../utils/utils.sh" +fi + +# shellcheck source=../../../utils/utils.sh +source "$UTILSSH" + +run_python_bt2 "$BT_TESTS_SRCDIR/plugins/flt.utils.trimmer/test_trimming" -- 2.34.1