FairMQ  1.3.8
C++ Message Passing Framework
MemoryResourceTools.h
1 /********************************************************************************
2  * Copyright (C) 2018 CERN and copyright holders of ALICE O2 *
3  * Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
4  * *
5  * This software is distributed under the terms of the *
6  * GNU Lesser General Public Licence (LGPL) version 3, *
7  * copied verbatim in the file "LICENSE" *
8  ********************************************************************************/
9 
14 
15 #include <fairmq/FairMQTransportFactory.h>
16 #include <fairmq/MemoryResources.h>
17 
18 namespace fair {
19 namespace mq {
20 
21 using BytePmrAllocator = pmr::polymorphic_allocator<fair::mq::byte>;
22 
23 //_________________________________________________________________________________________________
24 // return the message associated with the container or throw if it is not possible
25 template<typename ContainerT>
26 // typename std::enable_if<
27 // std::is_base_of<
28 // pmr::polymorphic_allocator<typename
29 // ContainerT::value_type>,
30 // typename ContainerT::allocator_type>::value == true,
31 // FairMQMessagePtr>::type
32 FairMQMessagePtr getMessage(ContainerT &&container_, FairMQMemoryResource *targetResource = nullptr)
33 {
34  auto container = std::move(container_);
35  auto alloc = container.get_allocator();
36 
37  auto resource = dynamic_cast<FairMQMemoryResource *>(alloc.resource());
38  if (!resource && !targetResource) {
39  throw std::runtime_error("Neither the container or target resource specified");
40  }
41  size_t containerSizeBytes = container.size() * sizeof(typename ContainerT::value_type);
42  if ((!targetResource && resource)
43  || (resource && targetResource && resource->is_equal(*targetResource))) {
44  auto message = resource->getMessage(static_cast<void *>(
45  const_cast<typename std::remove_const<typename ContainerT::value_type>::type *>(
46  container.data())));
47  if (message)
48  {
49  message->SetUsedSize(containerSizeBytes);
50  return message;
51  } else {
52  //container is not required to allocate (like in std::string small string optimization)
53  //in case we get no message we fall back to default (copy) behaviour)
54  targetResource = resource;
55  }
56  }
57 
58  auto message = targetResource->getTransportFactory()->CreateMessage(containerSizeBytes);
59  std::memcpy(static_cast<fair::mq::byte *>(message->GetData()),
60  container.data(),
61  containerSizeBytes);
62  return message;
63 };
64 
65 } /* namespace mq */
66 } /* namespace fair */
Tools for interfacing containers to the transport via polymorphic allocators.
Definition: DeviceRunner.h:23

privacy