From 14d33b5a3557209b9958c3accecd2f6f676b339b Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Wed, 14 Feb 2024 11:11:43 -0500 Subject: [PATCH] cpp-common/bt2: add C++ graph bindings Add C++ bindings to create and manipulate graphs. Create `bt2::Graph` objects with the `bt2::Graph::create()` static method. Add components to graphs with the `bt2::Graph::addComponent()` methods. There are overloads of this methods for sources, filters and sinks, and with and without initialization data. Connect ports with the `bt2::Graph::connectPorts()` method. The method does not (yet) provide access to the connection object returned by the lib. Run a graph with `bt2::Graph::run()` or `bt2::Graph::run_once()`. Change-Id: I92719f9dd6e8c77ded20d1bb4a5ddd2a03e8cf0d Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/11806 Reviewed-by: Philippe Proulx --- src/Makefile.am | 1 + src/cpp-common/bt2/graph.hpp | 185 +++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 src/cpp-common/bt2/graph.hpp diff --git a/src/Makefile.am b/src/Makefile.am index b226abee..01ae18b5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -120,6 +120,7 @@ cpp_common_libcpp_common_la_SOURCES = \ cpp-common/bt2/component-class-dev.hpp \ cpp-common/bt2/component-class.hpp \ cpp-common/bt2/component-port.hpp \ + cpp-common/bt2/graph.hpp \ cpp-common/bt2/exc.hpp \ cpp-common/bt2/field-class.hpp \ cpp-common/bt2/field-path.hpp \ diff --git a/src/cpp-common/bt2/graph.hpp b/src/cpp-common/bt2/graph.hpp new file mode 100644 index 00000000..787888af --- /dev/null +++ b/src/cpp-common/bt2/graph.hpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2024 EfficiOS, Inc. + * + * SPDX-License-Identifier: MIT + */ + +#ifndef BABELTRACE_CPP_COMMON_BT2_GRAPH_HPP +#define BABELTRACE_CPP_COMMON_BT2_GRAPH_HPP + +#include + +#include + +#include "borrowed-object.hpp" +#include "component-class.hpp" +#include "exc.hpp" +#include "shared-object.hpp" + +namespace bt2 { +namespace internal { + +struct GraphRefFuncs final +{ + static void get(const bt_graph * const libObjPtr) noexcept + { + bt_graph_get_ref(libObjPtr); + } + + static void put(const bt_graph * const libObjPtr) noexcept + { + bt_graph_put_ref(libObjPtr); + } +}; + +} /* namespace internal */ + +class Graph final : public BorrowedObject +{ +public: + using Shared = SharedObject; + + explicit Graph(const LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr} + { + } + + static Shared create(const std::uint64_t mipVersion) + { + const auto libObjPtr = bt_graph_create(mipVersion); + + if (!libObjPtr) { + throw MemoryError {}; + } + + return Shared::createWithoutRef(libObjPtr); + } + + ConstSourceComponent addComponent(const ConstSourceComponentClass componentClass, + const bt2c::CStringView name, + const OptionalBorrowedObject params = {}, + const LoggingLevel loggingLevel = LoggingLevel::NONE) const + { + return this->_addComponent( + componentClass, name, params, static_cast(nullptr), loggingLevel, + bt_graph_add_source_component_with_initialize_method_data); + } + + template + ConstSourceComponent addComponent(const ConstSourceComponentClass componentClass, + const bt2c::CStringView name, InitDataT& initData, + const OptionalBorrowedObject params = {}, + const LoggingLevel loggingLevel = LoggingLevel::NONE) const + { + return this->_addComponent( + componentClass, name, params, &initData, loggingLevel, + bt_graph_add_source_component_with_initialize_method_data); + } + + ConstFilterComponent addComponent(const ConstFilterComponentClass componentClass, + const bt2c::CStringView name, + const OptionalBorrowedObject params = {}, + const LoggingLevel loggingLevel = LoggingLevel::NONE) const + { + return this->_addComponent( + componentClass, name, params, static_cast(nullptr), loggingLevel, + bt_graph_add_filter_component_with_initialize_method_data); + } + + template + ConstFilterComponent addComponent(const ConstFilterComponentClass componentClass, + const bt2c::CStringView name, InitDataT& initData, + const OptionalBorrowedObject params = {}, + const LoggingLevel loggingLevel = LoggingLevel::NONE) const + { + return this->_addComponent( + componentClass, name, params, &initData, loggingLevel, + bt_graph_add_filter_component_with_initialize_method_data); + } + + ConstSinkComponent addComponent(const ConstSinkComponentClass componentClass, + const bt2c::CStringView name, + const OptionalBorrowedObject params = {}, + const LoggingLevel loggingLevel = LoggingLevel::NONE) const + { + return this->_addComponent( + componentClass, name, params, static_cast(nullptr), loggingLevel, + bt_graph_add_sink_component_with_initialize_method_data); + } + + template + ConstSinkComponent addComponent(const ConstSinkComponentClass componentClass, + const bt2c::CStringView name, InitDataT& initData, + const OptionalBorrowedObject params = {}, + const LoggingLevel loggingLevel = LoggingLevel::NONE) const + { + return this->_addComponent( + componentClass, name, params, &initData, loggingLevel, + bt_graph_add_sink_component_with_initialize_method_data); + } + + void connectPorts(const ConstOutputPort outputPort, const ConstInputPort inputPort) const + { + const auto status = bt_graph_connect_ports(this->libObjPtr(), outputPort.libObjPtr(), + inputPort.libObjPtr(), nullptr); + + if (status == BT_GRAPH_CONNECT_PORTS_STATUS_ERROR) { + throw Error {}; + } else if (status == BT_GRAPH_CONNECT_PORTS_STATUS_MEMORY_ERROR) { + throw MemoryError {}; + } + } + + void runOnce() const + { + const auto status = bt_graph_run_once(this->libObjPtr()); + + if (status == BT_GRAPH_RUN_ONCE_STATUS_ERROR) { + throw Error {}; + } else if (status == BT_GRAPH_RUN_ONCE_STATUS_MEMORY_ERROR) { + throw MemoryError {}; + } else if (status == BT_GRAPH_RUN_ONCE_STATUS_AGAIN) { + throw TryAgain {}; + } + } + + void run() const + { + const auto status = bt_graph_run(this->libObjPtr()); + + if (status == BT_GRAPH_RUN_STATUS_ERROR) { + throw Error {}; + } else if (status == BT_GRAPH_RUN_STATUS_MEMORY_ERROR) { + throw MemoryError {}; + } else if (status == BT_GRAPH_RUN_STATUS_AGAIN) { + throw TryAgain {}; + } + } + +private: + template + ConstComponentT + _addComponent(const ConstComponentClassT componentClass, const bt2c::CStringView name, + const OptionalBorrowedObject params, InitDataT * const initData, + const LoggingLevel loggingLevel, AddFuncT&& addFunc) const + { + typename ConstComponentT::LibObjPtr libObjPtr = nullptr; + + const auto status = addFunc(this->libObjPtr(), componentClass.libObjPtr(), name, + params ? params->libObjPtr() : nullptr, + const_cast(static_cast(initData)), + static_cast(loggingLevel), &libObjPtr); + + if (status == BT_GRAPH_ADD_COMPONENT_STATUS_ERROR) { + throw Error {}; + } else if (status == BT_GRAPH_ADD_COMPONENT_STATUS_MEMORY_ERROR) { + throw MemoryError {}; + } + + return wrap(libObjPtr); + } +}; + +} /* namespace bt2 */ + +#endif /* BABELTRACE_CPP_COMMON_BT2_GRAPH_HPP */ -- 2.34.1