Commit df279e99 by Tobias Fuchs

containers_cpp: interface of IndexedObjectPool conforming to ObjectPool

parent d3a090c3
...@@ -33,9 +33,9 @@ namespace embb { ...@@ -33,9 +33,9 @@ namespace embb {
namespace containers { namespace containers {
namespace internal { namespace internal {
template<typename T, class IndexPool, class Allocator> template<typename Type, class IndexPool, class Allocator>
template<typename RAI> template<typename RAI>
IndexedObjectPool<T, IndexPool, Allocator>:: IndexedObjectPool<Type, IndexPool, Allocator>::
IndexedObjectPool(RAI first, RAI last) : IndexedObjectPool(RAI first, RAI last) :
size_(static_cast<size_t>(std::distance(first, last))), size_(static_cast<size_t>(std::distance(first, last))),
indexPool(internal::ReturningTrueIterator(0), indexPool(internal::ReturningTrueIterator(0),
...@@ -50,9 +50,9 @@ IndexedObjectPool(RAI first, RAI last) : ...@@ -50,9 +50,9 @@ IndexedObjectPool(RAI first, RAI last) :
} }
} }
template<typename T, class IndexPool, class Allocator> template<typename Type, class IndexPool, class Allocator>
IndexedObjectPool<T, IndexPool, Allocator >:: IndexedObjectPool<Type, IndexPool, Allocator >::
IndexedObjectPool(size_t size, const T & defaultInstance) : IndexedObjectPool(size_t size, const Type & defaultInstance) :
size_(size), size_(size),
indexPool(internal::ReturningTrueIterator(0), indexPool(internal::ReturningTrueIterator(0),
internal::ReturningTrueIterator(size_)) { internal::ReturningTrueIterator(size_)) {
...@@ -66,42 +66,103 @@ IndexedObjectPool(size_t size, const T & defaultInstance) : ...@@ -66,42 +66,103 @@ IndexedObjectPool(size_t size, const T & defaultInstance) :
} }
} }
template<typename T, class IndexPool, class Allocator> template<typename Type, class IndexPool, class Allocator>
IndexedObjectPool<T, IndexPool, Allocator >:: IndexedObjectPool<Type, IndexPool, Allocator >::
~IndexedObjectPool() { ~IndexedObjectPool() {
allocator.deallocate(elements, size_); allocator.deallocate(elements, size_);
} }
template<typename T, class IndexPool, class Allocator> template<typename Type, class IndexPool, class Allocator>
int IndexedObjectPool<T, IndexPool, Allocator >:: void IndexedObjectPool<Type, IndexPool, Allocator >::
Allocate(T & element) {
// Reserve a pool index:
bool reservedFlag;
int index = indexPool.Allocate(reservedFlag);
// Assign element to be allocated at pool index.
// Index returned from index pool is -1 if no index
// is available.
if (index >= 0) {
element = elements[index];
}
return index;
}
template<typename T, class IndexPool, class Allocator>
void IndexedObjectPool<T, IndexPool, Allocator >::
Free(int elementIndex) { Free(int elementIndex) {
// Call the referenced element's destructor: // Call the referenced element's destructor:
elements[elementIndex].~T(); elements[elementIndex].~Type();
// Release index of the element for reuse: // Release index of the element for reuse:
indexPool.Free(true, elementIndex); indexPool.Free(true, elementIndex);
} }
template<typename T, class IndexPool, class Allocator> template<typename Type, class IndexPool, class Allocator>
T & IndexedObjectPool<T, IndexPool, Allocator >:: Type & IndexedObjectPool<Type, IndexPool, Allocator >::
operator[](size_t elementIndex) { operator[](int elementIndex) {
return elements[elementIndex]; return elements[elementIndex];
} }
template<class Type, typename ValuePool, class ObjectAllocator>
int IndexedObjectPool<Type, ValuePool, ObjectAllocator>::AllocateRaw(
Type * & newElement) {
newElement = NULL;
// Reserve a pool index:
bool val;
int allocated_index = indexPool.Allocate(val);
if (allocated_index >= 0) {
// Return pointer to reserved element:
Type * ret_pointer = &(elements[allocated_index]);
newElement = ret_pointer;
}
return allocated_index;
}
template<typename Type, class IndexPool, class Allocator>
int IndexedObjectPool<Type, IndexPool, Allocator >::
Allocate() {
Type * raw_object = NULL;
int element_index = AllocateRaw(raw_object);
if (element_index >= 0 && raw_object != NULL) {
new (raw_object)Type();
}
return element_index;
}
template<typename Type, class IndexPool, class Allocator>
template<typename Param1>
int IndexedObjectPool<Type, IndexPool, Allocator >::Allocate(
Param1 const & param1) {
Type * raw_object = NULL;
int element_index = AllocateRaw(raw_object);
if (element_index >= 0 && raw_object != NULL) {
new (raw_object)Type(param1);
}
return element_index;
}
template<typename Type, class IndexPool, class Allocator>
template<typename Param1, typename Param2>
int IndexedObjectPool<Type, IndexPool, Allocator >::Allocate(
Param1 const & param1, Param2 const & param2) {
Type * raw_object = NULL;
int element_index = AllocateRaw(raw_object);
if (element_index >= 0 && raw_object != NULL) {
new (raw_object)Type(param1, param2);
}
return element_index;
}
template<typename Type, class IndexPool, class Allocator>
template<typename Param1, typename Param2, typename Param3>
int IndexedObjectPool<Type, IndexPool, Allocator >::Allocate(
Param1 const & param1, Param2 const & param2,
Param3 const & param3) {
Type * raw_object = NULL;
int element_index = AllocateRaw(raw_object);
if (element_index >= 0 && raw_object != NULL) {
new (raw_object)Type(param1, param2, param3);
}
return element_index;
}
template<typename Type, class IndexPool, class Allocator>
template<typename Param1, typename Param2, typename Param3, typename Param4>
int IndexedObjectPool<Type, IndexPool, Allocator >::Allocate(
Param1 const & param1, Param2 const & param2,
Param3 const & param3, Param4 const & param4) {
Type * raw_object = NULL;
int element_index = AllocateRaw(raw_object);
if (element_index >= 0 && raw_object != NULL) {
new (raw_object)Type(param1, param2, param3, param4);
}
return element_index;
}
} // namespace internal } // namespace internal
} // namespace containers } // namespace containers
} // namespace embb } // namespace embb
......
...@@ -38,14 +38,14 @@ namespace containers { ...@@ -38,14 +38,14 @@ namespace containers {
namespace internal { namespace internal {
template< template<
typename T, typename Type,
class IndexPool = LockFreeTreeValuePool<bool, false>, class IndexPool = LockFreeTreeValuePool<bool, false>,
class Allocator = embb::base::Allocator<T> class Allocator = embb::base::Allocator<T>
> >
class IndexedObjectPool { class IndexedObjectPool {
private: private:
const size_t size_; const size_t size_;
T * elements; Type * elements;
Allocator allocator; Allocator allocator;
IndexPool indexPool; IndexPool indexPool;
IndexedObjectPool(); IndexedObjectPool();
...@@ -53,10 +53,13 @@ class IndexedObjectPool { ...@@ -53,10 +53,13 @@ class IndexedObjectPool {
IndexedObjectPool(const IndexedObjectPool&); IndexedObjectPool(const IndexedObjectPool&);
// Prevent assignment // Prevent assignment
IndexedObjectPool& operator=(const IndexedObjectPool&); IndexedObjectPool& operator=(const IndexedObjectPool&);
// Allocates pool index and resolves pointer to reserved element
int AllocateRaw(Type * & newElement);
public: public:
/** /**
* \see value_pool_concept * Creates an indexed object pool, initializing all pool elements
* with elements from given range.
* *
* \notthreadsafe * \notthreadsafe
* *
...@@ -73,7 +76,8 @@ class IndexedObjectPool { ...@@ -73,7 +76,8 @@ class IndexedObjectPool {
); );
/** /**
* \see value_pool_concept * Creates an indexed object pool of size \c capacity, initializing
* all pool elements with given default instance.
* *
* \notthreadsafe * \notthreadsafe
* *
...@@ -84,7 +88,7 @@ class IndexedObjectPool { ...@@ -84,7 +88,7 @@ class IndexedObjectPool {
IndexedObjectPool( IndexedObjectPool(
size_t size, size_t size,
/**< [IN] Number of elements the pool is filled with */ /**< [IN] Number of elements the pool is filled with */
const T & defaultInstance const Type & defaultInstance
/**< [IN] Default instance to initialize pool elements with */ /**< [IN] Default instance to initialize pool elements with */
); );
...@@ -94,16 +98,6 @@ class IndexedObjectPool { ...@@ -94,16 +98,6 @@ class IndexedObjectPool {
~IndexedObjectPool(); ~IndexedObjectPool();
/** /**
* Request element and index from pool.
*
* \return index of element
*
* \see object_pool_concept
*
*/
int Allocate(T & element);
/**
* Return element and index to the pool. * Return element and index to the pool.
* *
* \see value_pool_concept * \see value_pool_concept
...@@ -117,7 +111,38 @@ class IndexedObjectPool { ...@@ -117,7 +111,38 @@ class IndexedObjectPool {
* \see object_pool_concept * \see object_pool_concept
* *
*/ */
T & operator[](size_t elementIndex); Type & operator[](int elementIndex);
#ifdef DOXYGEN
/**
* Allocates an element from the pool.
*
* If the underlying value pool is wait-free/lock-free, this operation is
* also wait-free/lock-free, respectively.
*
* \return Index of the allocated object if successful, otherwise \c -1.
*
* \param ... Arguments of arbitrary type, passed to the object's constructor
*/
int Allocate(...);
#else
int Allocate();
template<typename Param1>
int Allocate(Param1 const& param1);
template<typename Param1, typename Param2>
int Allocate(Param1 const& param1, Param2 const& param2);
template<typename Param1, typename Param2, typename Param3>
int Allocate(Param1 const& param1, Param2 const& param2,
Param3 const& param3);
template<typename Param1, typename Param2, typename Param3, typename Param4>
int Allocate(Param1 const& param1, Param2 const& param2,
Param3 const& param3, Param4 const& param4);
#endif
}; };
} // namespace internal } // namespace internal
......
...@@ -127,7 +127,7 @@ class WaitFreeMPMCQueueNode { ...@@ -127,7 +127,7 @@ class WaitFreeMPMCQueueNode {
/**< [IN] New pointer value to set */ /**< [IN] New pointer value to set */
); );
inline bool Next_IsNull() const; inline bool NextIsNull() const;
inline uint32_t EnqueueAID() const; inline uint32_t EnqueueAID() const;
...@@ -155,18 +155,18 @@ class WaitFreeMPMCQueueNode { ...@@ -155,18 +155,18 @@ class WaitFreeMPMCQueueNode {
*/ */
template< template<
typename Type, typename Type,
class ValuePool =
WaitFreeArrayValuePool<bool, false>,
class NodeAllocator = class NodeAllocator =
embb::base::AllocatorCacheAligned<internal::WaitFreeMPMCQueueNode<Type> >, embb::base::AllocatorCacheAligned<internal::WaitFreeMPMCQueueNode<Type> >,
class OpAllocator = class OpAllocator =
embb::base::AllocatorCacheAligned<embb::base::Atomic<uint32_t> >, embb::base::AllocatorCacheAligned<embb::base::Atomic<uint32_t> >
class ValuePool =
WaitFreeArrayValuePool<bool, false>
> >
class WaitFreeMPMCQueue { class WaitFreeMPMCQueue {
private: private:
typedef internal::WaitFreeMPMCQueueNode<Type> Node_t; typedef internal::WaitFreeMPMCQueueNode<Type> Node_t;
typedef typename internal::WaitFreeMPMCQueueNode<Type>::index_t index_t; typedef typename internal::WaitFreeMPMCQueueNode<Type>::index_t index_t;
typedef WaitFreeMPMCQueue<Type, NodeAllocator, OpAllocator, ValuePool> self_t; typedef WaitFreeMPMCQueue<Type, ValuePool, NodeAllocator, OpAllocator> self_t;
typedef internal::IndexedObjectPool< typedef internal::IndexedObjectPool<
internal::WaitFreeMPMCQueueNode<Type>, ValuePool, NodeAllocator> NodePool_t; internal::WaitFreeMPMCQueueNode<Type>, ValuePool, NodeAllocator> NodePool_t;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment