From df8863ad5159ab802e0f6b06df0428e61176ec8f Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Tue, 12 Mar 2024 17:24:12 -0400 Subject: [PATCH] flt.utils.muxer: use clock correlation validator Change the clock correlation validation code in `flt.utils.muxer` to use the clock correlation validation library. Change-Id: I5452f530de5fb035f66da5fc6f63bba48711e503 Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/11991 Reviewed-by: Philippe Proulx Tested-by: jenkins --- src/Makefile.am | 3 +- src/plugins/utils/muxer/msg-iter.cpp | 189 ++++++++------------------- src/plugins/utils/muxer/msg-iter.hpp | 44 +------ 3 files changed, 56 insertions(+), 180 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 0cf75990..2d18268c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -642,7 +642,8 @@ plugins_utils_babeltrace_plugin_utils_la_LIBADD += \ common/libcommon.la \ cpp-common/vendor/fmt/libfmt.la \ logging/liblogging.la \ - plugins/common/param-validation/libparam-validation.la + plugins/common/param-validation/libparam-validation.la \ + clock-correlation-validator/libclock-correlation-validator.la endif # ctf plugin diff --git a/src/plugins/utils/muxer/msg-iter.cpp b/src/plugins/utils/muxer/msg-iter.cpp index 99ffdeb2..b1d86945 100644 --- a/src/plugins/utils/muxer/msg-iter.cpp +++ b/src/plugins/utils/muxer/msg-iter.cpp @@ -10,8 +10,6 @@ #include -#include "common/common.h" -#include "cpp-common/bt2c/call.hpp" #include "cpp-common/bt2c/fmt.hpp" #include "cpp-common/bt2s/make-unique.hpp" #include "cpp-common/vendor/fmt/format.h" @@ -234,179 +232,94 @@ void MsgIter::_seekBeginning() } } -namespace { - -std::string optLogStr(const char * const str) noexcept -{ - return str ? fmt::format("\"{}\"", str) : "(none)"; -} - -} /* namespace */ - -void MsgIter::_setClkClsExpectation( - const bt2::OptionalBorrowedObject clkCls) noexcept +void MsgIter::_validateMsgClkCls(const bt2::ConstMessage msg) { - BT_ASSERT_DBG(_mClkClsExpectation == _ClkClsExpectation::ANY); - - /* No initial clock class: also expect none afterwards */ - if (!clkCls) { - _mClkClsExpectation = _ClkClsExpectation::NONE; + if (G_LIKELY(!msg.isStreamBeginning() && !msg.isMessageIteratorInactivity())) { + /* + * We don't care about the other types: all the messages related + * to a given stream shared the same default clock class, if + * any. + */ return; } - /* - * This is the first clock class that this message iterator - * encounters. Its properties determine what to expect for the whole - * lifetime of the iterator. - */ - if (clkCls->originIsUnixEpoch()) { - /* Expect clock classes having a Unix epoch origin*/ - _mClkClsExpectation = _ClkClsExpectation::ORIG_IS_UNIX_EPOCH; - } else { - if (clkCls->uuid()) { - /* - * Expect clock classes not having a Unix epoch origin and - * with a specific UUID. - */ - _mClkClsExpectation = _ClkClsExpectation::ORIG_ISNT_UNIX_EPOCH_AND_SPEC_UUID; - _mExpectedClkClsUuid = *clkCls->uuid(); - } else { - /* - * Expect clock classes not having a Unix epoch origin and - * without a UUID. - */ - _mClkClsExpectation = _ClkClsExpectation::ORIG_ISNT_UNIX_EPOCH_AND_NO_UUID; - _mExpectedClkCls = clkCls->shared(); - } - } -} + BT_CPPLOGD("Validating the clock class of a message: msg-type={}", msg.type()); -void MsgIter::_makeSureClkClsIsExpected( - const bt2::ConstMessage msg, - const bt2::OptionalBorrowedObject clkCls) const -{ - BT_ASSERT_DBG(_mClkClsExpectation != _ClkClsExpectation::ANY); + try { + _mClkCorrValidator.validate(msg); + } catch (const bt2ccv::ClockCorrelationError& error) { + using Type = bt2ccv::ClockCorrelationError::Type; - if (!clkCls) { - if (_mClkClsExpectation != _ClkClsExpectation::NONE) { - /* - * `msg` is a stream beginning message because a message - * iterator inactivity message always has a clock class. - */ - const auto streamCls = msg.asStreamBeginning().stream().cls(); + const auto actualClockCls = error.actualClockCls(); + + switch (error.type()) { + case Type::EXPECTING_NO_CLOCK_CLASS_GOT_ONE: + BT_CPPLOGE_APPEND_CAUSE_AND_THROW(bt2::Error, + "Expecting no clock class, but got one: " + "clock-class-addr={}, clock-class-name={}", + fmt::ptr(actualClockCls->libObjPtr()), + actualClockCls->name()); + + case Type::EXPECTING_ORIGIN_UNIX_GOT_NONE: + case Type::EXPECTING_ORIGIN_UUID_GOT_NONE: + case Type::EXPECTING_ORIGIN_NO_UUID_GOT_NONE: + { + const auto streamCls = *error.streamCls(); BT_CPPLOGE_APPEND_CAUSE_AND_THROW(bt2::Error, "Expecting a clock class, but got none: " "stream-class-addr={}, stream-class-name=\"{}\", " "stream-class-id={}", - static_cast(streamCls.libObjPtr()), - optLogStr(streamCls.name()), streamCls.id()); + fmt::ptr(streamCls.libObjPtr()), streamCls.name(), + streamCls.id()); } - return; - } - - const auto clkClsAddr = static_cast(clkCls->libObjPtr()); - - switch (_mClkClsExpectation) { - case _ClkClsExpectation::ORIG_IS_UNIX_EPOCH: - if (!clkCls->originIsUnixEpoch()) { + case Type::EXPECTING_ORIGIN_UNIX_GOT_OTHER: BT_CPPLOGE_APPEND_CAUSE_AND_THROW(bt2::Error, "Expecting a clock class having a Unix epoch origin, " "but got one not having a Unix epoch origin: " "clock-class-addr={}, clock-class-name={}", - clkClsAddr, optLogStr(clkCls->name())); - } - - break; - case _ClkClsExpectation::ORIG_ISNT_UNIX_EPOCH_AND_NO_UUID: - BT_ASSERT_DBG(!_mExpectedClkClsUuid); - BT_ASSERT_DBG(_mExpectedClkCls); - - if (clkCls->libObjPtr() != _mExpectedClkCls->libObjPtr()) { - BT_CPPLOGE_APPEND_CAUSE_AND_THROW( - bt2::Error, - "Unexpected clock class: " - "expected-clock-class-addr={}, expected-clock-class-name={}, " - "actual-clock-class-addr={}, actual-clock-class-name={}", - fmt::ptr(_mExpectedClkCls->libObjPtr()), optLogStr(_mExpectedClkCls->name()), - clkClsAddr, optLogStr(clkCls->name())); - } - - break; - case _ClkClsExpectation::ORIG_ISNT_UNIX_EPOCH_AND_SPEC_UUID: - BT_ASSERT_DBG(_mExpectedClkClsUuid); - BT_ASSERT_DBG(!_mExpectedClkCls); + fmt::ptr(actualClockCls->libObjPtr()), + actualClockCls->name()); - if (clkCls->originIsUnixEpoch()) { + case Type::EXPECTING_ORIGIN_UUID_GOT_UNIX: BT_CPPLOGE_APPEND_CAUSE_AND_THROW( bt2::Error, "Expecting a clock class not having a Unix epoch origin, " "but got one having a Unix epoch origin: " "clock-class-addr={}, clock-class-name={}", - clkClsAddr, optLogStr(clkCls->name())); - } + fmt::ptr(actualClockCls->libObjPtr()), actualClockCls->name()); - if (!clkCls->uuid()) { + case Type::EXPECTING_ORIGIN_UUID_GOT_NO_UUID: BT_CPPLOGE_APPEND_CAUSE_AND_THROW( bt2::Error, "Expecting a clock class with a UUID, but got one without a UUID: " "clock-class-addr={}, clock-class-name={}", - clkClsAddr, optLogStr(clkCls->name())); - } + fmt::ptr(actualClockCls->libObjPtr()), actualClockCls->name()); - if (*clkCls->uuid() != bt2c::UuidView {*_mExpectedClkClsUuid}) { + case Type::EXPECTING_ORIGIN_UUID_GOT_OTHER_UUID: BT_CPPLOGE_APPEND_CAUSE_AND_THROW(bt2::Error, "Expecting a clock class with a specific UUID, " "but got one with a different UUID: " "clock-class-addr={}, clock-class-name={}, " "expected-uuid=\"{}\", uuid=\"{}\"", - clkClsAddr, optLogStr(clkCls->name()), - _mExpectedClkClsUuid->str(), clkCls->uuid()->str()); - } - - break; - case _ClkClsExpectation::NONE: - BT_CPPLOGE_APPEND_CAUSE_AND_THROW(bt2::Error, - "Expecting no clock class, but got one: " - "clock-class-addr={}, clock-class-name={}", - clkClsAddr, optLogStr(clkCls->name())); - break; - default: - bt_common_abort(); - } -} - -void MsgIter::_validateMsgClkCls(const bt2::ConstMessage msg) -{ - if (G_LIKELY(!msg.isStreamBeginning() && !msg.isMessageIteratorInactivity())) { - /* - * We don't care about the other types: all the messages related - * to a given stream shared the same default clock class, if - * any. - */ - return; - } + fmt::ptr(actualClockCls->libObjPtr()), + actualClockCls->name(), *error.expectedUuid(), + *actualClockCls->uuid()); - BT_CPPLOGD("Validating the clock class of a message: msg-type={}", msg.type()); + case Type::EXPECTING_ORIGIN_NO_UUID_GOT_OTHER: + { + const auto expectedClockCls = error.expectedClockCls(); - /* Get the clock class, if any, of `msg` */ - const auto clkCls = bt2c::call([msg]() -> bt2::OptionalBorrowedObject { - if (msg.isStreamBeginning()) { - return msg.asStreamBeginning().streamClassDefaultClockClass(); - } else { - BT_ASSERT(msg.isMessageIteratorInactivity()); - return msg.asMessageIteratorInactivity().clockSnapshot().clockClass(); + BT_CPPLOGE_APPEND_CAUSE_AND_THROW( + bt2::Error, + "Unexpected clock class: " + "expected-clock-class-addr={}, expected-clock-class-name={}, " + "actual-clock-class-addr={}, actual-clock-class-name={}", + fmt::ptr(expectedClockCls->libObjPtr()), expectedClockCls->name(), + fmt::ptr(actualClockCls->libObjPtr()), actualClockCls->name()); + } } - }); - - /* Set the expectation or check it */ - if (_mClkClsExpectation == _ClkClsExpectation::ANY) { - /* First message: set the expectation */ - this->_setClkClsExpectation(clkCls); - } else { - /* Make sure clock class is expected */ - this->_makeSureClkClsIsExpected(msg, clkCls); } } diff --git a/src/plugins/utils/muxer/msg-iter.hpp b/src/plugins/utils/muxer/msg-iter.hpp index d8c33c37..73620b5e 100644 --- a/src/plugins/utils/muxer/msg-iter.hpp +++ b/src/plugins/utils/muxer/msg-iter.hpp @@ -11,12 +11,10 @@ #include #include "cpp-common/bt2/component-class-dev.hpp" -#include "cpp-common/bt2/optional-borrowed-object.hpp" #include "cpp-common/bt2/self-message-iterator-configuration.hpp" #include "cpp-common/bt2c/prio-heap.hpp" -#include "cpp-common/bt2c/uuid.hpp" -#include "cpp-common/bt2s/optional.hpp" +#include "clock-correlation-validator/clock-correlation-validator.hpp" #include "upstream-msg-iter.hpp" namespace bt2mux { @@ -28,16 +26,6 @@ class MsgIter final : public bt2::UserMessageIterator friend bt2::UserMessageIterator; private: - /* Clock class nature expectation */ - enum class _ClkClsExpectation - { - ANY, - NONE, - ORIG_IS_UNIX_EPOCH, - ORIG_ISNT_UNIX_EPOCH_AND_SPEC_UUID, - ORIG_ISNT_UNIX_EPOCH_AND_NO_UUID, - }; - /* Comparator for `_mHeap` with its own logger */ class _HeapComparator final { @@ -77,19 +65,6 @@ private: */ void _validateMsgClkCls(bt2::ConstMessage msg); - /* - * Sets the clock class expectation (`_mClkClsExpectation` and - * `_mExpectedClkClsUuid`) according to `clkCls`. - */ - void _setClkClsExpectation(bt2::OptionalBorrowedObject clkCls) noexcept; - - /* - * Checks that `clkCls` meets the current clock class expectation, - * throwing if it doesn't. - */ - void _makeSureClkClsIsExpected(bt2::ConstMessage msg, - bt2::OptionalBorrowedObject clkCls) const; - /* * Container of all the upstream message iterators. * @@ -115,21 +90,8 @@ private: */ std::vector _mUpstreamMsgItersToReload; - /* - * Which kind of clock class to expect from any incoming message. - * - * The very first received message determines this for all the - * following. - * - * For `ORIG_ISNT_UNIX_EPOCH_AND_SPEC_UUID`, `*_mExpectedClkClsUuid` - * is the expected specific UUID. - * - * For `ORIG_ISNT_UNIX_EPOCH_AND_NO_UUID`, `_mExpectedClkCls` is the - * expected clock class. - */ - _ClkClsExpectation _mClkClsExpectation = _ClkClsExpectation::ANY; - bt2s::optional _mExpectedClkClsUuid; - bt2::ConstClockClass::Shared _mExpectedClkCls; + /* Clock class correlation validator */ + bt2ccv::ClockCorrelationValidator _mClkCorrValidator; }; } /* namespace bt2mux */ -- 2.34.1