Skip to content

Commit f1663a8

Browse files
committed
DataModel: remove unsupported classes
The code in question conflicts with the modern / standardized specification of std::pmr where the polymorphic_allocators cannot be moved. Given we are not actually using those classes in any case, I am removing them. If we will need the functionality in the future, we will in any case need to reimplement / rethink / verify them.
1 parent c4bca14 commit f1663a8

File tree

2 files changed

+0
-231
lines changed

2 files changed

+0
-231
lines changed

DataFormats/MemoryResources/include/MemoryResources/MemoryResources.h

Lines changed: 0 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -111,162 +111,6 @@ class MessageResource : public FairMQMemoryResource
111111
}
112112
};
113113

114-
//__________________________________________________________________________________________________
115-
// A spectator pmr memory resource which only watches the memory of the underlying buffer, does not
116-
// carry out real allocation. It owns the underlying buffer which is destroyed on deallocation.
117-
template <typename BufferType>
118-
class SpectatorMemoryResource : public fair::mq::pmr::memory_resource
119-
{
120-
public:
121-
using buffer_type = BufferType;
122-
123-
SpectatorMemoryResource() noexcept = delete;
124-
SpectatorMemoryResource(const SpectatorMemoryResource&) noexcept = delete;
125-
SpectatorMemoryResource(SpectatorMemoryResource&&) noexcept = default;
126-
SpectatorMemoryResource& operator=(const SpectatorMemoryResource&) = delete;
127-
SpectatorMemoryResource& operator=(SpectatorMemoryResource&&) = default;
128-
~SpectatorMemoryResource() noexcept override = default;
129-
130-
// the resource is the pointer managed by unique_ptr
131-
template <typename T>
132-
SpectatorMemoryResource(std::unique_ptr<T, typename buffer_type::deleter_type>&& buffer, size_t size)
133-
: mBuffer{std::move(buffer)}, mPointer{mBuffer.get()}, mSize{size}
134-
{
135-
}
136-
137-
// the resource is the data of the vector managed by unique ptr
138-
template <typename T>
139-
SpectatorMemoryResource(std::unique_ptr<std::vector<T>, typename buffer_type::deleter_type>&& buffer)
140-
: mBuffer{std::move(buffer)}, mPointer{mBuffer->data()}, mSize{mBuffer->size() * sizeof(T)}
141-
{
142-
}
143-
144-
// TODO: the underlying resource can be directly the vector or the read only buffer
145-
protected:
146-
void* do_allocate(std::size_t bytes, std::size_t /*alignment*/) override
147-
{
148-
if (mSize > 0) {
149-
if (bytes > mSize) {
150-
throw std::bad_alloc();
151-
}
152-
mSize = 0;
153-
return mPointer;
154-
}
155-
throw std::runtime_error("Can not allocate: this memory resource is only supposed to provide spectator access to external buffer");
156-
}
157-
158-
void do_deallocate(void* p, std::size_t /*bytes*/, std::size_t /*alignment*/) override
159-
{
160-
if (p == mPointer) {
161-
mBuffer.reset();
162-
mPointer = nullptr;
163-
} else if (mPointer == nullptr) {
164-
// there is an error in the logic flow, this should never be called more than once
165-
throw std::logic_error("underlying controlled resource has been released already");
166-
} else {
167-
throw std::logic_error("this resource can only deallocate the controlled resource pointer");
168-
}
169-
}
170-
bool do_is_equal(const memory_resource& /*other*/) const noexcept override
171-
{
172-
// uniquely owns the underlying resource, can never be equal to any other instance
173-
return false;
174-
}
175-
176-
private:
177-
buffer_type mBuffer;
178-
void* mPointer = nullptr;
179-
size_t mSize = 0;
180-
};
181-
182-
//__________________________________________________________________________________________________
183-
// This in general (as in STL) is a bad idea, but here it is safe to inherit from an allocator since we
184-
// have no additional data and only override some methods so we don't get into slicing and other problems.
185-
template <typename T>
186-
class SpectatorAllocator : public fair::mq::pmr::polymorphic_allocator<T>
187-
{
188-
public:
189-
using fair::mq::pmr::polymorphic_allocator<T>::polymorphic_allocator;
190-
using propagate_on_container_move_assignment = std::true_type;
191-
192-
// skip default construction of empty elements
193-
// this is important for two reasons: one: it allows us to adopt an existing buffer (e.g. incoming message) and
194-
// quickly construct large vectors while skipping the element initialization.
195-
template <class U>
196-
void construct(U*)
197-
{
198-
}
199-
200-
// dont try to call destructors, makes no sense since resource is managed externally AND allowed
201-
// types cannot have side effects
202-
template <typename U>
203-
void destroy(U*)
204-
{
205-
}
206-
207-
T* allocate(size_t size) { return reinterpret_cast<T*>(this->resource()->allocate(size * sizeof(T), 64)); }
208-
void deallocate(T* ptr, size_t size)
209-
{
210-
this->resource()->deallocate(const_cast<typename std::remove_cv<T>::type*>(ptr), size);
211-
}
212-
};
213-
214-
//__________________________________________________________________________________________________
215-
/// This allocator has a pmr-like interface, but keeps the unique MessageResource as internal state,
216-
/// allowing full resource (associated message) management internally without any global state.
217-
template <typename T>
218-
class OwningMessageSpectatorAllocator
219-
{
220-
public:
221-
using value_type = T;
222-
223-
MessageResource mResource;
224-
225-
OwningMessageSpectatorAllocator() noexcept = default;
226-
OwningMessageSpectatorAllocator(const OwningMessageSpectatorAllocator&) noexcept = default;
227-
OwningMessageSpectatorAllocator(OwningMessageSpectatorAllocator&&) noexcept = default;
228-
OwningMessageSpectatorAllocator(MessageResource&& resource) noexcept : mResource{resource} {}
229-
230-
template <class U>
231-
OwningMessageSpectatorAllocator(const OwningMessageSpectatorAllocator<U>& other) noexcept : mResource(other.mResource)
232-
{
233-
}
234-
235-
OwningMessageSpectatorAllocator& operator=(const OwningMessageSpectatorAllocator& other)
236-
{
237-
mResource = other.mResource;
238-
return *this;
239-
}
240-
241-
OwningMessageSpectatorAllocator select_on_container_copy_construction() const
242-
{
243-
return OwningMessageSpectatorAllocator();
244-
}
245-
246-
fair::mq::pmr::memory_resource* resource() { return &mResource; }
247-
248-
// skip default construction of empty elements
249-
// this is important for two reasons: one: it allows us to adopt an existing buffer (e.g. incoming message) and
250-
// quickly construct large vectors while skipping the element initialization.
251-
template <class U>
252-
void construct(U*)
253-
{
254-
}
255-
256-
// dont try to call destructors, makes no sense since resource is managed externally AND allowed
257-
// types cannot have side effects
258-
template <typename U>
259-
void destroy(U*)
260-
{
261-
}
262-
263-
T* allocate(size_t size) { return reinterpret_cast<T*>(mResource.allocate(size * sizeof(T), 64)); }
264-
void deallocate(T* ptr, size_t size)
265-
{
266-
mResource.deallocate(const_cast<typename std::remove_cv<T>::type*>(ptr), size);
267-
}
268-
};
269-
270114
// The NoConstructAllocator behaves like the normal pmr vector but does not call constructors / destructors
271115
template <typename T>
272116
class NoConstructAllocator : public fair::mq::pmr::polymorphic_allocator<T>
@@ -301,21 +145,10 @@ class NoConstructAllocator : public fair::mq::pmr::polymorphic_allocator<T>
301145
//__________________________________________________________________________________________________
302146
//__________________________________________________________________________________________________
303147

304-
using ByteSpectatorAllocator = SpectatorAllocator<std::byte>;
305148
using BytePmrAllocator = fair::mq::pmr::polymorphic_allocator<std::byte>;
306149
template <class T>
307150
using vector = std::vector<T, fair::mq::pmr::polymorphic_allocator<T>>;
308151

309-
//__________________________________________________________________________________________________
310-
/// Return a std::vector spanned over the contents of the message, takes ownership of the message
311-
template <typename ElemT>
312-
auto adoptVector(size_t nelem, fair::mq::MessagePtr message)
313-
{
314-
static_assert(std::is_trivially_destructible<ElemT>::value);
315-
return std::vector<ElemT, OwningMessageSpectatorAllocator<ElemT>>(
316-
nelem, OwningMessageSpectatorAllocator<ElemT>(MessageResource{std::move(message)}));
317-
};
318-
319152
//__________________________________________________________________________________________________
320153
/// Get the allocator associated to a transport factory
321154
inline static FairMQMemoryResource* getTransportAllocator(fair::mq::TransportFactory* factory)

DataFormats/MemoryResources/test/testMemoryResources.cxx

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -152,68 +152,4 @@ BOOST_AUTO_TEST_CASE(getMessage_test)
152152
}
153153
}
154154

155-
BOOST_AUTO_TEST_CASE(adoptVector_test)
156-
{
157-
size_t session{(size_t)getpid() * 1000 + 3};
158-
fair::mq::ProgOptions config;
159-
config.SetProperty<std::string>("session", std::to_string(session));
160-
161-
auto factoryZMQ = fair::mq::TransportFactory::CreateTransportFactory("zeromq");
162-
auto factorySHM = fair::mq::TransportFactory::CreateTransportFactory("shmem", "adoptVector_test", &config);
163-
auto allocZMQ = getTransportAllocator(factoryZMQ.get());
164-
auto allocSHM = getTransportAllocator(factorySHM.get());
165-
166-
testData::nconstructions = 0;
167-
168-
// Create a bogus message
169-
auto message = factoryZMQ->CreateMessage(3 * sizeof(testData));
170-
auto messageAddr = message.get();
171-
testData tmpBuf[3] = {3, 2, 1};
172-
std::memcpy(message->GetData(), tmpBuf, 3 * sizeof(testData));
173-
174-
auto adoptedOwner = adoptVector<testData>(3, std::move(message));
175-
BOOST_CHECK(adoptedOwner[0].i == 3);
176-
BOOST_CHECK(adoptedOwner[1].i == 2);
177-
BOOST_CHECK(adoptedOwner[2].i == 1);
178-
179-
auto reclaimedMessage = o2::pmr::getMessage(std::move(adoptedOwner));
180-
BOOST_CHECK(reclaimedMessage.get() == messageAddr);
181-
BOOST_CHECK(adoptedOwner.size() == 0);
182-
183-
auto modified = adoptVector<testData>(3, std::move(reclaimedMessage));
184-
modified.emplace_back(9);
185-
BOOST_CHECK(modified[3].i == 9);
186-
BOOST_CHECK(modified.size() == 4);
187-
BOOST_CHECK(testData::nconstructions == 7);
188-
auto modifiedMessage = getMessage(std::move(modified));
189-
BOOST_CHECK(modifiedMessage != nullptr);
190-
BOOST_CHECK(modifiedMessage.get() != messageAddr);
191-
}
192-
193-
BOOST_AUTO_TEST_CASE(test_SpectatorMemoryResource)
194-
{
195-
constexpr int size = 5;
196-
auto buffer = std::make_unique<int[]>(size);
197-
auto const* bufferdata = buffer.get();
198-
SpectatorMemoryResource<decltype(buffer)> resource(std::move(buffer), size * sizeof(int));
199-
std::vector<int, o2::pmr::SpectatorAllocator<int>> bufferclone(size, o2::pmr::SpectatorAllocator<int>(&resource));
200-
BOOST_CHECK(bufferclone.data() == bufferdata);
201-
BOOST_CHECK(bufferclone.size() == size);
202-
BOOST_CHECK_THROW(bufferclone.resize(2 * size), std::runtime_error);
203-
204-
auto vecbuf = std::make_unique<std::vector<int>>(size);
205-
auto const* vectordata = vecbuf->data();
206-
SpectatorMemoryResource<decltype(vecbuf)> vecresource(std::move(vecbuf));
207-
std::vector<int, o2::pmr::SpectatorAllocator<int>> vecclone(size, o2::pmr::SpectatorAllocator<int>(&vecresource));
208-
BOOST_CHECK(vecclone.data() == vectordata);
209-
BOOST_CHECK(vecclone.size() == size);
210-
BOOST_CHECK_THROW(vecclone.resize(2 * size), std::runtime_error);
211-
212-
std::vector<int, o2::pmr::SpectatorAllocator<int>> vecmove;
213-
vecmove = std::move(vecclone);
214-
BOOST_CHECK(vecclone.size() == 0);
215-
BOOST_CHECK(vecmove.data() == vectordata);
216-
BOOST_CHECK(vecmove.size() == size);
217-
}
218-
219155
}; // namespace o2::pmr

0 commit comments

Comments
 (0)