mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 16:46:47 +00:00
Alignment part I - Interface and shmem send
This commit is contained in:
parent
20544e1f18
commit
53a4d17f8b
|
@ -17,11 +17,26 @@
|
||||||
using fairmq_free_fn = void(void* data, void* hint);
|
using fairmq_free_fn = void(void* data, void* hint);
|
||||||
class FairMQTransportFactory;
|
class FairMQTransportFactory;
|
||||||
|
|
||||||
|
namespace fair
|
||||||
|
{
|
||||||
|
namespace mq
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Alignment
|
||||||
|
{
|
||||||
|
size_t alignment;
|
||||||
|
explicit operator size_t() const { return alignment; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace mq */
|
||||||
|
} /* namespace fair */
|
||||||
|
|
||||||
class FairMQMessage
|
class FairMQMessage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FairMQMessage() = default;
|
FairMQMessage() = default;
|
||||||
FairMQMessage(FairMQTransportFactory* factory) : fTransport(factory) {}
|
FairMQMessage(FairMQTransportFactory* factory) : fTransport(factory) {}
|
||||||
|
|
||||||
virtual void Rebuild() = 0;
|
virtual void Rebuild() = 0;
|
||||||
virtual void Rebuild(const size_t size) = 0;
|
virtual void Rebuild(const size_t size) = 0;
|
||||||
virtual void Rebuild(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) = 0;
|
virtual void Rebuild(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) = 0;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <fairmq/Transports.h>
|
#include <fairmq/Transports.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory> // shared_ptr
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
@ -47,13 +47,22 @@ class FairMQTransportFactory
|
||||||
fair::mq::ChannelResource* GetMemoryResource() { return &fMemoryResource; }
|
fair::mq::ChannelResource* GetMemoryResource() { return &fMemoryResource; }
|
||||||
operator fair::mq::ChannelResource*() { return &fMemoryResource; }
|
operator fair::mq::ChannelResource*() { return &fMemoryResource; }
|
||||||
|
|
||||||
/// @brief Create empty FairMQMessage
|
/// @brief Create empty FairMQMessage (for receiving)
|
||||||
/// @return pointer to FairMQMessage
|
/// @return pointer to FairMQMessage
|
||||||
virtual FairMQMessagePtr CreateMessage() = 0;
|
virtual FairMQMessagePtr CreateMessage() = 0;
|
||||||
|
/// @brief Create empty FairMQMessage (for receiving), align received buffer to specified alignment
|
||||||
|
/// @param alignment alignment to align received buffer to
|
||||||
|
/// @return pointer to FairMQMessage
|
||||||
|
virtual FairMQMessagePtr CreateMessage(fair::mq::Alignment alignment) = 0;
|
||||||
/// @brief Create new FairMQMessage of specified size
|
/// @brief Create new FairMQMessage of specified size
|
||||||
/// @param size message size
|
/// @param size message size
|
||||||
/// @return pointer to FairMQMessage
|
/// @return pointer to FairMQMessage
|
||||||
virtual FairMQMessagePtr CreateMessage(const size_t size) = 0;
|
virtual FairMQMessagePtr CreateMessage(const size_t size) = 0;
|
||||||
|
/// @brief Create new FairMQMessage of specified size and alignment
|
||||||
|
/// @param size message size
|
||||||
|
/// @param alignment message alignment
|
||||||
|
/// @return pointer to FairMQMessage
|
||||||
|
virtual FairMQMessagePtr CreateMessage(const size_t size, fair::mq::Alignment alignment) = 0;
|
||||||
/// @brief Create new FairMQMessage with user provided buffer and size
|
/// @brief Create new FairMQMessage with user provided buffer and size
|
||||||
/// @param data pointer to user provided buffer
|
/// @param data pointer to user provided buffer
|
||||||
/// @param size size of the user provided buffer
|
/// @param size size of the user provided buffer
|
||||||
|
|
|
@ -34,6 +34,16 @@ Message::Message(boost::container::pmr::memory_resource* pmr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message::Message(boost::container::pmr::memory_resource* pmr, Alignment /* alignment */)
|
||||||
|
: fInitialSize(0)
|
||||||
|
, fSize(0)
|
||||||
|
, fData(nullptr)
|
||||||
|
, fFreeFunction(nullptr)
|
||||||
|
, fHint(nullptr)
|
||||||
|
, fPmr(pmr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Message::Message(boost::container::pmr::memory_resource* pmr, const size_t size)
|
Message::Message(boost::container::pmr::memory_resource* pmr, const size_t size)
|
||||||
: fInitialSize(size)
|
: fInitialSize(size)
|
||||||
, fSize(size)
|
, fSize(size)
|
||||||
|
@ -48,6 +58,20 @@ Message::Message(boost::container::pmr::memory_resource* pmr, const size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message::Message(boost::container::pmr::memory_resource* pmr, const size_t size, Alignment /* alignment */)
|
||||||
|
: fInitialSize(size)
|
||||||
|
, fSize(size)
|
||||||
|
, fData(nullptr)
|
||||||
|
, fFreeFunction(nullptr)
|
||||||
|
, fHint(nullptr)
|
||||||
|
, fPmr(pmr)
|
||||||
|
{
|
||||||
|
if (size) {
|
||||||
|
fData = fPmr->allocate(size);
|
||||||
|
assert(fData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Message::Message(boost::container::pmr::memory_resource* pmr,
|
Message::Message(boost::container::pmr::memory_resource* pmr,
|
||||||
void* data,
|
void* data,
|
||||||
const size_t size,
|
const size_t size,
|
||||||
|
|
|
@ -34,7 +34,9 @@ class Message final : public fair::mq::Message
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Message(boost::container::pmr::memory_resource* pmr);
|
Message(boost::container::pmr::memory_resource* pmr);
|
||||||
|
Message(boost::container::pmr::memory_resource* pmr, Alignment alignment);
|
||||||
Message(boost::container::pmr::memory_resource* pmr, const size_t size);
|
Message(boost::container::pmr::memory_resource* pmr, const size_t size);
|
||||||
|
Message(boost::container::pmr::memory_resource* pmr, const size_t size, Alignment alignment);
|
||||||
Message(boost::container::pmr::memory_resource* pmr,
|
Message(boost::container::pmr::memory_resource* pmr,
|
||||||
void* data,
|
void* data,
|
||||||
const size_t size,
|
const size_t size,
|
||||||
|
|
|
@ -41,11 +41,23 @@ auto TransportFactory::CreateMessage() -> MessagePtr
|
||||||
return MessagePtr{new Message(&fMemoryResource)};
|
return MessagePtr{new Message(&fMemoryResource)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto TransportFactory::CreateMessage(Alignment /* alignment */) -> MessagePtr
|
||||||
|
{
|
||||||
|
// TODO Do not ignore alignment
|
||||||
|
return MessagePtr{new Message(&fMemoryResource)};
|
||||||
|
}
|
||||||
|
|
||||||
auto TransportFactory::CreateMessage(const size_t size) -> MessagePtr
|
auto TransportFactory::CreateMessage(const size_t size) -> MessagePtr
|
||||||
{
|
{
|
||||||
return MessagePtr{new Message(&fMemoryResource, size)};
|
return MessagePtr{new Message(&fMemoryResource, size)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto TransportFactory::CreateMessage(const size_t size, Alignment /* alignment */) -> MessagePtr
|
||||||
|
{
|
||||||
|
// TODO Do not ignore alignment
|
||||||
|
return MessagePtr{new Message(&fMemoryResource, size)};
|
||||||
|
}
|
||||||
|
|
||||||
auto TransportFactory::CreateMessage(void* data,
|
auto TransportFactory::CreateMessage(void* data,
|
||||||
const size_t size,
|
const size_t size,
|
||||||
fairmq_free_fn* ffn,
|
fairmq_free_fn* ffn,
|
||||||
|
|
|
@ -36,7 +36,9 @@ class TransportFactory final : public FairMQTransportFactory
|
||||||
TransportFactory operator=(const TransportFactory&) = delete;
|
TransportFactory operator=(const TransportFactory&) = delete;
|
||||||
|
|
||||||
auto CreateMessage() -> MessagePtr override;
|
auto CreateMessage() -> MessagePtr override;
|
||||||
|
auto CreateMessage(Alignment alignment) -> MessagePtr override;
|
||||||
auto CreateMessage(const std::size_t size) -> MessagePtr override;
|
auto CreateMessage(const std::size_t size) -> MessagePtr override;
|
||||||
|
auto CreateMessage(const std::size_t size, Alignment alignment) -> MessagePtr override;
|
||||||
auto CreateMessage(void* data, const std::size_t size, fairmq_free_fn* ffn, void* hint = nullptr) -> MessagePtr override;
|
auto CreateMessage(void* data, const std::size_t size, fairmq_free_fn* ffn, void* hint = nullptr) -> MessagePtr override;
|
||||||
auto CreateMessage(UnmanagedRegionPtr& region, void* data, const std::size_t size, void* hint = nullptr) -> MessagePtr override;
|
auto CreateMessage(UnmanagedRegionPtr& region, void* data, const std::size_t size, void* hint = nullptr) -> MessagePtr override;
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,17 @@ class Message final : public fair::mq::Message
|
||||||
fManager.IncrementMsgCounter();
|
fManager.IncrementMsgCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message(Manager& manager, Alignment /* alignment */, FairMQTransportFactory* factory = nullptr)
|
||||||
|
: fair::mq::Message(factory)
|
||||||
|
, fManager(manager)
|
||||||
|
, fQueued(false)
|
||||||
|
, fMeta{0, 0, 0, -1}
|
||||||
|
, fRegionPtr(nullptr)
|
||||||
|
, fLocalPtr(nullptr)
|
||||||
|
{
|
||||||
|
fManager.IncrementMsgCounter();
|
||||||
|
}
|
||||||
|
|
||||||
Message(Manager& manager, const size_t size, FairMQTransportFactory* factory = nullptr)
|
Message(Manager& manager, const size_t size, FairMQTransportFactory* factory = nullptr)
|
||||||
: fair::mq::Message(factory)
|
: fair::mq::Message(factory)
|
||||||
, fManager(manager)
|
, fManager(manager)
|
||||||
|
@ -59,6 +70,18 @@ class Message final : public fair::mq::Message
|
||||||
fManager.IncrementMsgCounter();
|
fManager.IncrementMsgCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message(Manager& manager, const size_t size, Alignment alignment, FairMQTransportFactory* factory = nullptr)
|
||||||
|
: fair::mq::Message(factory)
|
||||||
|
, fManager(manager)
|
||||||
|
, fQueued(false)
|
||||||
|
, fMeta{0, 0, 0, -1}
|
||||||
|
, fRegionPtr(nullptr)
|
||||||
|
, fLocalPtr(nullptr)
|
||||||
|
{
|
||||||
|
InitializeChunk(size, static_cast<size_t>(alignment));
|
||||||
|
fManager.IncrementMsgCounter();
|
||||||
|
}
|
||||||
|
|
||||||
Message(Manager& manager, void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr, FairMQTransportFactory* factory = nullptr)
|
Message(Manager& manager, void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr, FairMQTransportFactory* factory = nullptr)
|
||||||
: fair::mq::Message(factory)
|
: fair::mq::Message(factory)
|
||||||
, fManager(manager)
|
, fManager(manager)
|
||||||
|
@ -219,19 +242,24 @@ class Message final : public fair::mq::Message
|
||||||
mutable Region* fRegionPtr;
|
mutable Region* fRegionPtr;
|
||||||
mutable char* fLocalPtr;
|
mutable char* fLocalPtr;
|
||||||
|
|
||||||
bool InitializeChunk(const size_t size)
|
bool InitializeChunk(const size_t size, size_t alignment = 0)
|
||||||
{
|
{
|
||||||
tools::RateLimiter rateLimiter(20);
|
tools::RateLimiter rateLimiter(20);
|
||||||
|
|
||||||
while (fMeta.fHandle < 0) {
|
while (fMeta.fHandle < 0) {
|
||||||
try {
|
try {
|
||||||
boost::interprocess::managed_shared_memory::size_type actualSize = size;
|
// boost::interprocess::managed_shared_memory::size_type actualSize = size;
|
||||||
char* hint = 0; // unused for boost::interprocess::allocate_new
|
// char* hint = 0; // unused for boost::interprocess::allocate_new
|
||||||
fLocalPtr = fManager.Segment().allocation_command<char>(boost::interprocess::allocate_new, size, actualSize, hint);
|
// fLocalPtr = fManager.Segment().allocation_command<char>(boost::interprocess::allocate_new, size, actualSize, hint);
|
||||||
|
if (alignment == 0) {
|
||||||
|
fLocalPtr = reinterpret_cast<char*>(fManager.Segment().allocate(size));
|
||||||
|
} else {
|
||||||
|
fLocalPtr = reinterpret_cast<char*>(fManager.Segment().allocate_aligned(size, alignment));
|
||||||
|
}
|
||||||
} catch (boost::interprocess::bad_alloc& ba) {
|
} catch (boost::interprocess::bad_alloc& ba) {
|
||||||
// LOG(warn) << "Shared memory full...";
|
// LOG(warn) << "Shared memory full...";
|
||||||
if (fManager.ThrowingOnBadAlloc()) {
|
if (fManager.ThrowingOnBadAlloc()) {
|
||||||
throw MessageBadAlloc(tools::ToString("shmem: could not create a message of size ", size));
|
throw MessageBadAlloc(tools::ToString("shmem: could not create a message of size ", size, ", alignment: ", (alignment != 0) ? std::to_string(alignment) : "default"));
|
||||||
}
|
}
|
||||||
rateLimiter.maybe_sleep();
|
rateLimiter.maybe_sleep();
|
||||||
if (fManager.Interrupted()) {
|
if (fManager.Interrupted()) {
|
||||||
|
|
|
@ -101,11 +101,21 @@ class TransportFactory final : public fair::mq::TransportFactory
|
||||||
return tools::make_unique<Message>(*fManager, this);
|
return tools::make_unique<Message>(*fManager, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessagePtr CreateMessage(Alignment alignment) override
|
||||||
|
{
|
||||||
|
return tools::make_unique<Message>(*fManager, alignment, this);
|
||||||
|
}
|
||||||
|
|
||||||
MessagePtr CreateMessage(const size_t size) override
|
MessagePtr CreateMessage(const size_t size) override
|
||||||
{
|
{
|
||||||
return tools::make_unique<Message>(*fManager, size, this);
|
return tools::make_unique<Message>(*fManager, size, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessagePtr CreateMessage(const size_t size, Alignment alignment) override
|
||||||
|
{
|
||||||
|
return tools::make_unique<Message>(*fManager, size, alignment, this);
|
||||||
|
}
|
||||||
|
|
||||||
MessagePtr CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) override
|
MessagePtr CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) override
|
||||||
{
|
{
|
||||||
return tools::make_unique<Message>(*fManager, data, size, ffn, hint, this);
|
return tools::make_unique<Message>(*fManager, data, size, ffn, hint, this);
|
||||||
|
|
|
@ -47,6 +47,17 @@ class Message final : public fair::mq::Message
|
||||||
LOG(error) << "failed initializing message, reason: " << zmq_strerror(errno);
|
LOG(error) << "failed initializing message, reason: " << zmq_strerror(errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message(Alignment /* alignment */, FairMQTransportFactory* factory = nullptr)
|
||||||
|
: fair::mq::Message(factory)
|
||||||
|
, fUsedSizeModified(false)
|
||||||
|
, fUsedSize()
|
||||||
|
, fMsg(tools::make_unique<zmq_msg_t>())
|
||||||
|
, fViewMsg(nullptr)
|
||||||
|
{
|
||||||
|
if (zmq_msg_init(fMsg.get()) != 0) {
|
||||||
|
LOG(error) << "failed initializing message, reason: " << zmq_strerror(errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Message(const size_t size, FairMQTransportFactory* factory = nullptr)
|
Message(const size_t size, FairMQTransportFactory* factory = nullptr)
|
||||||
: fair::mq::Message(factory)
|
: fair::mq::Message(factory)
|
||||||
|
@ -60,6 +71,18 @@ class Message final : public fair::mq::Message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message(const size_t size, Alignment /* alignment */, FairMQTransportFactory* factory = nullptr)
|
||||||
|
: fair::mq::Message(factory)
|
||||||
|
, fUsedSizeModified(false)
|
||||||
|
, fUsedSize(size)
|
||||||
|
, fMsg(tools::make_unique<zmq_msg_t>())
|
||||||
|
, fViewMsg(nullptr)
|
||||||
|
{
|
||||||
|
if (zmq_msg_init_size(fMsg.get(), size) != 0) {
|
||||||
|
LOG(error) << "failed initializing message with size, reason: " << zmq_strerror(errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Message(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr, FairMQTransportFactory* factory = nullptr)
|
Message(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr, FairMQTransportFactory* factory = nullptr)
|
||||||
: fair::mq::Message(factory)
|
: fair::mq::Message(factory)
|
||||||
, fUsedSizeModified(false)
|
, fUsedSizeModified(false)
|
||||||
|
|
|
@ -56,11 +56,21 @@ class TransportFactory final : public FairMQTransportFactory
|
||||||
return tools::make_unique<Message>(this);
|
return tools::make_unique<Message>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessagePtr CreateMessage(Alignment alignment) override
|
||||||
|
{
|
||||||
|
return tools::make_unique<Message>(alignment, this);
|
||||||
|
}
|
||||||
|
|
||||||
MessagePtr CreateMessage(const size_t size) override
|
MessagePtr CreateMessage(const size_t size) override
|
||||||
{
|
{
|
||||||
return tools::make_unique<Message>(size, this);
|
return tools::make_unique<Message>(size, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessagePtr CreateMessage(const size_t size, Alignment alignment) override
|
||||||
|
{
|
||||||
|
return tools::make_unique<Message>(size, alignment, this);
|
||||||
|
}
|
||||||
|
|
||||||
MessagePtr CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) override
|
MessagePtr CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) override
|
||||||
{
|
{
|
||||||
return tools::make_unique<Message>(data, size, ffn, hint, this);
|
return tools::make_unique<Message>(data, size, ffn, hint, this);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -77,6 +78,19 @@ void RunMsgRebuild(const string& transport)
|
||||||
EXPECT_EQ(string(static_cast<char*>(msg->GetData()), msg->GetSize()), string("asdf"));
|
EXPECT_EQ(string(static_cast<char*>(msg->GetData()), msg->GetSize()), string("asdf"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Alignment(const string& transport)
|
||||||
|
{
|
||||||
|
size_t session{fair::mq::tools::UuidHash()};
|
||||||
|
|
||||||
|
fair::mq::ProgOptions config;
|
||||||
|
config.SetProperty<string>("session", to_string(session));
|
||||||
|
|
||||||
|
auto factory = FairMQTransportFactory::CreateTransportFactory(transport, fair::mq::tools::Uuid(), &config);
|
||||||
|
|
||||||
|
FairMQMessagePtr msg(factory->CreateMessage(100, fair::mq::Alignment{64}));
|
||||||
|
ASSERT_EQ(reinterpret_cast<uintptr_t>(msg->GetData()) % 64, 0);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Resize, zeromq)
|
TEST(Resize, zeromq)
|
||||||
{
|
{
|
||||||
RunPushPullWithMsgResize("zeromq", "ipc://test_message_resize");
|
RunPushPullWithMsgResize("zeromq", "ipc://test_message_resize");
|
||||||
|
@ -97,4 +111,9 @@ TEST(Rebuild, shmem)
|
||||||
RunMsgRebuild("shmem");
|
RunMsgRebuild("shmem");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Alignment, shmem) // TODO: add test for ZeroMQ once it is implemented
|
||||||
|
{
|
||||||
|
Alignment("shmem");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue
Block a user