@@ -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
271115template <typename T>
272116class 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>;
305148using BytePmrAllocator = fair::mq::pmr::polymorphic_allocator<std::byte>;
306149template <class T >
307150using 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
321154inline static FairMQMemoryResource* getTransportAllocator (fair::mq::TransportFactory* factory)
0 commit comments