Project
Loading...
Searching...
No Matches
MemoryResources.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
23
27
28#ifndef ALICEO2_MEMORY_RESOURCES_
29#define ALICEO2_MEMORY_RESOURCES_
30
31#include <boost/container/pmr/memory_resource.hpp>
32#include <boost/container/pmr/monotonic_buffer_resource.hpp>
33#include <boost/container/pmr/polymorphic_allocator.hpp>
34#include <cstring>
35#include <string>
36#include <type_traits>
37#include <utility>
38#include <vector>
39#include <unordered_map>
40#include <fairmq/Message.h>
41#include <fairmq/TransportFactory.h>
42#include <fairmq/MemoryResources.h>
43#include <fairmq/MemoryResourceTools.h>
44
45namespace o2::pmr
46{
47
48using FairMQMemoryResource = fair::mq::MemoryResource;
49using ChannelResource = fair::mq::ChannelResource;
50using namespace fair::mq::pmr;
51
52template <typename ContainerT>
53fair::mq::MessagePtr getMessage(ContainerT&& container, FairMQMemoryResource* targetResource = nullptr)
54{
55 return fair::mq::getMessage(std::forward<ContainerT>(container), targetResource);
56}
57
58//__________________________________________________________________________________________________
64{
65
66 public:
67 MessageResource() noexcept = delete;
68 MessageResource(const MessageResource&) noexcept = default;
69 MessageResource(MessageResource&&) noexcept = default;
70 MessageResource& operator=(const MessageResource&) = default;
71 MessageResource& operator=(MessageResource&&) = default;
72 MessageResource(fair::mq::MessagePtr message)
73 : mUpstream{message->GetTransport()->GetMemoryResource()},
74 mMessageSize{message->GetSize()},
75 mMessageData{mUpstream ? mUpstream->setMessage(std::move(message))
76 : throw std::runtime_error("MessageResource::MessageResource upstream is nullptr")}
77 {
78 }
79 fair::mq::MessagePtr getMessage(void* p) override { return mUpstream->getMessage(p); }
80 void* setMessage(fair::mq::MessagePtr message) override { return mUpstream->setMessage(std::move(message)); }
81 fair::mq::TransportFactory* getTransportFactory() noexcept override { return nullptr; }
82 size_t getNumberOfMessages() const noexcept override { return mMessageData ? 1 : 0; }
83
84 protected:
86 size_t mMessageSize{0};
87 void* mMessageData{nullptr};
88 bool initialImport{true};
89
90 void* do_allocate(std::size_t bytes, std::size_t alignment) override
91 {
92 if (initialImport) {
93 if (bytes > mMessageSize) {
94 throw std::bad_alloc();
95 }
96 initialImport = false;
97 return mMessageData;
98 } else {
99 return mUpstream->allocate(bytes, alignment < 64 ? 64 : alignment);
100 }
101 }
102 void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override
103 {
104 mUpstream->deallocate(p, bytes, alignment < 64 ? 64 : alignment);
105 return;
106 }
107 bool do_is_equal(const memory_resource& /*other*/) const noexcept override
108 {
109 // since this uniquely owns the message it can never be equal to anybody else
110 return false;
111 }
112};
113
114// The NoConstructAllocator behaves like the normal pmr vector but does not call constructors / destructors
115template <typename T>
117{
118 public:
121
122 template <typename... Args>
123 NoConstructAllocator(Args&&... args) : fair::mq::pmr::polymorphic_allocator<T>(std::forward<Args>(args)...)
124 {
125 }
126
127 // skip default construction of empty elements
128 // this is important for two reasons: one: it allows us to adopt an existing buffer (e.g. incoming message) and
129 // quickly construct large vectors while skipping the element initialization.
130 template <class U>
131 void construct(U*)
132 {
133 }
134
135 // dont try to call destructors, makes no sense since resource is managed externally AND allowed
136 // types cannot have side effects
137 template <typename U>
138 void destroy(U*)
139 {
140 }
141};
142
143//__________________________________________________________________________________________________
144//__________________________________________________________________________________________________
145//__________________________________________________________________________________________________
146//__________________________________________________________________________________________________
147
149template <class T>
150using vector = std::vector<T, fair::mq::pmr::polymorphic_allocator<T>>;
151
152//__________________________________________________________________________________________________
154inline static FairMQMemoryResource* getTransportAllocator(fair::mq::TransportFactory* factory)
155{
156 return *factory;
157}
158
159} // namespace o2::pmr
160
161#endif
const auto & getMessage()
void * setMessage(fair::mq::MessagePtr message) override
MessageResource() noexcept=delete
fair::mq::TransportFactory * getTransportFactory() noexcept override
void do_deallocate(void *p, std::size_t bytes, std::size_t alignment) override
void * do_allocate(std::size_t bytes, std::size_t alignment) override
FairMQMemoryResource * mUpstream
fair::mq::MessagePtr getMessage(void *p) override
bool do_is_equal(const memory_resource &) const noexcept override
size_t getNumberOfMessages() const noexcept override
std::true_type propagate_on_container_move_assignment
NoConstructAllocator(Args &&... args)
GLuint GLsizei const GLchar * message
Definition glcorearb.h:2517
O2 memory allocators and interfaces related to managing memory via the trasport layer.
std::vector< T, fair::mq::pmr::polymorphic_allocator< T > > vector
fair::mq::ChannelResource ChannelResource
Defining DataPointCompositeObject explicitly as copiable.