Commit df279e99 by Tobias Fuchs

containers_cpp: interface of IndexedObjectPool conforming to ObjectPool

parent d3a090c3
......@@ -33,9 +33,9 @@ namespace embb {
namespace containers {
namespace internal {
template<typename T, class IndexPool, class Allocator>
template<typename Type, class IndexPool, class Allocator>
template<typename RAI>
IndexedObjectPool<T, IndexPool, Allocator>::
IndexedObjectPool<Type, IndexPool, Allocator>::
IndexedObjectPool(RAI first, RAI last) :
size_(static_cast<size_t>(std::distance(first, last))),
indexPool(internal::ReturningTrueIterator(0),
......@@ -50,9 +50,9 @@ IndexedObjectPool(RAI first, RAI last) :
}
}
template<typename T, class IndexPool, class Allocator>
IndexedObjectPool<T, IndexPool, Allocator >::
IndexedObjectPool(size_t size, const T & defaultInstance) :
template<typename Type, class IndexPool, class Allocator>
IndexedObjectPool<Type, IndexPool, Allocator >::
IndexedObjectPool(size_t size, const Type & defaultInstance) :
size_(size),
indexPool(internal::ReturningTrueIterator(0),
internal::ReturningTrueIterator(size_)) {
......@@ -66,42 +66,103 @@ IndexedObjectPool(size_t size, const T & defaultInstance) :
}
}
template<typename T, class IndexPool, class Allocator>
IndexedObjectPool<T, IndexPool, Allocator >::
template<typename Type, class IndexPool, class Allocator>
IndexedObjectPool<Type, IndexPool, Allocator >::
~IndexedObjectPool() {
allocator.deallocate(elements, size_);
}
template<typename T, class IndexPool, class Allocator>
int IndexedObjectPool<T, 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 >::
template<typename Type, class IndexPool, class Allocator>
void IndexedObjectPool<Type, IndexPool, Allocator >::
Free(int elementIndex) {
// Call the referenced element's destructor:
elements[elementIndex].~T();
elements[elementIndex].~Type();
// Release index of the element for reuse:
indexPool.Free(true, elementIndex);
}
template<typename T, class IndexPool, class Allocator>
T & IndexedObjectPool<T, IndexPool, Allocator >::
operator[](size_t elementIndex) {
template<typename Type, class IndexPool, class Allocator>
Type & IndexedObjectPool<Type, IndexPool, Allocator >::
operator[](int 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 containers
} // namespace embb
......
......@@ -38,14 +38,14 @@ namespace containers {
namespace internal {
template<
typename T,
typename Type,
class IndexPool = LockFreeTreeValuePool<bool, false>,
class Allocator = embb::base::Allocator<T>
>
class IndexedObjectPool {
private:
const size_t size_;
T * elements;
Type * elements;
Allocator allocator;
IndexPool indexPool;
IndexedObjectPool();
......@@ -53,10 +53,13 @@ class IndexedObjectPool {
IndexedObjectPool(const IndexedObjectPool&);
// Prevent assignment
IndexedObjectPool& operator=(const IndexedObjectPool&);
// Allocates pool index and resolves pointer to reserved element
int AllocateRaw(Type * & newElement);
public:
/**
* \see value_pool_concept
* Creates an indexed object pool, initializing all pool elements
* with elements from given range.
*
* \notthreadsafe
*
......@@ -73,8 +76,9 @@ class IndexedObjectPool {
);
/**
* \see value_pool_concept
*
* Creates an indexed object pool of size \c capacity, initializing
* all pool elements with given default instance.
*
* \notthreadsafe
*
* \memory dynamically allocates
......@@ -84,7 +88,7 @@ class IndexedObjectPool {
IndexedObjectPool(
size_t size,
/**< [IN] Number of elements the pool is filled with */
const T & defaultInstance
const Type & defaultInstance
/**< [IN] Default instance to initialize pool elements with */
);
......@@ -94,16 +98,6 @@ class 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.
*
* \see value_pool_concept
......@@ -117,7 +111,38 @@ class IndexedObjectPool {
* \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
......
......@@ -127,7 +127,7 @@ class WaitFreeMPMCQueueNode {
/**< [IN] New pointer value to set */
);
inline bool Next_IsNull() const;
inline bool NextIsNull() const;
inline uint32_t EnqueueAID() const;
......@@ -155,18 +155,18 @@ class WaitFreeMPMCQueueNode {
*/
template<
typename Type,
class ValuePool =
WaitFreeArrayValuePool<bool, false>,
class NodeAllocator =
embb::base::AllocatorCacheAligned<internal::WaitFreeMPMCQueueNode<Type> >,
class OpAllocator =
embb::base::AllocatorCacheAligned<embb::base::Atomic<uint32_t> >,
class ValuePool =
WaitFreeArrayValuePool<bool, false>
embb::base::AllocatorCacheAligned<embb::base::Atomic<uint32_t> >
>
class WaitFreeMPMCQueue {
private:
typedef internal::WaitFreeMPMCQueueNode<Type> Node_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<
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