#include <babeltrace2/babeltrace.h>
-#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"
oldestUpstreamMsgIter.portName());
try {
- if (G_LIKELY(oldestUpstreamMsgIter.reload() == UpstreamMsgIter::ReloadStatus::MORE)) {
+ if (G_LIKELY(oldestUpstreamMsgIter.reload() == UpstreamMsgIter::ReloadStatus::More)) {
/* New current message: update heap */
_mHeap.replaceTop(&oldestUpstreamMsgIter);
BT_CPPLOGD("More messages available; updated heap: port-name={}, heap-len={}",
"port-name={}, heap-len={}, to-reload-len={}",
upstreamMsgIter.portName(), _mHeap.len(), _mUpstreamMsgItersToReload.size());
- if (G_LIKELY(upstreamMsgIter.reload() == UpstreamMsgIter::ReloadStatus::MORE)) {
+ if (G_LIKELY(upstreamMsgIter.reload() == UpstreamMsgIter::ReloadStatus::More)) {
/* New current message: move to heap */
_mHeap.insert(&upstreamMsgIter);
BT_CPPLOGD("More messages available; "
_mHeap.clear();
_mUpstreamMsgItersToReload.clear();
- /* Also reset clock class expectation */
- _mClkClsExpectation = _ClkClsExpectation::ANY;
- _mExpectedClkClsUuid.reset();
-
/* Make each upstream message iterator seek */
for (auto& upstreamMsgIter : _mUpstreamMsgIters) {
/* This may throw! */
}
}
-namespace {
-
-const char *msgTypeStr(const bt2::ConstMessage msg) noexcept
-{
- return bt_common_message_type_string(static_cast<bt_message_type>(msg.type()));
-}
-
-std::string optLogStr(const char * const str) noexcept
-{
- return str ? fmt::format("\"{}\"", str) : "(none)";
-}
-
-} /* namespace */
-
-void MsgIter::_setClkClsExpectation(
- const bt2::OptionalBorrowedObject<bt2::ConstClockClass> 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;
- }
- }
-}
+ BT_CPPLOGD("Validating the clock class of a message: msg-type={}", msg.type());
-void MsgIter::_makeSureClkClsIsExpected(
- const bt2::ConstMessage msg,
- const bt2::OptionalBorrowedObject<bt2::ConstClockClass> 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::ExpectingNoClockClassGotOne:
+ 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::ExpectingOriginUnixGotNone:
+ case Type::ExpectingOriginUuidGotNone:
+ case Type::ExpectingOriginNoUuidGotNone:
+ {
+ 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<const void *>(streamCls.libObjPtr()),
- optLogStr(streamCls.name()), streamCls.id());
+ fmt::ptr(streamCls.libObjPtr()), streamCls.name(),
+ streamCls.id());
}
- return;
- }
-
- const auto clkClsAddr = static_cast<const void *>(clkCls->libObjPtr());
-
- switch (_mClkClsExpectation) {
- case _ClkClsExpectation::ORIG_IS_UNIX_EPOCH:
- if (!clkCls->originIsUnixEpoch()) {
+ case Type::ExpectingOriginUnixGotOther:
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()));
- }
+ fmt::ptr(actualClockCls->libObjPtr()),
+ actualClockCls->name());
- break;
- case _ClkClsExpectation::ORIG_ISNT_UNIX_EPOCH_AND_NO_UUID:
- BT_ASSERT_DBG(!_mExpectedClkClsUuid);
-
- if (clkCls->originIsUnixEpoch()) {
+ case Type::ExpectingOriginUuidGotUnix:
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()));
- }
-
- if (clkCls->uuid()) {
- BT_CPPLOGE_APPEND_CAUSE_AND_THROW(
- bt2::Error,
- "Expecting a clock class without a UUID, but got one with a UUID: "
- "clock-class-addr={}, clock-class-name={}, uuid={}",
- clkClsAddr, optLogStr(clkCls->name()), clkCls->uuid()->str());
- }
-
- break;
- case _ClkClsExpectation::ORIG_ISNT_UNIX_EPOCH_AND_SPEC_UUID:
- BT_ASSERT_DBG(_mExpectedClkClsUuid);
+ fmt::ptr(actualClockCls->libObjPtr()), actualClockCls->name());
- if (clkCls->originIsUnixEpoch()) {
- 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()));
- }
-
- if (!clkCls->uuid()) {
+ case Type::ExpectingOriginUuidGotNoUuid:
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::ExpectingOriginUuidGotOtherUuid:
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());
- }
+ fmt::ptr(actualClockCls->libObjPtr()),
+ actualClockCls->name(), *error.expectedUuid(),
+ *actualClockCls->uuid());
- 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;
- }
-
- BT_CPPLOGD("Validating the clock class of a message: msg-type={}", msgTypeStr(msg));
+ case Type::ExpectingOriginNoUuidGotOther:
+ {
+ const auto expectedClockCls = error.expectedClockCls();
- /* Get the clock class, if any, of `msg` */
- const auto clkCls = bt2c::call([msg]() -> bt2::OptionalBorrowedObject<bt2::ConstClockClass> {
- if (msg.isStreamBeginning()) {
- return msg.asStreamBeginning().stream().cls().defaultClockClass();
- } 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);
}
}
BT_CPPLOGT("Comparing two messages: "
"port-name-a={}, msg-a-type={}, msg-a-ts={}, "
"port-name-b={}, msg-b-type={}, msg-b-ts={}",
- upstreamMsgIterA->portName(), msgTypeStr(msgA), optMsgTsStr(msgTsA),
- upstreamMsgIterB->portName(), msgTypeStr(msgB), optMsgTsStr(msgTsB));
+ upstreamMsgIterA->portName(), msgA.type(), optMsgTsStr(msgTsA),
+ upstreamMsgIterB->portName(), msgB.type(), optMsgTsStr(msgTsB));
}
/*