/******************************************************************************** * Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * * This software is distributed under the terms of the * * GNU Lesser General Public Licence (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ #ifndef FAIR_MQ_OFI_CONTROLMESSAGES_H #define FAIR_MQ_OFI_CONTROLMESSAGES_H #include #include #include #include #include #include #include namespace asio { template auto buffer(const PodType& obj) -> asio::const_buffer { return asio::const_buffer(static_cast(&obj), sizeof(PodType)); } } // namespace asio namespace fair::mq::ofi { enum class ControlMessageType { Empty = 1, PostBuffer, PostMultiPartStartBuffer }; struct Empty {}; struct PostBuffer { uint64_t size; // buffer size (size_t) }; struct PostMultiPartStartBuffer { uint32_t numParts; // buffer size (size_t) uint64_t size; // buffer size (size_t) }; union ControlMessageContent { PostBuffer postBuffer; PostMultiPartStartBuffer postMultiPartStartBuffer; }; struct ControlMessage { ControlMessageType type; ControlMessageContent msg; }; template using unique_ptr = std::unique_ptr>; template auto MakeControlMessageWithPmr(std::pmr::memory_resource& pmr, Args&&... args) -> ofi::unique_ptr { void* mem = pmr.allocate(sizeof(ControlMessage)); ControlMessage* ctrl = new (mem) ControlMessage(); if (std::is_same::value) { ctrl->type = ControlMessageType::PostBuffer; ctrl->msg.postBuffer = PostBuffer(std::forward(args)...); } else if (std::is_same::value) { ctrl->type = ControlMessageType::PostMultiPartStartBuffer; ctrl->msg.postMultiPartStartBuffer = PostMultiPartStartBuffer(std::forward(args)...); } else if (std::is_same::value) { ctrl->type = ControlMessageType::Empty; } return ofi::unique_ptr(ctrl, [&pmr](ControlMessage* p) { p->~ControlMessage(); pmr.deallocate(p, sizeof(T)); }); } template auto MakeControlMessage(Args&&... args) -> ControlMessage { ControlMessage ctrl; if (std::is_same::value) { ctrl.type = ControlMessageType::PostBuffer; } else if (std::is_same::value) { ctrl.type = ControlMessageType::PostMultiPartStartBuffer; } else if (std::is_same::value) { ctrl.type = ControlMessageType::Empty; } ctrl.msg = T(std::forward(args)...); return ctrl; } } // namespace fair::mq::ofi #endif /* FAIR_MQ_OFI_CONTROLMESSAGES_H */