Changeset 123:0d33b676b2a4 in finroc_plugins_data_ports


Ignore:
Timestamp:
27.08.2017 21:12:10 (2 years ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Phase:
public
Message:

Makes ports with cheaply copied types use buffer-size-specific buffer pools instead of data-type-specific buffer pools. This significantly reduces the number of required buffer pools, simplifies the code (no type registration and associated indices management required), and data type annotations are no longer required for this purpose.

Files:
20 edited

Legend:

Unmodified
Added
Removed
  • api/tBoundedPort.h

    r119 r123  
    115115    if (!bounds.InBounds(value)) 
    116116    { 
    117       typename tPortBase::tUnusedManagerPointer new_buffer(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(this->GetCheaplyCopyableTypeIndex()).release()); 
     117      typename tPortBase::tUnusedManagerPointer new_buffer(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(this->GetCheaplyCopiedTypeBufferPoolIndex()).release()); 
    118118      tImplementationVariation::Assign(new_buffer->GetObject().template GetData<T>(), bounds.GetOutOfBoundsDefault()); 
    119119      this->BrowserPublishRaw(new_buffer); // If port is already connected, could this have undesirable side-effects? (I do not think so - otherwise we need to do something more sophisticated here) 
  • api/tDeserializationScope.cpp

    r76 r123  
    8080  if (IsCheaplyCopiedType(type)) 
    8181  { 
    82     uint32_t index = optimized::GetCheaplyCopiedTypeIndex(type); 
     82    uint32_t index = optimized::GetCheaplyCopiedBufferPoolIndex(type); 
    8383    if (optimized::tThreadLocalBufferPools::Get()) 
    8484    { 
    85       return tPortDataPointerImplementation<rrlib::rtti::tGenericObject, false>(optimized::tThreadLocalBufferPools::Get()->GetUnusedBuffer(index).release(), true); 
     85      return tPortDataPointerImplementation<rrlib::rtti::tGenericObject, false>(optimized::tThreadLocalBufferPools::Get()->GetUnusedBuffer(index, type).release(), true); 
    8686    } 
    8787    else 
    8888    { 
    89       return tPortDataPointerImplementation<rrlib::rtti::tGenericObject, false>(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(index).release(), true); 
     89      return tPortDataPointerImplementation<rrlib::rtti::tGenericObject, false>(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(index, type).release(), true); 
    9090    } 
    9191  } 
  • api/tGenericPortImplementation.cpp

    r122 r123  
    116116    if (thread_local_pools) 
    117117    { 
    118       typename optimized::tThreadLocalBufferPools::tBufferPointer buffer = thread_local_pools->GetUnusedBuffer(static_cast<tPortBase&>(port).GetCheaplyCopyableTypeIndex()); 
     118      typename optimized::tThreadLocalBufferPools::tBufferPointer buffer = thread_local_pools->GetUnusedBuffer(static_cast<tPortBase&>(port).GetCheaplyCopiedTypeBufferPoolIndex(), port.GetDataType()); 
    119119      buffer->SetTimestamp(timestamp); 
    120120      buffer->GetObject().DeepCopyFrom(data); 
     
    124124    else 
    125125    { 
    126       typename optimized::tCheapCopyPort::tUnusedManagerPointer buffer(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(static_cast<tPortBase&>(port).GetCheaplyCopyableTypeIndex()).release()); 
     126      typename optimized::tCheapCopyPort::tUnusedManagerPointer buffer(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(static_cast<tPortBase&>(port).GetCheaplyCopiedTypeBufferPoolIndex(), port.GetDataType()).release()); 
    127127      buffer->SetTimestamp(timestamp); 
    128128      buffer->GetObject().DeepCopyFrom(data); 
  • api/tGenericPortImplementation.h

    r122 r123  
    142142      if (optimized::tThreadLocalBufferPools::Get()) 
    143143      { 
    144         return tPortDataPointerImplementation<rrlib::rtti::tGenericObject, false>(optimized::tThreadLocalBufferPools::Get()->GetUnusedBuffer(cc_port.GetCheaplyCopyableTypeIndex()).release(), true); 
     144        return tPortDataPointerImplementation<rrlib::rtti::tGenericObject, false>(optimized::tThreadLocalBufferPools::Get()->GetUnusedBuffer(cc_port.GetCheaplyCopiedTypeBufferPoolIndex(), port.GetDataType()).release(), true); 
    145145      } 
    146146      else 
    147147      { 
    148         return tPortDataPointerImplementation<rrlib::rtti::tGenericObject, false>(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(cc_port.GetCheaplyCopyableTypeIndex()).release(), true); 
     148        return tPortDataPointerImplementation<rrlib::rtti::tGenericObject, false>(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(cc_port.GetCheaplyCopiedTypeBufferPoolIndex(), port.GetDataType()).release(), true); 
    149149      } 
    150150    } 
  • api/tPortImplementation.h

    r119 r123  
    147147  static inline void BrowserPublish(optimized::tCheapCopyPort& port, const T& data, const rrlib::time::tTimestamp& timestamp) 
    148148  { 
    149     typename optimized::tCheapCopyPort::tUnusedManagerPointer buffer(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(port.GetCheaplyCopyableTypeIndex()).release()); 
     149    typename optimized::tCheapCopyPort::tUnusedManagerPointer buffer(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(port.GetCheaplyCopiedTypeBufferPoolIndex(), port.GetDataType()).release()); 
    150150    buffer->SetTimestamp(timestamp); 
    151151    tBase::Assign(buffer->GetObject().GetData<typename tBase::tPortBuffer>(), data); 
     
    158158    if (thread_local_pools) 
    159159    { 
    160       typename optimized::tThreadLocalBufferPools::tBufferPointer buffer = thread_local_pools->GetUnusedBuffer(port.GetCheaplyCopyableTypeIndex()); 
     160      typename optimized::tThreadLocalBufferPools::tBufferPointer buffer = thread_local_pools->GetUnusedBuffer(port.GetCheaplyCopiedTypeBufferPoolIndex(), port.GetDataType()); 
    161161      buffer->SetTimestamp(timestamp); 
    162162      tBase::Assign(buffer->GetObject().GetData<typename tBase::tPortBuffer>(), data); 
     
    166166    else 
    167167    { 
    168       typename optimized::tCheapCopyPort::tUnusedManagerPointer buffer(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(port.GetCheaplyCopyableTypeIndex()).release()); 
     168      typename optimized::tCheapCopyPort::tUnusedManagerPointer buffer(optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(port.GetCheaplyCopiedTypeBufferPoolIndex(), port.GetDataType()).release()); 
    169169      buffer->SetTimestamp(timestamp); 
    170170      tBase::Assign(buffer->GetObject().GetData<typename tBase::tPortBuffer>(), data); 
  • api/tPortListenerAdapter.h

    r101 r123  
    273273      { 
    274274        optimized::tSingleThreadedCheapCopyPortGeneric::tCurrentValueBuffer& buffer = static_cast<optimized::tSingleThreadedCheapCopyPortGeneric::tCurrentValueBuffer&>(value); 
    275         auto buffer_manager = optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(buffer.cheaply_copyable_type_index); 
     275        auto buffer_manager = optimized::tGlobalBufferPools::Instance().GetUnusedBuffer(buffer.cheaply_copied_type_buffer_pool_index, change_context.Origin().GetDataType()); 
    276276        buffer_manager->GetObject().DeepCopyFrom(*buffer.data); 
    277277        tPortDataPointer<const rrlib::rtti::tGenericObject> pointer( 
  • common/tPortBufferPool.h

    r46 r123  
    5858namespace data_ports 
    5959{ 
     60 
     61//---------------------------------------------------------------------- 
     62// Forward declarations / typedefs / enums 
     63//---------------------------------------------------------------------- 
     64namespace standard 
     65{ 
     66class tPortBufferManager; 
     67} 
     68 
    6069namespace common 
    6170{ 
    62  
    63 //---------------------------------------------------------------------- 
    64 // Forward declarations / typedefs / enums 
    65 //---------------------------------------------------------------------- 
    6671 
    6772//---------------------------------------------------------------------- 
     
    109114          tBufferPoolSingleThreaded, tBufferPoolConcurrent >::type tBufferPool; 
    110115 
     116  /*! Whether this is a buffer pool for a standard port */ 
     117  enum { cSTANDARD_PORT = std::is_same<TBufferManager, standard::tPortBufferManager>::value }; 
     118 
     119  /*! Information what kind of content buffers contain (either data type - or buffer size) */ 
     120  typedef typename std::conditional<cSTANDARD_PORT, rrlib::rtti::tType, uint32_t>::type tContentId; 
     121 
    111122//---------------------------------------------------------------------- 
    112123// Public methods and typedefs 
     
    118129 
    119130  /*! 
    120    * \param data_type Type of buffers in pool 
    121    * \param intial_size Number of buffer to allocate initially 
    122    */ 
    123   tPortBufferPool(const rrlib::rtti::tType& data_type, int initial_size) : 
     131   * \param buffer_content Buffer content 
     132   * \param intial_size Number of buffers to allocate initially 
     133   */ 
     134  tPortBufferPool(const tContentId& buffer_content, int initial_size) : 
    124135    buffer_pool() 
    125136  { 
    126     AllocateAdditionalBuffers(data_type, initial_size); 
     137    AllocateAdditionalBuffers(buffer_content, initial_size); 
    127138  } 
    128139 
     
    133144   * Allocates the specified number of additional buffers and adds them to pool 
    134145   * 
    135    * \param data_type Data type of buffers to add 
     146   * \param buffer_content Buffer content 
    136147   * \param count Number of buffers to allocate and add 
    137148   */ 
    138   inline void AllocateAdditionalBuffers(const rrlib::rtti::tType& data_type, size_t count) 
     149  inline void AllocateAdditionalBuffers(const tContentId& buffer_content, size_t count) 
    139150  { 
    140151    for (size_t i = 0; i < count; i++) 
    141152    { 
    142       CreateBuffer(data_type); 
    143     } 
    144   } 
    145  
    146 //  /*! 
    147 //   * \return Data Type of buffers in pool 
    148 //   */ 
    149 //  inline rrlib::rtti::tType GetDataType() const 
    150 //  { 
    151 //    return data_type; 
    152 //  } 
    153  
    154   /*! 
    155    * \param cheaply_copyable_type_index Index of 'cheaply copied' data type of pool 
     153      CreateBuffer(buffer_content); 
     154    } 
     155  } 
     156 
     157  /*! 
     158   * \param data_type Data type of desired buffer 
    156159   * \return Returns unused buffer. If there are no buffers that can be reused, a new buffer is allocated. 
    157160   */ 
    158   inline tPointer GetUnusedBuffer(uint32_t cheaply_copyable_type_index) 
     161  template <bool Tstandard_port = cSTANDARD_PORT> 
     162  inline tPointer GetUnusedBuffer(const typename std::enable_if<Tstandard_port, rrlib::rtti::tType>::type& data_type) 
    159163  { 
    160164    tPointer buffer = buffer_pool.GetUnusedBuffer(); 
     
    163167      return std::move(buffer); 
    164168    } 
    165     return CreateBuffer(optimized::GetType(cheaply_copyable_type_index)); 
    166   } 
    167  
    168   /*! 
    169    * \param data_type Data type of buffers in this pool 
    170    * \param possibly_create_buffer Create new buffer if there is none in pool at the moment? 
    171    * \return Returns unused buffer. If there are no buffers that can be reused, a new buffer is possibly allocated. 
    172    */ 
    173   inline tPointer GetUnusedBuffer(const rrlib::rtti::tType& data_type, bool possibly_create_buffer = true) 
     169    return CreateBuffer(data_type); 
     170  } 
     171 
     172  /*! 
     173   * \param buffer_size Size of buffer 
     174   * \param data_type Data type of desired buffer 
     175   * \return Returns unused buffer. If there are no buffers that can be reused, a new buffer is allocated. 
     176   */ 
     177  template <bool Tstandard_port = cSTANDARD_PORT> 
     178  inline tPointer GetUnusedBuffer(typename std::enable_if < !Tstandard_port, uint32_t >::type buffer_size, const rrlib::rtti::tType& data_type) 
    174179  { 
    175180    tPointer buffer = buffer_pool.GetUnusedBuffer(); 
     
    178183      return std::move(buffer); 
    179184    } 
    180     return possibly_create_buffer ? CreateBuffer(data_type) : tPointer(); 
     185    return CreateBuffer(buffer_size); 
    181186  } 
    182187 
     
    193198//---------------------------------------------------------------------- 
    194199private: 
    195  
    196   /*! Data Type of buffers in pool */ 
    197   //const rrlib::rtti::tType data_type;  This information would be redundant 
    198200 
    199201  /*! Wrapped buffer pool */ 
     
    202204 
    203205  /* 
    204    * \param data_type Data type of buffers in this pool 
     206   * \param buffer_content Buffer content 
    205207   * \return Create new buffer/instance of port data and add to pool 
    206208   */ 
    207   tPointer CreateBuffer(const rrlib::rtti::tType& data_type) 
    208   { 
    209     std::unique_ptr<TBufferManager> new_buffer(TBufferManager::CreateInstance(data_type)); 
     209  tPointer CreateBuffer(const tContentId& buffer_content) 
     210  { 
     211    std::unique_ptr<TBufferManager> new_buffer(TBufferManager::CreateInstance(buffer_content)); 
    210212 
    211213    // In case we have a string: allocate a certain buffer size (for RT capabilities with smaller payload) - 
    212214    // We do not need this check for 'cheaply copied' types - therefore the concurrency condition 
    213     if (CONCURRENCY != rrlib::concurrent_containers::tConcurrency::NONE && new_buffer->GetObject().GetType().GetRttiName() == typeid(tString).name()) 
     215    if (cSTANDARD_PORT && new_buffer->GetObject().GetType().GetRttiName() == typeid(tString).name()) 
    214216    { 
    215217      static_cast<rrlib::rtti::tGenericObject&>(new_buffer->GetObject()).GetData<tString>().reserve(512);  // TODO: move to parameter in some config.h 
     
    217219    return buffer_pool.AddBuffer(std::move(new_buffer)); 
    218220  } 
    219  
    220221}; 
    221222 
  • definitions.h

    r104 r123  
    8282constexpr core::tFrameworkElement::tFlags cDEFAULT_OUTPUT_PORT_FLAGS = core::tFrameworkElement::tFlag::EMITS_DATA | core::tFrameworkElement::tFlag::OUTPUT_PORT; 
    8383 
     84enum { cMAX_SIZE_CHEAPLY_COPIED_TYPES = 256 };  //!< Types bigger than this value (in bytes) are never considered cheaply-copied types 
     85 
    8486//---------------------------------------------------------------------- 
    8587// Function declarations 
  • optimized/cheaply_copied_types.cpp

    r106 r123  
    4040//---------------------------------------------------------------------- 
    4141#include "plugins/data_ports/type_traits.h" 
    42 #include "plugins/data_ports/numeric/tNumber.h" 
     42#include "plugins/data_ports/optimized/tThreadSpecificBufferPools.h" 
    4343 
    4444//---------------------------------------------------------------------- 
     
    7272// Implementation 
    7373//---------------------------------------------------------------------- 
    74 namespace internal 
     74namespace 
    7575{ 
    7676 
    77 class tIndexAnnotation 
    78 { 
    79 public: 
    80  
    81   tIndexAnnotation(uint32_t index = 0) : index(index) {} 
    82  
    83   /*! Cheaply copied typed index */ 
    84   uint32_t index; 
    85 }; 
     77enum { cPOOL_BUFFER_SIZE_STEP = tThreadSpecificBufferPools<true>::cPOOL_BUFFER_SIZE_STEP }; 
    8678 
    8779/*! Register with types */ 
    8880struct tRegister 
    8981{ 
    90   struct tEntry 
    91   { 
    92     rrlib::rtti::tType type; 
    93     std::atomic<size_t> port_count; 
    94  
    95     tEntry() : type(), port_count(0) 
    96     {} 
    97   }; 
    98  
    9982  /*! Cheaply copied types used in ports */ 
    100   std::array<tEntry, cMAX_CHEAPLY_COPYABLE_TYPES> used_types; 
    101  
    102   /*! Number of registered types */ 
    103   size_t registered_types; 
     83  std::array < uint32_t, cMAX_SIZE_CHEAPLY_COPIED_TYPES / cPOOL_BUFFER_SIZE_STEP > used_pools; 
    10484 
    10585  tRegister() : 
    106     used_types(), 
    107     registered_types(1) 
     86    used_pools() 
    10887  { 
    109     // Put number at position zero - as this is the most frequently used type 
    110     used_types[0].type = rrlib::rtti::tDataType<numeric::tNumber>("Number"); 
     88    used_pools.fill(0); 
    11189  } 
    11290}; 
    113  
    114 } 
    11591 
    11692/*! 
    11793 * \return Register singleton 
    11894 */ 
    119 static internal::tRegister& GetRegister() 
     95tRegister& GetRegister() 
    12096{ 
    121   static internal::tRegister the_register; 
     97  static tRegister the_register; 
    12298  return the_register; 
    12399} 
    124100 
     101} 
    125102 
    126 uint32_t GetCheaplyCopiedTypeIndex(const rrlib::rtti::tType& type) 
     103uint32_t GetCheaplyCopiedBufferPoolIndex(const rrlib::rtti::tType& type) 
    127104{ 
    128   internal::tIndexAnnotation annotation = type.GetAnnotation<internal::tIndexAnnotation>(); 
    129   if (annotation.index) 
    130   { 
    131     return annotation.index - 1; 
    132   } 
    133  
    134   static rrlib::thread::tMutex mutex; 
    135   rrlib::thread::tLock lock(mutex); 
    136   if (!IsCheaplyCopiedType(type)) 
    137   { 
    138     FINROC_LOG_PRINT_STATIC(ERROR, "Invalid type registered"); 
    139     abort(); 
    140   } 
    141  
    142   // check again - now synchronized - as type could have been added 
    143   internal::tRegister& reg = GetRegister(); 
    144   for (size_t i = 0; i < reg.registered_types; i++) 
    145   { 
    146     if (reg.used_types[i].type == type) 
    147     { 
    148       return i; 
    149     } 
    150   } 
    151  
    152   uint32_t result = reg.registered_types; 
    153   reg.used_types[result].type = type; 
    154   reg.registered_types++; 
    155   rrlib::rtti::tType type_copy = type; 
    156   type_copy.AddAnnotation(internal::tIndexAnnotation(result + 1)); // +1 so that index zero is different from Null-memory 
    157   if (result >= cMAX_CHEAPLY_COPYABLE_TYPES) 
    158   { 
    159     FINROC_LOG_PRINT_STATIC(ERROR, "Maximum number of cheaply copyable types exceeded"); 
    160     abort(); 
    161   } 
     105  uint32_t result = (type.GetSize() <= cPOOL_BUFFER_SIZE_STEP) ? 0 : ((type.GetSize() - 1) / cPOOL_BUFFER_SIZE_STEP); 
     106  assert(result >= 0 && result < cMAX_SIZE_CHEAPLY_COPIED_TYPES / cPOOL_BUFFER_SIZE_STEP); 
    162107  return result; 
    163108} 
    164109 
    165 size_t GetPortCount(uint32_t cheaply_copied_type_index) 
     110size_t GetPortCount(uint32_t cheaply_copied_type_buffer_pool_index) 
    166111{ 
    167   return GetRegister().used_types[cheaply_copied_type_index].port_count; 
    168 } 
    169  
    170 size_t GetRegisteredTypeCount() 
    171 { 
    172   return GetRegister().registered_types; 
    173 } 
    174  
    175 rrlib::rtti::tType GetType(uint32_t cheaply_copied_type_index) 
    176 { 
    177   return GetRegister().used_types[cheaply_copied_type_index].type; 
     112  return GetRegister().used_pools[cheaply_copied_type_buffer_pool_index]; 
    178113} 
    179114 
    180115uint32_t RegisterPort(const rrlib::rtti::tType& type) 
    181116{ 
    182   uint32_t result = GetCheaplyCopiedTypeIndex(type); 
    183   GetRegister().used_types[result].port_count++; 
     117  uint32_t result = GetCheaplyCopiedBufferPoolIndex(type); 
     118  GetRegister().used_pools[result]++; 
    184119  return result; 
    185120} 
    186121 
    187 void UnregisterPort(uint32_t cheaply_copied_type_index) 
     122void UnregisterPort(const rrlib::rtti::tType& type) 
    188123{ 
    189   GetRegister().used_types[cheaply_copied_type_index].port_count--; 
     124  GetRegister().used_pools[GetCheaplyCopiedBufferPoolIndex(type)]--; 
    190125} 
    191126 
  • optimized/cheaply_copied_types.h

    r46 r123  
    6060//---------------------------------------------------------------------- 
    6161 
    62 /*! Maximum number of cheaply copyable types used in ports */ 
    63 enum { cMAX_CHEAPLY_COPYABLE_TYPES = 150 }; 
    64  
    6562//---------------------------------------------------------------------- 
    6663// Function declarations 
     
    6966/*! 
    7067 * \param type Data type 
    71  * \return 'Cheaply copied type index' of this type 
     68 * \return Buffer pool index for this type 
    7269 */ 
    73 uint32_t GetCheaplyCopiedTypeIndex(const rrlib::rtti::tType& type); 
     70uint32_t GetCheaplyCopiedBufferPoolIndex(const rrlib::rtti::tType& type); 
    7471 
    7572/*! 
    76  * \param cheaply_copied_type_index 'cheaply copied type index' 
    77  * \return Number of ports that use this type 
     73 * \param cheaply_copied_type_buffer_pool_index Buffer pool index for this type 
     74 * \return Number of ports that use this buffer pool 
    7875 */ 
    79 size_t GetPortCount(uint32_t cheaply_copied_type_index); 
    80  
    81 /*! 
    82  * \return Number of registered 'cheaply copied' types 
    83  */ 
    84 size_t GetRegisteredTypeCount(); 
    85  
    86 /*! 
    87  * Looks up data type from 'cheaply copied type index' 
    88  */ 
    89 rrlib::rtti::tType GetType(uint32_t cheaply_copied_type_index); 
     76size_t GetPortCount(uint32_t cheaply_copied_type_buffer_pool_index); 
    9077 
    9178/*! 
     
    9380 * 
    9481 * \param type Type that port uses 
    95  * \return 'Cheaply copied type index' of this type 
     82 * \return Buffer pool index for this type 
    9683 */ 
    9784uint32_t RegisterPort(const rrlib::rtti::tType& type); 
     
    10087 * Unregister port for use of specified 'cheaply copied' type 
    10188 * 
    102  * \param cheaply_copied_type_index 'Cheaply copied type index' of type that port used 
     89 * \param type Type that port uses 
    10390 */ 
    104 void UnregisterPort(uint32_t cheaply_copied_type_index); 
     91void UnregisterPort(const rrlib::rtti::tType& type); 
    10592 
    10693//---------------------------------------------------------------------- 
  • optimized/tCheapCopyPort.cpp

    r118 r123  
    9595tCheapCopyPort::tCheapCopyPort(common::tAbstractDataPortCreationInfo creation_info) : 
    9696  common::tAbstractDataPort(creation_info), 
    97   cheaply_copyable_type_index(RegisterPort(creation_info.data_type)), 
     97  cheaply_copied_type_buffer_pool_index(RegisterPort(creation_info.data_type)), 
    9898  default_value(internal::CreateDefaultValue(creation_info)), 
    9999  current_value(0), 
     
    109109 
    110110  // Initialize value 
    111   tCheaplyCopiedBufferManager* initial = tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copyable_type_index).release(); 
     111  tCheaplyCopiedBufferManager* initial = tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()).release(); 
    112112  assert(initial->GetObject().GetType() == GetDataType()); 
    113113  initial->InitReferenceCounter(1); 
     
    141141tCheapCopyPort::~tCheapCopyPort() 
    142142{ 
     143  UnregisterPort(GetDataType()); 
    143144  tTaggedBufferPointer cur_pointer = current_value.exchange(0); 
    144145  tPortBufferUnlocker unlocker; 
     
    154155  } 
    155156 
    156   tUnusedManagerPointer buffer(tGlobalBufferPools::Instance().GetUnusedBuffer(GetCheaplyCopyableTypeIndex()).release()); 
     157  tUnusedManagerPointer buffer(tGlobalBufferPools::Instance().GetUnusedBuffer(GetCheaplyCopiedTypeBufferPoolIndex(), GetDataType()).release()); 
    157158  buffer->GetObject().DeepCopyFrom(*default_value); 
    158159  buffer->SetTimestamp(rrlib::time::cNO_TIME); 
     
    220221void tCheapCopyPort::CallPullRequestHandler(tPublishingDataGlobalBuffer& publishing_data) 
    221222{ 
    222   tUnusedManagerPointer result = tUnusedManagerPointer(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copyable_type_index).release()); 
     223  tUnusedManagerPointer result = tUnusedManagerPointer(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()).release()); 
    223224  if (pull_request_handler->RawPullRequest(*this, *result)) 
    224225  { 
     
    229230void tCheapCopyPort::CallPullRequestHandler(tPublishingDataThreadLocalBuffer& publishing_data) 
    230231{ 
    231   tUnusedManagerPointer result = tUnusedManagerPointer(tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copyable_type_index).release()); 
     232  tUnusedManagerPointer result = tUnusedManagerPointer(tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()).release()); 
    232233  if (pull_request_handler->RawPullRequest(*this, *result)) 
    233234  { 
     
    284285    // there obviously will not arrive any buffer from current thread in the meantime 
    285286 
    286     auto unused_manager = tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copyable_type_index); 
     287    auto unused_manager = tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()); 
    287288    for (; ;) 
    288289    { 
     
    302303  else 
    303304  { 
    304     tUnusedManagerPointer unused_manager = tUnusedManagerPointer(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copyable_type_index).release()); 
     305    tUnusedManagerPointer unused_manager = tUnusedManagerPointer(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()).release()); 
    305306    CopyCurrentValueToManager(*unused_manager, tStrategy::NEVER_PULL); 
    306307    common::tPublishOperation<tCheapCopyPort, tPublishingDataGlobalBuffer> data(unused_manager); 
     
    382383{ 
    383384  // this is a one-time event => use global buffer 
    384   tUnusedManagerPointer unused_manager(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copyable_type_index).release()); 
     385  tUnusedManagerPointer unused_manager(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()).release()); 
    385386  CopyCurrentValueToManager(*unused_manager, tStrategy::NEVER_PULL); 
    386387  if (typeid(connector) == typeid(common::tConversionConnector)) 
     
    403404    if (current_buffer->GetThreadLocalOrigin()) 
    404405    { 
    405       tUnusedManagerPointer unused_manager = tUnusedManagerPointer(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copyable_type_index).release()); 
     406      tUnusedManagerPointer unused_manager = tUnusedManagerPointer(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()).release()); 
    406407      CopyCurrentValueToManager(*unused_manager, tStrategy::NEVER_PULL); 
    407408      publishing_data.Init(unused_manager); 
     
    432433  // there obviously will not arrive any buffer from current thread in the meantime 
    433434 
    434   auto unused_manager = tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copyable_type_index); 
     435  auto unused_manager = tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()); 
    435436  for (; ;) 
    436437  { 
  • optimized/tCheapCopyPort.h

    r114 r123  
    302302   * \return Returns data type's 'cheaply copyable type index' 
    303303   */ 
    304   inline uint32_t GetCheaplyCopyableTypeIndex() const 
    305   { 
    306     return cheaply_copyable_type_index; 
     304  inline uint32_t GetCheaplyCopiedTypeBufferPoolIndex() const 
     305  { 
     306    return cheaply_copied_type_buffer_pool_index; 
    307307  } 
    308308 
     
    616616  tUnusedManagerPointer GetUnusedBuffer(tPublishingDataGlobalBuffer& publishing_data) 
    617617  { 
    618     return tUnusedManagerPointer(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copyable_type_index).release()); 
     618    return tUnusedManagerPointer(tGlobalBufferPools::Instance().GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()).release()); 
    619619  } 
    620620  tUnusedManagerPointer GetUnusedBuffer(tPublishingDataThreadLocalBuffer& publishing_data) 
    621621  { 
    622     return tUnusedManagerPointer(tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copyable_type_index).release()); 
     622    return tUnusedManagerPointer(tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copied_type_buffer_pool_index, GetDataType()).release()); 
    623623  } 
    624624 
     
    651651  friend class common::tPullOperation; 
    652652 
    653   /*! 'cheaply copyable type index' of type used in this port */ 
    654   uint32_t cheaply_copyable_type_index; 
     653  /*! Index of buffer pool to use */ 
     654  uint32_t cheaply_copied_type_buffer_pool_index; 
    655655 
    656656  /*! default value - invariant: must never be null if used (must always be copied, too) */ 
     
    792792//    } 
    793793// 
    794 //    tThreadLocalBufferManager* unused_manager = tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copyable_type_index); 
     794//    tThreadLocalBufferManager* unused_manager = tThreadLocalBufferPools::Get()->GetUnusedBuffer(cheaply_copied_type_buffer_pool_index); 
    795795//    for (; ;) 
    796796//    { 
  • optimized/tCheaplyCopiedBufferManager.cpp

    r106 r123  
    7777tCheaplyCopiedBufferManager::~tCheaplyCopiedBufferManager() 
    7878{ 
    79   if (!GetThreadLocalOrigin()) 
    80   { 
    81     GetObject().~tGenericObject(); 
    82   } 
    8379} 
    8480 
    85 tCheaplyCopiedBufferManager* tCheaplyCopiedBufferManager::CreateInstance(const rrlib::rtti::tType& type) 
     81tCheaplyCopiedBufferManager* tCheaplyCopiedBufferManager::CreateInstance(uint32_t buffer_size) 
    8682{ 
    8783  static_assert(sizeof(tCheaplyCopiedBufferManager) % 8 == 0, "Port Data manager must be aligned to 8 byte boundary"); 
    88   char* placement = (char*)operator new(sizeof(tCheaplyCopiedBufferManager) + type.GetSize(true)); 
    89   type.EmplaceGenericObject(placement + sizeof(tCheaplyCopiedBufferManager)).release(); 
     84  assert(buffer_size % 8 == 0); 
     85  char* placement = (char*)operator new(sizeof(tCheaplyCopiedBufferManager) + sizeof(rrlib::rtti::tGenericObject) + buffer_size); 
     86  memset(placement + sizeof(tCheaplyCopiedBufferManager), 0, buffer_size); 
     87  rrlib::rtti::tDataType<int>().EmplaceGenericObject(placement + sizeof(tCheaplyCopiedBufferManager)).release();  // Type is adjusted later 
    9088  return new(placement) tCheaplyCopiedBufferManager(); 
    9189} 
  • optimized/tCheaplyCopiedBufferManager.h

    r59 r123  
    8585  /*! 
    8686   * Creates instance of tCheaplyCopiedBufferManager containing a buffer 
    87    * of the specified type 
     87   * of the specified size 
    8888   * 
    89    * \param Type of buffer 
     89   * \param buffer_size Size of buffer 
    9090   * \return Created instance (can be deleted like any other objects using delete operator) 
    9191   */ 
    92   static tCheaplyCopiedBufferManager* CreateInstance(const rrlib::rtti::tType& type); 
     92  static tCheaplyCopiedBufferManager* CreateInstance(uint32_t buffer_size); 
    9393 
    9494  /*! 
     
    107107  { 
    108108    return origin; 
     109  } 
     110 
     111  /*! 
     112   * Sets data type of managed object 
     113   * 
     114   * \param type Type of object 
     115   */ 
     116  void SetType(const rrlib::rtti::tType& type) 
     117  { 
     118    const_cast<rrlib::rtti::tType&>(GetObject().GetType()) = type; 
    109119  } 
    110120 
  • optimized/tSingleThreadedCheapCopyPortGeneric.cpp

    r115 r123  
    7979  current_value.data.reset(creation_info.data_type.CreateGenericObject()); 
    8080  current_value.data_pointer = current_value.data->GetRawDataPointer(); 
    81   current_value.cheaply_copyable_type_index = RegisterPort(creation_info.data_type); 
     81  current_value.cheaply_copied_type_buffer_pool_index = RegisterPort(creation_info.data_type); 
    8282  current_value.timestamp = rrlib::time::cNO_TIME; 
    8383 
     
    104104 
    105105tSingleThreadedCheapCopyPortGeneric::~tSingleThreadedCheapCopyPortGeneric() 
    106 {} 
     106{ 
     107  UnregisterPort(GetDataType()); 
     108} 
    107109 
    108110void tSingleThreadedCheapCopyPortGeneric::ApplyDefaultValue() 
  • optimized/tSingleThreadedCheapCopyPortGeneric.h

    r114 r123  
    8989 
    9090    /*! 'cheaply copyable type index' of type used in this port */ 
    91     uint32_t cheaply_copyable_type_index; 
     91    uint32_t cheaply_copied_type_buffer_pool_index; 
    9292 
    9393    /*! Pointer to data buffer with current value (optimization - avoids one indirection) */ 
     
    187187   * \return Returns data type's 'cheaply copyable type index' 
    188188   */ 
    189   inline uint32_t GetCheaplyCopyableTypeIndex() const 
    190   { 
    191     return current_value.cheaply_copyable_type_index; 
     189  inline uint32_t GetCheaplyCopiedTypeBufferPoolIndex() const 
     190  { 
     191    return current_value.cheaply_copied_type_buffer_pool_index; 
    192192  } 
    193193 
  • optimized/tThreadLocalBufferManager.cpp

    r106 r123  
    7878tThreadLocalBufferManager::~tThreadLocalBufferManager() 
    7979{ 
    80   GetObject().~tGenericObject(); 
    8180} 
    8281 
    83 tThreadLocalBufferManager* tThreadLocalBufferManager::CreateInstance(const rrlib::rtti::tType& type) 
     82tThreadLocalBufferManager* tThreadLocalBufferManager::CreateInstance(uint32_t buffer_size) 
    8483{ 
    8584  static_assert(sizeof(tThreadLocalBufferManager) % 8 == 0, "Port Data manager must be aligned to 8 byte boundary"); 
    86   char* placement = (char*)operator new(sizeof(tThreadLocalBufferManager) + type.GetSize(true)); 
    87   type.EmplaceGenericObject(placement + sizeof(tThreadLocalBufferManager)).release(); 
     85  char* placement = (char*)operator new(sizeof(tThreadLocalBufferManager) + sizeof(rrlib::rtti::tGenericObject) + buffer_size); 
     86  memset(placement + sizeof(tThreadLocalBufferManager), 0, buffer_size); 
     87  rrlib::rtti::tDataType<int>().EmplaceGenericObject(placement + sizeof(tCheaplyCopiedBufferManager)).release();  // Type is adjusted later 
    8888  return new(placement) tThreadLocalBufferManager(); 
    8989} 
  • optimized/tThreadLocalBufferManager.h

    r46 r123  
    101101  /*! 
    102102   * Creates instance of tThreadLocalBufferManager containing a buffer 
    103    * of the specified type 
    104    * 
    105    * \param Type of buffer 
     103   * of the specified size 
     104   * 
     105   * \param buffer_size Size of buffer 
    106106   * \return Created instance (can be deleted like any other objects using delete operator) 
    107107   */ 
    108   static tThreadLocalBufferManager* CreateInstance(const rrlib::rtti::tType& type); 
     108  static tThreadLocalBufferManager* CreateInstance(uint32_t buffer_size); 
    109109 
    110110  /*! 
     
    181181 
    182182  /*! 
     183   * Sets data type of managed object 
     184   * 
     185   * \param type Type of object 
     186   */ 
     187  void SetType(const rrlib::rtti::tType& type) 
     188  { 
     189    const_cast<rrlib::rtti::tType&>(GetObject().GetType()) = type; 
     190  } 
     191 
     192  /*! 
    183193   * \return Thread-local reference counter (If additional locks are required during publishing operation, adding to this counter is a safe and efficient way of doing this) 
    184194   */ 
  • optimized/tThreadSpecificBufferPools.h

    r46 r123  
    4646// Internal includes with "" 
    4747//---------------------------------------------------------------------- 
     48#include "plugins/data_ports/definitions.h" 
    4849#include "plugins/data_ports/common/tPortBufferPool.h" 
    4950#include "plugins/data_ports/optimized/cheaply_copied_types.h" 
     
    7475 * There is also a global instance of this class shared by the remaining threads. 
    7576 * 
     77 * There separate pools for different buffer sizes. 
     78 * 
    7679 * \tparam SHARED True if this pool is shared by multiple threads 
    7780 */ 
     
    9598  typedef typename tBufferPool::tPointer tBufferPointer; 
    9699 
     100  /*! Step size for buffer pool size increase (8 means there is of buffer pool with buffers of 8 byte in size, 16 byte in size, etc.) */ 
     101  enum { cPOOL_BUFFER_SIZE_STEP = 8 }; 
     102 
    97103 
    98104  tThreadSpecificBufferPools() : 
     
    106112 
    107113  /*! 
    108    * \param cheaply_copied_type_index 'Cheaply copied type index' of buffer to obtain 
     114   * \param buffer_pool_index Pool index of buffer to obtain 
     115   * \param type Desired data type of buffer 
    109116   * \return Unused buffer of specified type 
    110117   */ 
    111   tBufferPointer GetUnusedBuffer(uint32_t cheaply_copied_type_index) 
     118  tBufferPointer GetUnusedBuffer(uint32_t buffer_pool_index, const rrlib::rtti::tType& type) 
    112119  { 
    113     return pools[cheaply_copied_type_index].GetUnusedBuffer(cheaply_copied_type_index); 
     120    tBufferPointer result = pools[buffer_pool_index].GetUnusedBuffer((buffer_pool_index + 1) * cPOOL_BUFFER_SIZE_STEP, type); 
     121    result->SetType(type); 
     122    return std::move(result); 
    114123  } 
    115124 
     
    119128protected: 
    120129 
    121   /*! The set of pools (index is index in CheaplyCopiedTypeRegister) */ 
    122   std::array<tBufferPool, cMAX_CHEAPLY_COPYABLE_TYPES> pools; 
     130  /*! The set of pools (index is buffer size / cPOOL_BUFFER_SIZE_STEP) */ 
     131  std::array < tBufferPool, cMAX_SIZE_CHEAPLY_COPIED_TYPES / cPOOL_BUFFER_SIZE_STEP > pools; 
    123132 
    124133  /*! 
     
    127136  void AddMissingPools() 
    128137  { 
    129     uint32_t type_count = GetRegisteredTypeCount(); 
    130     for (uint32_t i = 0; i < type_count; i++) 
     138    for (uint32_t i = 0; i < pools.size(); i++) 
    131139    { 
    132140      size_t initial_size = (i == 0) ? 50 : std::min<size_t>(GetPortCount(i), 10); // TODO: add proper heuristics/mechanisms for initial buffer allocation 
    133       pools[i].AllocateAdditionalBuffers(GetType(i), initial_size); 
     141      pools[i].AllocateAdditionalBuffers((i + 1) * cPOOL_BUFFER_SIZE_STEP, initial_size); 
    134142    } 
    135143  } 
  • type_traits.h

    r66 r123  
    4343// Internal includes with "" 
    4444//---------------------------------------------------------------------- 
     45#include "plugins/data_ports/definitions.h" 
    4546 
    4647//---------------------------------------------------------------------- 
     
    7879struct tIsCheaplyCopiedType 
    7980{ 
    80   enum { value = std::is_trivially_destructible<T>::value && (sizeof(T) <= 256) }; 
     81  enum { value = std::is_trivially_destructible<T>::value && (sizeof(T) <= cMAX_SIZE_CHEAPLY_COPIED_TYPES) }; 
    8182}; 
    8283 
     
    8687inline bool IsCheaplyCopiedType(const rrlib::rtti::tType& dt) 
    8788{ 
    88   return dt.GetSize() <= 256 && ((dt.GetTypeTraits() & rrlib::rtti::trait_flags::cHAS_TRIVIAL_DESTRUCTOR) != 0); 
     89  return dt.GetSize() <= cMAX_SIZE_CHEAPLY_COPIED_TYPES && ((dt.GetTypeTraits() & rrlib::rtti::trait_flags::cHAS_TRIVIAL_DESTRUCTOR) != 0); 
    8990} 
    9091 
Note: See TracChangeset for help on using the changeset viewer.