Commit 8b6b7369 by Marcus Winter

containers_cpp: revised template argument names

parent 8af3d2c0
...@@ -62,19 +62,19 @@ T LockFreeMPMCQueueNode<T>::GetElement() { ...@@ -62,19 +62,19 @@ T LockFreeMPMCQueueNode<T>::GetElement() {
} }
} // namespace internal } // namespace internal
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
void LockFreeMPMCQueue<T, ValuePool>:: void LockFreeMPMCQueue<Type, ValuePool>::
DeletePointerCallback(internal::LockFreeMPMCQueueNode<T>* to_delete) { DeletePointerCallback(internal::LockFreeMPMCQueueNode<Type>* to_delete) {
objectPool.Free(to_delete); objectPool.Free(to_delete);
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
LockFreeMPMCQueue<T, ValuePool>::~LockFreeMPMCQueue() { LockFreeMPMCQueue<Type, ValuePool>::~LockFreeMPMCQueue() {
// Nothing to do here, did not allocate anything. // Nothing to do here, did not allocate anything.
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
LockFreeMPMCQueue<T, ValuePool>::LockFreeMPMCQueue(size_t capacity) : LockFreeMPMCQueue<Type, ValuePool>::LockFreeMPMCQueue(size_t capacity) :
capacity(capacity), capacity(capacity),
// Disable "this is used in base member initializer" warning. // Disable "this is used in base member initializer" warning.
// We explicitly want this. // We explicitly want this.
...@@ -82,7 +82,8 @@ capacity(capacity), ...@@ -82,7 +82,8 @@ capacity(capacity),
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4355) #pragma warning(disable:4355)
#endif #endif
delete_pointer_callback(*this, &LockFreeMPMCQueue<T>::DeletePointerCallback), delete_pointer_callback(*this,
&LockFreeMPMCQueue<Type>::DeletePointerCallback),
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
#endif #endif
...@@ -94,26 +95,26 @@ capacity(capacity), ...@@ -94,26 +95,26 @@ capacity(capacity),
embb::base::Thread::GetThreadsMaxCount() + embb::base::Thread::GetThreadsMaxCount() +
capacity + 1) { capacity + 1) {
// Allocate dummy node to reduce the number of special cases to consider. // Allocate dummy node to reduce the number of special cases to consider.
internal::LockFreeMPMCQueueNode<T>* dummyNode = objectPool.Allocate(); internal::LockFreeMPMCQueueNode<Type>* dummyNode = objectPool.Allocate();
// Initially, head and tail point to the dummy node. // Initially, head and tail point to the dummy node.
head = dummyNode; head = dummyNode;
tail = dummyNode; tail = dummyNode;
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
size_t LockFreeMPMCQueue<T, ValuePool>::GetCapacity() { size_t LockFreeMPMCQueue<Type, ValuePool>::GetCapacity() {
return capacity; return capacity;
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
bool LockFreeMPMCQueue<T, ValuePool>::TryEnqueue(T const& element) { bool LockFreeMPMCQueue<Type, ValuePool>::TryEnqueue(Type const& element) {
// Get node from the pool containing element to enqueue. // Get node from the pool containing element to enqueue.
internal::LockFreeMPMCQueueNode<T>* node = objectPool.Allocate(element); internal::LockFreeMPMCQueueNode<Type>* node = objectPool.Allocate(element);
// Queue full, cannot enqueue // Queue full, cannot enqueue
if (node == NULL) if (node == NULL)
return false; return false;
internal::LockFreeMPMCQueueNode<T>* my_tail; internal::LockFreeMPMCQueueNode<Type>* my_tail;
for (;;) { for (;;) {
my_tail = tail; my_tail = tail;
...@@ -124,14 +125,14 @@ bool LockFreeMPMCQueue<T, ValuePool>::TryEnqueue(T const& element) { ...@@ -124,14 +125,14 @@ bool LockFreeMPMCQueue<T, ValuePool>::TryEnqueue(T const& element) {
continue; // Hazard pointer outdated, retry continue; // Hazard pointer outdated, retry
} }
internal::LockFreeMPMCQueueNode<T>* my_tail_next = my_tail->GetNext(); internal::LockFreeMPMCQueueNode<Type>* my_tail_next = my_tail->GetNext();
if (my_tail == tail) { if (my_tail == tail) {
// If the next pointer of the tail node is null, the tail pointer // If the next pointer of the tail node is null, the tail pointer
// points to the last object. We try to set the next pointer of the // points to the last object. We try to set the next pointer of the
// tail node to our new node. // tail node to our new node.
if (my_tail_next == NULL) { if (my_tail_next == NULL) {
internal::LockFreeMPMCQueueNode<T>* expected = NULL; internal::LockFreeMPMCQueueNode<Type>* expected = NULL;
// This fails if the next pointer of the "cached" tail is not null // This fails if the next pointer of the "cached" tail is not null
// anymore, i.e., another thread added a node before we could complete. // anymore, i.e., another thread added a node before we could complete.
if (my_tail->GetNext().CompareAndSwap(expected, node)) if (my_tail->GetNext().CompareAndSwap(expected, node))
...@@ -151,13 +152,13 @@ bool LockFreeMPMCQueue<T, ValuePool>::TryEnqueue(T const& element) { ...@@ -151,13 +152,13 @@ bool LockFreeMPMCQueue<T, ValuePool>::TryEnqueue(T const& element) {
return true; return true;
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
bool LockFreeMPMCQueue<T, ValuePool>::TryDequeue(T & element) { bool LockFreeMPMCQueue<Type, ValuePool>::TryDequeue(Type & element) {
internal::LockFreeMPMCQueueNode<T>* my_head; internal::LockFreeMPMCQueueNode<Type>* my_head;
internal::LockFreeMPMCQueueNode<T>* my_tail; internal::LockFreeMPMCQueueNode<Type>* my_tail;
internal::LockFreeMPMCQueueNode<T>* my_next; internal::LockFreeMPMCQueueNode<Type>* my_next;
internal::LockFreeMPMCQueueNode<T>* expected; internal::LockFreeMPMCQueueNode<Type>* expected;
T data; Type data;
for (;;) { for (;;) {
my_head = head; my_head = head;
hazardPointer.GuardPointer(0, my_head); hazardPointer.GuardPointer(0, my_head);
......
...@@ -59,14 +59,14 @@ namespace internal { ...@@ -59,14 +59,14 @@ namespace internal {
} }
} // namespace internal } // namespace internal
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
void LockFreeStack< T, ValuePool >:: void LockFreeStack< Type, ValuePool >::
DeletePointerCallback(internal::LockFreeStackNode<T>* to_delete) { DeletePointerCallback(internal::LockFreeStackNode<Type>* to_delete) {
objectPool.Free(to_delete); objectPool.Free(to_delete);
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
LockFreeStack< T, ValuePool >::LockFreeStack(size_t capacity) : LockFreeStack< Type, ValuePool >::LockFreeStack(size_t capacity) :
capacity(capacity), capacity(capacity),
// Disable "this is used in base member initializer" warning. // Disable "this is used in base member initializer" warning.
// We explicitly want this. // We explicitly want this.
...@@ -75,7 +75,7 @@ capacity(capacity), ...@@ -75,7 +75,7 @@ capacity(capacity),
#pragma warning(disable:4355) #pragma warning(disable:4355)
#endif #endif
delete_pointer_callback(*this, delete_pointer_callback(*this,
&LockFreeStack<T>::DeletePointerCallback), &LockFreeStack<Type>::DeletePointerCallback),
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
#endif #endif
...@@ -88,19 +88,19 @@ capacity(capacity), ...@@ -88,19 +88,19 @@ capacity(capacity),
capacity) { capacity) {
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
size_t LockFreeStack< T, ValuePool >::GetCapacity() { size_t LockFreeStack< Type, ValuePool >::GetCapacity() {
return capacity; return capacity;
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
LockFreeStack< T, ValuePool >::~LockFreeStack() { LockFreeStack< Type, ValuePool >::~LockFreeStack() {
// Nothing to do here, did not allocate anything. // Nothing to do here, did not allocate anything.
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
bool LockFreeStack< T, ValuePool >::TryPush(T const& element) { bool LockFreeStack< Type, ValuePool >::TryPush(Type const& element) {
internal::LockFreeStackNode<T>* newNode = internal::LockFreeStackNode<Type>* newNode =
objectPool.Allocate(element); objectPool.Allocate(element);
// Stack full, cannot push // Stack full, cannot push
...@@ -108,16 +108,16 @@ bool LockFreeStack< T, ValuePool >::TryPush(T const& element) { ...@@ -108,16 +108,16 @@ bool LockFreeStack< T, ValuePool >::TryPush(T const& element) {
return false; return false;
for (;;) { for (;;) {
internal::LockFreeStackNode<T>* top_cached = top; internal::LockFreeStackNode<Type>* top_cached = top;
newNode->SetNext(top_cached); newNode->SetNext(top_cached);
if (top.CompareAndSwap(top_cached, newNode)) if (top.CompareAndSwap(top_cached, newNode))
return true; return true;
} }
} }
template< typename T, typename ValuePool > template< typename Type, typename ValuePool >
bool LockFreeStack< T, ValuePool >::TryPop(T & element) { bool LockFreeStack< Type, ValuePool >::TryPop(Type & element) {
internal::LockFreeStackNode<T>* top_cached = top; internal::LockFreeStackNode<Type>* top_cached = top;
for (;;) { for (;;) {
top_cached = top; top_cached = top;
...@@ -146,7 +146,7 @@ bool LockFreeStack< T, ValuePool >::TryPop(T & element) { ...@@ -146,7 +146,7 @@ bool LockFreeStack< T, ValuePool >::TryPop(T & element) {
} }
} }
T data = top_cached->GetElement(); Type data = top_cached->GetElement();
// We don't need to read from this reference anymore, unguard it // We don't need to read from this reference anymore, unguard it
hazardPointer.GuardPointer(0, NULL); hazardPointer.GuardPointer(0, NULL);
......
...@@ -29,39 +29,44 @@ ...@@ -29,39 +29,44 @@
namespace embb { namespace embb {
namespace containers { namespace containers {
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
int LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
int LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
GetSmallestPowerByTwoValue(int value) { GetSmallestPowerByTwoValue(int value) {
int result = 1; int result = 1;
while (result < value) result <<= 1; while (result < value) result <<= 1;
return result; return result;
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
bool LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>::IsLeaf( class TreeAllocator >
int node ) { bool LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
IsLeaf(int node) {
if (node >= size - 1 && node <= 2 * size - 1) { if (node >= size - 1 && node <= 2 * size - 1) {
return true; return true;
} }
return false; return false;
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
bool LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
bool LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
IsValid(int node) { IsValid(int node) {
return (node >= 0 && node <= 2 * size - 1); return (node >= 0 && node <= 2 * size - 1);
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
int LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
int LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
GetLeftChildIndex(int node) { GetLeftChildIndex(int node) {
int index = 2 * node + 1; int index = 2 * node + 1;
assert(IsValid(index)); assert(IsValid(index));
return index; return index;
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
int LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
int LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
GetRightChildIndex(int node) { GetRightChildIndex(int node) {
int index = 2 * node + 2; int index = 2 * node + 2;
assert(IsValid(index)); assert(IsValid(index));
...@@ -75,16 +80,18 @@ NodeIndexToPoolIndex(int node) { ...@@ -75,16 +80,18 @@ NodeIndexToPoolIndex(int node) {
return(node - (size - 1)); return(node - (size - 1));
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
int LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
int LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
PoolIndexToNodeIndex(int index) { PoolIndexToNodeIndex(int index) {
int node = index + (size - 1); int node = index + (size - 1);
assert(IsLeaf(node)); assert(IsLeaf(node));
return node; return node;
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
bool LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
bool LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
IsRoot(int node) { IsRoot(int node) {
return(0 == node); return(0 == node);
} }
...@@ -97,14 +104,15 @@ GetParentNode(int node) { ...@@ -97,14 +104,15 @@ GetParentNode(int node) {
return parent; return parent;
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
int LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
allocate_rec(int node, T& element) { int LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
allocate_rec(int node, Type& element) {
// If we are a leaf, we try to allocate a cell using CAS. // If we are a leaf, we try to allocate a cell using CAS.
if (IsLeaf(node)) { if (IsLeaf(node)) {
int pool_index = NodeIndexToPoolIndex(node); int pool_index = NodeIndexToPoolIndex(node);
T expected = pool[pool_index]; Type expected = pool[pool_index];
if (expected == Undefined) if (expected == Undefined)
return -1; return -1;
...@@ -120,7 +128,7 @@ allocate_rec(int node, T& element) { ...@@ -120,7 +128,7 @@ allocate_rec(int node, T& element) {
int desired; int desired;
// Try to decrement node value. // Try to decrement node value.
// This is the point, where the algorithm becomes not wait-free. We have to // This is the point, where the algorithm becomes not wait-free. We have to
// atomically decrement the value in the node iff the result is greater than // atomically decrement the value in the node if the result is greater than
// or equal to zero. This cannot be done atomically. // or equal to zero. This cannot be done atomically.
do { do {
current = tree[node]; current = tree[node];
...@@ -141,8 +149,9 @@ allocate_rec(int node, T& element) { ...@@ -141,8 +149,9 @@ allocate_rec(int node, T& element) {
return rightResult; return rightResult;
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
void LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
void LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
Fill(int node, int elementsToStore, int power2Value) { Fill(int node, int elementsToStore, int power2Value) {
if (IsLeaf(node)) if (IsLeaf(node))
return; return;
...@@ -165,15 +174,17 @@ Fill(int node, int elementsToStore, int power2Value) { ...@@ -165,15 +174,17 @@ Fill(int node, int elementsToStore, int power2Value) {
} }
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
int LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
Allocate(T & element) { int LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
Allocate(Type & element) {
return allocate_rec(0, element); return allocate_rec(0, element);
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
void LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
Free(T element, int index) { void LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
Free(Type element, int index) {
assert(element != Undefined); assert(element != Undefined);
// Put the element back // Put the element back
...@@ -188,9 +199,10 @@ Free(T element, int index) { ...@@ -188,9 +199,10 @@ Free(T element, int index) {
} }
} }
template< typename T, T Undefined, class PoolAllocator, class TreeAllocator > template< typename Type, Type Undefined, class PoolAllocator,
class TreeAllocator >
template< typename ForwardIterator > template< typename ForwardIterator >
LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
LockFreeTreeValuePool(ForwardIterator first, ForwardIterator last) { LockFreeTreeValuePool(ForwardIterator first, ForwardIterator last) {
// Number of elements to store // Number of elements to store
real_size = static_cast<int>(::std::distance(first, last)); real_size = static_cast<int>(::std::distance(first, last));
...@@ -218,12 +230,14 @@ LockFreeTreeValuePool(ForwardIterator first, ForwardIterator last) { ...@@ -218,12 +230,14 @@ LockFreeTreeValuePool(ForwardIterator first, ForwardIterator last) {
Fill(0, static_cast<int>(::std::distance(first, last)), size); Fill(0, static_cast<int>(::std::distance(first, last)), size);
} }
template<typename T, T Undefined, class PoolAllocator, class TreeAllocator > template<typename Type, Type Undefined, class PoolAllocator,
LockFreeTreeValuePool<T, Undefined, PoolAllocator, TreeAllocator>:: class TreeAllocator >
LockFreeTreeValuePool<Type, Undefined, PoolAllocator, TreeAllocator>::
~LockFreeTreeValuePool() { ~LockFreeTreeValuePool() {
poolAllocator.deallocate(pool, static_cast<size_t>(real_size)); poolAllocator.deallocate(pool, static_cast<size_t>(real_size));
treeAllocator.deallocate(tree, static_cast<size_t>(tree_size)); treeAllocator.deallocate(tree, static_cast<size_t>(tree_size));
} }
} // namespace containers } // namespace containers
} // namespace embb } // namespace embb
......
...@@ -29,60 +29,60 @@ ...@@ -29,60 +29,60 @@
namespace embb { namespace embb {
namespace containers { namespace containers {
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
ObjectPool<T, ValuePool, ObjectAllocator>:: ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::ReturningTrueIterator(size_t count_value) : ReturningTrueIterator::ReturningTrueIterator(size_t count_value) :
count_value(count_value), count_value(count_value),
ret_value(true) ret_value(true)
{} {}
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
typename ObjectPool<T, ValuePool, ObjectAllocator>:: typename ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::self_type ReturningTrueIterator::self_type
ObjectPool<T, ValuePool, ObjectAllocator>:: ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::operator++() { ReturningTrueIterator::operator++() {
self_type i = *this; self_type i = *this;
count_value++; count_value++;
return i; return i;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
typename ObjectPool<T, ValuePool, ObjectAllocator>:: typename ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::self_type ObjectPool<T, ValuePool, ObjectAllocator>:: ReturningTrueIterator::self_type ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::operator++(int) { ReturningTrueIterator::operator++(int) {
count_value++; count_value++;
return *this; return *this;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
typename ObjectPool<T, ValuePool, ObjectAllocator>:: typename ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::reference ObjectPool<T, ValuePool, ObjectAllocator>:: ReturningTrueIterator::reference ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::operator*() { ReturningTrueIterator::operator*() {
return ret_value; return ret_value;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
typename ObjectPool<T, ValuePool, ObjectAllocator>:: typename ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::pointer ObjectPool<T, ValuePool, ObjectAllocator>:: ReturningTrueIterator::pointer ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::operator->() { ReturningTrueIterator::operator->() {
return &ret_value; return &ret_value;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
bool ObjectPool<T, ValuePool, ObjectAllocator>:: bool ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::operator==(const self_type& rhs) { ReturningTrueIterator::operator==(const self_type& rhs) {
return count_value == rhs.count_value; return count_value == rhs.count_value;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
bool ObjectPool<T, ValuePool, ObjectAllocator>:: bool ObjectPool<Type, ValuePool, ObjectAllocator>::
ReturningTrueIterator::operator!=(const self_type& rhs) { ReturningTrueIterator::operator!=(const self_type& rhs) {
return count_value != rhs.count_value; return count_value != rhs.count_value;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
bool ObjectPool<T, ValuePool, ObjectAllocator>:: bool ObjectPool<Type, ValuePool, ObjectAllocator>::
IsContained(const T &obj) const { IsContained(const Type &obj) const {
if ((&obj < &objects[0]) || (&obj > &objects[capacity - 1])) { if ((&obj < &objects[0]) || (&obj > &objects[capacity - 1])) {
return false; return false;
} else { } else {
...@@ -90,104 +90,104 @@ IsContained(const T &obj) const { ...@@ -90,104 +90,104 @@ IsContained(const T &obj) const {
} }
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
int ObjectPool<T, ValuePool, ObjectAllocator>:: int ObjectPool<Type, ValuePool, ObjectAllocator>::
GetIndexOfObject(const T &obj) const { GetIndexOfObject(const Type &obj) const {
assert(IsContained(obj)); assert(IsContained(obj));
return(static_cast<int>(&obj - &objects[0])); return(static_cast<int>(&obj - &objects[0]));
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
T* ObjectPool<T, ValuePool, ObjectAllocator>::AllocateRaw() { Type* ObjectPool<Type, ValuePool, ObjectAllocator>::AllocateRaw() {
bool val; bool val;
int allocated_index = p.Allocate(val); int allocated_index = p.Allocate(val);
if (allocated_index == -1) { if (allocated_index == -1) {
return NULL; return NULL;
} else { } else {
T* ret_pointer = &(objects[allocated_index]); Type* ret_pointer = &(objects[allocated_index]);
return ret_pointer; return ret_pointer;
} }
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
size_t ObjectPool<T, ValuePool, ObjectAllocator>::GetCapacity() { size_t ObjectPool<Type, ValuePool, ObjectAllocator>::GetCapacity() {
return capacity; return capacity;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
ObjectPool<T, ValuePool, ObjectAllocator>::ObjectPool(size_t capacity) : ObjectPool<Type, ValuePool, ObjectAllocator>::ObjectPool(size_t capacity) :
capacity(capacity), capacity(capacity),
p(ReturningTrueIterator(0), ReturningTrueIterator(capacity)) { p(ReturningTrueIterator(0), ReturningTrueIterator(capacity)) {
// Allocate the objects (without construction, just get the memory) // Allocate the objects (without construction, just get the memory)
objects = objectAllocator.allocate(capacity); objects = objectAllocator.allocate(capacity);
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
void ObjectPool<T, ValuePool, ObjectAllocator>::Free(T* obj) { void ObjectPool<Type, ValuePool, ObjectAllocator>::Free(Type* obj) {
int index = GetIndexOfObject(*obj); int index = GetIndexOfObject(*obj);
obj->~T(); obj->~Type();
p.Free(true, index); p.Free(true, index);
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
T* ObjectPool<T, ValuePool, ObjectAllocator>::Allocate() { Type* ObjectPool<Type, ValuePool, ObjectAllocator>::Allocate() {
T* rawObject = AllocateRaw(); Type* rawObject = AllocateRaw();
if (rawObject != NULL) if (rawObject != NULL)
new (rawObject)T(); new (rawObject)Type();
return rawObject; return rawObject;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
template<typename Param1> template<typename Param1>
T* ObjectPool<T, ValuePool, ObjectAllocator>::Allocate( Type* ObjectPool<Type, ValuePool, ObjectAllocator>::Allocate(
Param1 const& param1) { Param1 const& param1) {
T* rawObject = AllocateRaw(); Type* rawObject = AllocateRaw();
if (rawObject != NULL) if (rawObject != NULL)
new (rawObject)T(param1); new (rawObject)Type(param1);
return rawObject; return rawObject;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
template<typename Param1, typename Param2> template<typename Param1, typename Param2>
T* ObjectPool<T, ValuePool, ObjectAllocator>::Allocate( Type* ObjectPool<Type, ValuePool, ObjectAllocator>::Allocate(
Param1 const& param1, Param2 const& param2) { Param1 const& param1, Param2 const& param2) {
T* rawObject = AllocateRaw(); Type* rawObject = AllocateRaw();
if (rawObject != NULL) if (rawObject != NULL)
new (rawObject)T(param1, param2); new (rawObject)Type(param1, param2);
return rawObject; return rawObject;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
template<typename Param1, typename Param2, typename Param3> template<typename Param1, typename Param2, typename Param3>
T* ObjectPool<T, ValuePool, ObjectAllocator>::Allocate( Type* ObjectPool<Type, ValuePool, ObjectAllocator>::Allocate(
Param1 const& param1, Param2 const& param2, Param1 const& param1, Param2 const& param2,
Param3 const& param3) { Param3 const& param3) {
T* rawObject = AllocateRaw(); Type* rawObject = AllocateRaw();
if (rawObject != NULL) if (rawObject != NULL)
new (rawObject)T(param1, param2, param3); new (rawObject)Type(param1, param2, param3);
return rawObject; return rawObject;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
template<typename Param1, typename Param2, typename Param3, typename Param4> template<typename Param1, typename Param2, typename Param3, typename Param4>
T* ObjectPool<T, ValuePool, ObjectAllocator>::Allocate( Type* ObjectPool<Type, ValuePool, ObjectAllocator>::Allocate(
Param1 const& param1, Param2 const& param2, Param1 const& param1, Param2 const& param2,
Param3 const& param3, Param4 const& param4) { Param3 const& param3, Param4 const& param4) {
T* rawObject = AllocateRaw(); Type* rawObject = AllocateRaw();
if (rawObject != NULL) if (rawObject != NULL)
new (rawObject)T(param1, param2, param3, param4); new (rawObject)Type(param1, param2, param3, param4);
return rawObject; return rawObject;
} }
template<class T, typename ValuePool, class ObjectAllocator> template<class Type, typename ValuePool, class ObjectAllocator>
ObjectPool<T, ValuePool, ObjectAllocator>::~ObjectPool() { ObjectPool<Type, ValuePool, ObjectAllocator>::~ObjectPool() {
// Deallocate the objects // Deallocate the objects
objectAllocator.deallocate(objects, capacity); objectAllocator.deallocate(objects, capacity);
} }
......
...@@ -29,20 +29,20 @@ ...@@ -29,20 +29,20 @@
namespace embb { namespace embb {
namespace containers { namespace containers {
template<typename T, T Undefined, class Allocator > template<typename Type, Type Undefined, class Allocator >
void WaitFreeArrayValuePool<T, Undefined, Allocator>:: void WaitFreeArrayValuePool<Type, Undefined, Allocator>::
Free(T element, int index) { Free(Type element, int index) {
assert(element != Undefined); assert(element != Undefined);
// Just put back the element // Just put back the element
pool[index].Store(element); pool[index].Store(element);
} }
template<typename T, T Undefined, class Allocator > template<typename Type, Type Undefined, class Allocator >
int WaitFreeArrayValuePool<T, Undefined, Allocator>:: int WaitFreeArrayValuePool<Type, Undefined, Allocator>::
Allocate(T & element) { Allocate(Type & element) {
for (int i = 0; i != size; ++i) { for (int i = 0; i != size; ++i) {
T expected; Type expected;
// If the memory cell is not available, go ahead // If the memory cell is not available, go ahead
if (Undefined == (expected = pool[i].Load())) if (Undefined == (expected = pool[i].Load()))
...@@ -58,9 +58,9 @@ Allocate(T & element) { ...@@ -58,9 +58,9 @@ Allocate(T & element) {
return -1; return -1;
} }
template<typename T, T Undefined, class Allocator > template<typename Type, Type Undefined, class Allocator >
template<typename ForwardIterator> template<typename ForwardIterator>
WaitFreeArrayValuePool<T, Undefined, Allocator>:: WaitFreeArrayValuePool<Type, Undefined, Allocator>::
WaitFreeArrayValuePool(ForwardIterator first, ForwardIterator last) { WaitFreeArrayValuePool(ForwardIterator first, ForwardIterator last) {
size_t dist = static_cast<size_t>(std::distance(first, last)); size_t dist = static_cast<size_t>(std::distance(first, last));
...@@ -77,8 +77,8 @@ WaitFreeArrayValuePool(ForwardIterator first, ForwardIterator last) { ...@@ -77,8 +77,8 @@ WaitFreeArrayValuePool(ForwardIterator first, ForwardIterator last) {
} }
} }
template<typename T, T Undefined, class Allocator > template<typename Type, Type Undefined, class Allocator >
WaitFreeArrayValuePool<T, Undefined, Allocator>::~WaitFreeArrayValuePool() { WaitFreeArrayValuePool<Type, Undefined, Allocator>::~WaitFreeArrayValuePool() {
allocator.deallocate(pool, (size_t)size); allocator.deallocate(pool, (size_t)size);
} }
} // namespace containers } // namespace containers
......
...@@ -36,21 +36,21 @@ ...@@ -36,21 +36,21 @@
namespace embb { namespace embb {
namespace containers { namespace containers {
template<typename T, class Allocator> template<typename Type, class Allocator>
WaitFreeSPSCQueue<T, Allocator>::WaitFreeSPSCQueue(size_t capacity) : WaitFreeSPSCQueue<Type, Allocator>::WaitFreeSPSCQueue(size_t capacity) :
capacity(capacity), capacity(capacity),
head_index(0), head_index(0),
tail_index(0) { tail_index(0) {
queue_array = allocator.allocate(capacity); queue_array = allocator.allocate(capacity);
} }
template<typename T, class Allocator> template<typename Type, class Allocator>
size_t WaitFreeSPSCQueue<T, Allocator>::GetCapacity() { size_t WaitFreeSPSCQueue<Type, Allocator>::GetCapacity() {
return capacity; return capacity;
} }
template<typename T, class Allocator> template<typename Type, class Allocator>
bool WaitFreeSPSCQueue<T, Allocator>::TryEnqueue(T const & element) { bool WaitFreeSPSCQueue<Type, Allocator>::TryEnqueue(Type const & element) {
if (head_index - tail_index == capacity) if (head_index - tail_index == capacity)
return false; return false;
...@@ -59,19 +59,19 @@ bool WaitFreeSPSCQueue<T, Allocator>::TryEnqueue(T const & element) { ...@@ -59,19 +59,19 @@ bool WaitFreeSPSCQueue<T, Allocator>::TryEnqueue(T const & element) {
return true; return true;
} }
template<typename T, class Allocator> template<typename Type, class Allocator>
bool WaitFreeSPSCQueue<T, Allocator>::TryDequeue(T & element) { bool WaitFreeSPSCQueue<Type, Allocator>::TryDequeue(Type & element) {
if (tail_index - head_index == 0) if (tail_index - head_index == 0)
return false; return false;
T x = queue_array[head_index % capacity]; Type x = queue_array[head_index % capacity];
this->head_index++; this->head_index++;
element = x; element = x;
return true; return true;
} }
template<typename T, class Allocator> template<typename Type, class Allocator>
WaitFreeSPSCQueue<T, Allocator>::~WaitFreeSPSCQueue() { WaitFreeSPSCQueue<Type, Allocator>::~WaitFreeSPSCQueue() {
allocator.deallocate(queue_array, capacity); allocator.deallocate(queue_array, capacity);
} }
} // namespace containers } // namespace containers
......
...@@ -46,20 +46,20 @@ namespace internal { ...@@ -46,20 +46,20 @@ namespace internal {
* Single linked lists, contains the element (\c element) and a pointer to the * Single linked lists, contains the element (\c element) and a pointer to the
* next node (\c next). * next node (\c next).
* *
* \tparam T Element type * \tparam Type Element type
*/ */
template< typename T > template< typename Type >
class LockFreeMPMCQueueNode { class LockFreeMPMCQueueNode {
private: private:
/** /**
* Pointer to the next node * Pointer to the next node
*/ */
embb::base::Atomic< LockFreeMPMCQueueNode< T >* > next; embb::base::Atomic< LockFreeMPMCQueueNode< Type >* > next;
/** /**
* The stored element * The stored element
*/ */
T element; Type element;
public: public:
/** /**
...@@ -73,7 +73,7 @@ class LockFreeMPMCQueueNode { ...@@ -73,7 +73,7 @@ class LockFreeMPMCQueueNode {
* Creates a queue node * Creates a queue node
*/ */
LockFreeMPMCQueueNode( LockFreeMPMCQueueNode(
T const& element Type const& element
/**< [IN] The element of this queue node */); /**< [IN] The element of this queue node */);
/** /**
...@@ -81,12 +81,12 @@ class LockFreeMPMCQueueNode { ...@@ -81,12 +81,12 @@ class LockFreeMPMCQueueNode {
* *
* \return The next pointer * \return The next pointer
*/ */
embb::base::Atomic< LockFreeMPMCQueueNode< T >* > & GetNext(); embb::base::Atomic< LockFreeMPMCQueueNode< Type >* > & GetNext();
/** /**
* Returns the element held by this node * Returns the element held by this node
*/ */
T GetElement(); Type GetElement();
}; };
} // namespace internal } // namespace internal
...@@ -99,11 +99,11 @@ class LockFreeMPMCQueueNode { ...@@ -99,11 +99,11 @@ class LockFreeMPMCQueueNode {
* *
* \see WaitFreeSPSCQueue * \see WaitFreeSPSCQueue
* *
* \tparam T Type of the queue elements * \tparam Type Type of the queue elements
* \tparam ValuePool Type of the value pool used as basis for the ObjectPool * \tparam ValuePool Type of the value pool used as basis for the ObjectPool
* which stores the elements. * which stores the elements.
*/ */
template< typename T, template< typename Type,
typename ValuePool = embb::containers::LockFreeTreeValuePool < bool, false > typename ValuePool = embb::containers::LockFreeTreeValuePool < bool, false >
> >
class LockFreeMPMCQueue { class LockFreeMPMCQueue {
...@@ -120,35 +120,35 @@ class LockFreeMPMCQueue { ...@@ -120,35 +120,35 @@ class LockFreeMPMCQueue {
* Callback to the method that is called by hazard pointers if a pointer is * Callback to the method that is called by hazard pointers if a pointer is
* not hazardous anymore, i.e., can safely be reused. * not hazardous anymore, i.e., can safely be reused.
*/ */
embb::base::Function < void, internal::LockFreeMPMCQueueNode<T>* > embb::base::Function < void, internal::LockFreeMPMCQueueNode<Type>* >
delete_pointer_callback; delete_pointer_callback;
/** /**
* The hazard pointer object, used for memory management. * The hazard pointer object, used for memory management.
*/ */
embb::containers::internal::HazardPointer embb::containers::internal::HazardPointer
< internal::LockFreeMPMCQueueNode<T>* > hazardPointer; < internal::LockFreeMPMCQueueNode<Type>* > hazardPointer;
/** /**
* The object pool, used for lock-free memory allocation. * The object pool, used for lock-free memory allocation.
*/ */
ObjectPool< internal::LockFreeMPMCQueueNode<T>, ValuePool > objectPool; ObjectPool< internal::LockFreeMPMCQueueNode<Type>, ValuePool > objectPool;
/** /**
* Atomic pointer to the head node of the queue * Atomic pointer to the head node of the queue
*/ */
embb::base::Atomic< internal::LockFreeMPMCQueueNode<T>* > head; embb::base::Atomic< internal::LockFreeMPMCQueueNode<Type>* > head;
/** /**
* Atomic pointer to the tail node of the queue * Atomic pointer to the tail node of the queue
*/ */
embb::base::Atomic< internal::LockFreeMPMCQueueNode<T>* > tail; embb::base::Atomic< internal::LockFreeMPMCQueueNode<Type>* > tail;
/** /**
* The callback function, used to cleanup non-hazardous pointers. * The callback function, used to cleanup non-hazardous pointers.
* \see delete_pointer_callback * \see delete_pointer_callback
*/ */
void DeletePointerCallback(internal::LockFreeMPMCQueueNode<T>* to_delete); void DeletePointerCallback(internal::LockFreeMPMCQueueNode<Type>* to_delete);
public: public:
/** /**
...@@ -157,8 +157,8 @@ class LockFreeMPMCQueue { ...@@ -157,8 +157,8 @@ class LockFreeMPMCQueue {
* \memory * \memory
* Let \c t be the maximum number of threads and \c x be <tt>2.5*t+1</tt>. * Let \c t be the maximum number of threads and \c x be <tt>2.5*t+1</tt>.
* Then, <tt>x*(3*t+1)</tt> elements of size <tt>sizeof(void*)</tt>, \c x * Then, <tt>x*(3*t+1)</tt> elements of size <tt>sizeof(void*)</tt>, \c x
* elements of size <tt>sizeof(T)</tt>, and \c capacity+1 elements of size * elements of size <tt>sizeof(Type)</tt>, and \c capacity+1 elements of size
* <tt>sizeof(T)</tt> are allocated. * <tt>sizeof(Type)</tt> are allocated.
* *
* \notthreadsafe * \notthreadsafe
* *
...@@ -198,7 +198,7 @@ class LockFreeMPMCQueue { ...@@ -198,7 +198,7 @@ class LockFreeMPMCQueue {
* \see CPP_CONCEPTS_QUEUE * \see CPP_CONCEPTS_QUEUE
*/ */
bool TryEnqueue( bool TryEnqueue(
T const& element Type const& element
/**< [IN] Const reference to the element that shall be enqueued */); /**< [IN] Const reference to the element that shall be enqueued */);
/** /**
...@@ -212,7 +212,7 @@ class LockFreeMPMCQueue { ...@@ -212,7 +212,7 @@ class LockFreeMPMCQueue {
* \see CPP_CONCEPTS_QUEUE * \see CPP_CONCEPTS_QUEUE
*/ */
bool TryDequeue( bool TryDequeue(
T & element Type & element
/**< [IN, OUT] Reference to the dequeued element. /**< [IN, OUT] Reference to the dequeued element.
Unchanged, if the operation Unchanged, if the operation
was not successful. */); was not successful. */);
......
...@@ -53,9 +53,9 @@ ...@@ -53,9 +53,9 @@
* *
* \par Requirements * \par Requirements
* - Let \c Stack be the stack class * - Let \c Stack be the stack class
* - Let \c T be the element type of the stack * - Let \c Type be the element type of the stack
* - Let \c capacity be a value of type \c size_t * - Let \c capacity be a value of type \c size_t
* - Let \c element be a reference to an element of type \c T * - Let \c element be a reference to an element of type \c Type
* *
* \par Valid Expressions * \par Valid Expressions
* <table> * <table>
...@@ -65,11 +65,11 @@ ...@@ -65,11 +65,11 @@
* <th>Description</th> * <th>Description</th>
* </tr> * </tr>
* <tr> * <tr>
* <td>\code{.cpp} Stack<T>(capacity) \endcode</td> * <td>\code{.cpp} Stack<Type>(capacity) \endcode</td>
* <td>Nothing</td> * <td>Nothing</td>
* <td> * <td>
* Constructs a stack with capacity \c capacity that holds elements of * Constructs a stack with capacity \c capacity that holds elements of
* type \c T. * type \c Type.
* </td> * </td>
* </tr> * </tr>
* <tr> * <tr>
...@@ -165,11 +165,11 @@ class LockFreeStackNode { ...@@ -165,11 +165,11 @@ class LockFreeStackNode {
* *
* \ingroup CPP_CONTAINERS_STACKS * \ingroup CPP_CONTAINERS_STACKS
* *
* \tparam T Type of the stack elements * \tparam Type Type of the stack elements
* \tparam ValuePool Type of the value pool used as basis for the ObjectPool * \tparam ValuePool Type of the value pool used as basis for the ObjectPool
* which stores the elements. * which stores the elements.
*/ */
template< typename T, template< typename Type,
typename ValuePool = embb::containers::LockFreeTreeValuePool < bool, false > > typename ValuePool = embb::containers::LockFreeTreeValuePool < bool, false > >
class LockFreeStack { class LockFreeStack {
private: private:
...@@ -183,29 +183,29 @@ class LockFreeStack { ...@@ -183,29 +183,29 @@ class LockFreeStack {
* Callback to the method that is called by hazard pointers if a pointer is * Callback to the method that is called by hazard pointers if a pointer is
* not hazardous anymore, i.e., can safely be reused. * not hazardous anymore, i.e., can safely be reused.
*/ */
embb::base::Function<void, internal::LockFreeStackNode<T>*> embb::base::Function<void, internal::LockFreeStackNode<Type>*>
delete_pointer_callback; delete_pointer_callback;
/** /**
* The hazard pointer object, used for memory management. * The hazard pointer object, used for memory management.
*/ */
internal::HazardPointer<internal::LockFreeStackNode<T>*> hazardPointer; internal::HazardPointer<internal::LockFreeStackNode<Type>*> hazardPointer;
/** /**
* The callback function, used to cleanup non-hazardous pointers. * The callback function, used to cleanup non-hazardous pointers.
* \see delete_pointer_callback * \see delete_pointer_callback
*/ */
void DeletePointerCallback(internal::LockFreeStackNode<T>* to_delete); void DeletePointerCallback(internal::LockFreeStackNode<Type>* to_delete);
/** /**
* The object pool, used for lock-free memory allocation. * The object pool, used for lock-free memory allocation.
*/ */
ObjectPool< internal::LockFreeStackNode<T>, ValuePool > objectPool; ObjectPool< internal::LockFreeStackNode<Type>, ValuePool > objectPool;
/** /**
* Atomic pointer to the top node of the stack (element that is popped next) * Atomic pointer to the top node of the stack (element that is popped next)
*/ */
embb::base::Atomic<internal::LockFreeStackNode<T>*> top; embb::base::Atomic<internal::LockFreeStackNode<Type>*> top;
public: public:
/** /**
...@@ -214,8 +214,8 @@ class LockFreeStack { ...@@ -214,8 +214,8 @@ class LockFreeStack {
* \memory * \memory
* Let \c t be the maximum number of threads and \c x be <tt>1.25*t+1</tt>. * Let \c t be the maximum number of threads and \c x be <tt>1.25*t+1</tt>.
* Then, <tt>x*(3*t+1)</tt> elements of size <tt>sizeof(void*)</tt>, \c x * Then, <tt>x*(3*t+1)</tt> elements of size <tt>sizeof(void*)</tt>, \c x
* elements of size <tt>sizeof(T)</tt>, and \c capacity elements of size * elements of size <tt>sizeof(Type)</tt>, and \c capacity elements of size
* <tt>sizeof(T)</tt> are allocated. * <tt>sizeof(Type)</tt> are allocated.
* *
* \notthreadsafe * \notthreadsafe
* *
...@@ -256,7 +256,7 @@ class LockFreeStack { ...@@ -256,7 +256,7 @@ class LockFreeStack {
* \see CPP_CONCEPTS_STACK * \see CPP_CONCEPTS_STACK
*/ */
bool TryPush( bool TryPush(
T const& element Type const& element
/**< [IN] Const reference to the element that shall be pushed */ /**< [IN] Const reference to the element that shall be pushed */
); );
...@@ -271,7 +271,7 @@ class LockFreeStack { ...@@ -271,7 +271,7 @@ class LockFreeStack {
* \see CPP_CONCEPTS_STACK * \see CPP_CONCEPTS_STACK
*/ */
bool TryPop( bool TryPop(
T & element Type & element
/**< [IN,OUT] Reference to the popped element. Unchanged, if the operation /**< [IN,OUT] Reference to the popped element. Unchanged, if the operation
was not successful. */ was not successful. */
); );
......
...@@ -41,15 +41,15 @@ namespace containers { ...@@ -41,15 +41,15 @@ namespace containers {
* *
* \see WaitFreeArrayValuePool * \see WaitFreeArrayValuePool
* *
* \tparam T Element type (must support atomic operations such as \c int). * \tparam Type Element type (must support atomic operations such as \c int).
* \tparam Undefined Bottom element (cannot be stored in the pool) * \tparam Undefined Bottom element (cannot be stored in the pool)
* \tparam PoolAllocator Allocator used to allocate the pool array * \tparam PoolAllocator Allocator used to allocate the pool array
* \tparam TreeAllocator Allocator used to allocate the array representing the * \tparam TreeAllocator Allocator used to allocate the array representing the
* binary tree. * binary tree.
*/ */
template<typename T, template<typename Type,
T Undefined, Type Undefined,
class PoolAllocator = embb::base::Allocator< embb::base::Atomic<T> >, class PoolAllocator = embb::base::Allocator< embb::base::Atomic<Type> >,
class TreeAllocator = embb::base::Allocator < embb::base::Atomic<int> > class TreeAllocator = embb::base::Allocator < embb::base::Atomic<int> >
> >
class LockFreeTreeValuePool { class LockFreeTreeValuePool {
...@@ -95,7 +95,7 @@ class LockFreeTreeValuePool { ...@@ -95,7 +95,7 @@ class LockFreeTreeValuePool {
* *
* The algorithm for allocating an element starts at the root node and * The algorithm for allocating an element starts at the root node and
* recursively traverses the tree. It tries to decrement a node (a decrement * recursively traverses the tree. It tries to decrement a node (a decrement
* is actually a conditional decrement, i.e., a node is decremented iff the * is actually a conditional decrement, i.e., a node is decremented if the
* result is not less than 0. This is the place, where the algorithm is not * result is not less than 0. This is the place, where the algorithm is not
* wait-free anymore, as this cannot be implemented atomically.) and if * wait-free anymore, as this cannot be implemented atomically.) and if
* successful, calls itself on the left child, if not successful, on the right * successful, calls itself on the left child, if not successful, on the right
...@@ -135,7 +135,7 @@ class LockFreeTreeValuePool { ...@@ -135,7 +135,7 @@ class LockFreeTreeValuePool {
embb::base::Atomic<int>* tree; embb::base::Atomic<int>* tree;
// The actual pool // The actual pool
embb::base::Atomic<T>* pool; embb::base::Atomic<Type>* pool;
PoolAllocator poolAllocator; PoolAllocator poolAllocator;
TreeAllocator treeAllocator; TreeAllocator treeAllocator;
...@@ -235,7 +235,7 @@ class LockFreeTreeValuePool { ...@@ -235,7 +235,7 @@ class LockFreeTreeValuePool {
int allocate_rec( int allocate_rec(
int node, int node,
/**< [IN] Node index */ /**< [IN] Node index */
T& element Type& element
/**< [IN,OUT] Allocated element, if there is any */ /**< [IN,OUT] Allocated element, if there is any */
); );
...@@ -260,8 +260,8 @@ class LockFreeTreeValuePool { ...@@ -260,8 +260,8 @@ class LockFreeTreeValuePool {
* *
* \memory Let <tt>n = \c std::distance(first, last))</tt> and \c k be the * \memory Let <tt>n = \c std::distance(first, last))</tt> and \c k be the
* minimum number such that <tt>n <= 2^k holds</tt>. Then, * minimum number such that <tt>n <= 2^k holds</tt>. Then,
* <tt>((2^k)-1) * sizeof(embb::Atomic<int>) + n*sizeof(embb::Atomic<T>)</tt> * <tt>((2^k)-1) * sizeof(embb::Atomic<int>) +
* bytes of memory are allocated. * n*sizeof(embb::Atomic<Type>)</tt> bytes of memory are allocated.
* *
* \notthreadsafe * \notthreadsafe
* *
...@@ -294,7 +294,7 @@ class LockFreeTreeValuePool { ...@@ -294,7 +294,7 @@ class LockFreeTreeValuePool {
* \see CPP_CONCEPTS_VALUE_POOL * \see CPP_CONCEPTS_VALUE_POOL
*/ */
int Allocate( int Allocate(
T & element Type & element
/**< [IN,OUT] Reference to the allocated element. Unchanged, if the /**< [IN,OUT] Reference to the allocated element. Unchanged, if the
operation was not successful. */ operation was not successful. */
); );
...@@ -309,7 +309,7 @@ class LockFreeTreeValuePool { ...@@ -309,7 +309,7 @@ class LockFreeTreeValuePool {
* \see CPP_CONCEPTS_VALUE_POOL * \see CPP_CONCEPTS_VALUE_POOL
*/ */
void Free( void Free(
T element, Type element,
/**< [IN] Element to be returned to the pool */ /**< [IN] Element to be returned to the pool */
int index int index
/**< [IN] Index of the element as obtained by Allocate() */ /**< [IN] Index of the element as obtained by Allocate() */
......
...@@ -48,15 +48,15 @@ namespace containers { ...@@ -48,15 +48,15 @@ namespace containers {
* *
* \ingroup CPP_CONTAINERS_POOLS * \ingroup CPP_CONTAINERS_POOLS
* *
* \tparam T Element type * \tparam Type Element type
* \tparam ValuePool Type of the underlying value pool, determines whether * \tparam ValuePool Type of the underlying value pool, determines whether
* the object pool is wait-free or lock-free * the object pool is wait-free or lock-free
* \tparam ObjectAllocator Type of allocator used to allocate objects * \tparam ObjectAllocator Type of allocator used to allocate objects
*/ */
template<class T, template<class Type,
typename ValuePool = typename ValuePool =
embb::containers::WaitFreeArrayValuePool< bool, false >, embb::containers::WaitFreeArrayValuePool< bool, false >,
class ObjectAllocator = embb::base::Allocator<T> > class ObjectAllocator = embb::base::Allocator<Type> >
class ObjectPool { class ObjectPool {
private: private:
/** /**
...@@ -67,7 +67,7 @@ class ObjectPool { ...@@ -67,7 +67,7 @@ class ObjectPool {
/** /**
* Array holding the allocated object * Array holding the allocated object
*/ */
T* objects; Type* objects;
/** /**
* Capacity of the object pool * Capacity of the object pool
...@@ -105,15 +105,15 @@ class ObjectPool { ...@@ -105,15 +105,15 @@ class ObjectPool {
bool ret_value; bool ret_value;
}; };
bool IsContained(const T &obj) const; bool IsContained(const Type &obj) const;
int GetIndexOfObject(const T &obj) const; int GetIndexOfObject(const Type &obj) const;
T* AllocateRaw(); Type* AllocateRaw();
public: public:
/** /**
* Constructs an object pool with capacity \c capacity. * Constructs an object pool with capacity \c capacity.
* *
* \memory Allocates \c capacity elements of type \c T. * \memory Allocates \c capacity elements of type \c Type.
* *
* \notthreadsafe * \notthreadsafe
*/ */
...@@ -147,7 +147,7 @@ class ObjectPool { ...@@ -147,7 +147,7 @@ class ObjectPool {
* \note The element must have been allocated with Allocate(). * \note The element must have been allocated with Allocate().
*/ */
void Free( void Free(
T* obj Type* obj
/**< [IN] Pointer to the object to be freed */ /**< [IN] Pointer to the object to be freed */
); );
...@@ -162,22 +162,22 @@ class ObjectPool { ...@@ -162,22 +162,22 @@ class ObjectPool {
* *
* \param ... Arguments of arbitrary type, passed to the object's constructor * \param ... Arguments of arbitrary type, passed to the object's constructor
*/ */
T* Allocate(...); Type* Allocate(...);
#else #else
T* Allocate(); Type* Allocate();
template<typename Param1> template<typename Param1>
T* Allocate(Param1 const& param1); Type* Allocate(Param1 const& param1);
template<typename Param1, typename Param2> template<typename Param1, typename Param2>
T* Allocate(Param1 const& param1, Param2 const& param2); Type* Allocate(Param1 const& param1, Param2 const& param2);
template<typename Param1, typename Param2, typename Param3> template<typename Param1, typename Param2, typename Param3>
T* Allocate(Param1 const& param1, Param2 const& param2, Type* Allocate(Param1 const& param1, Param2 const& param2,
Param3 const& param3); Param3 const& param3);
template<typename Param1, typename Param2, typename Param3, typename Param4> template<typename Param1, typename Param2, typename Param3, typename Param4>
T* Allocate(Param1 const& param1, Param2 const& param2, Type* Allocate(Param1 const& param1, Param2 const& param2,
Param3 const& param3, Param4 const& param4); Param3 const& param3, Param4 const& param4);
#endif #endif
......
...@@ -48,11 +48,11 @@ namespace containers { ...@@ -48,11 +48,11 @@ namespace containers {
* *
* \par Requirements * \par Requirements
* - Let \c Pool be the pool class * - Let \c Pool be the pool class
* - Let \c T be the element type of the pool. Atomic operations must be * - Let \c Type be the element type of the pool. Atomic operations must be
* possible on \c T. * possible on \c Type.
* - Let \c b, d be objects of type \c T * - Let \c b, d be objects of type \c Type
* - Let \c i, j be forward iterators supporting \c std::distance. * - Let \c i, j be forward iterators supporting \c std::distance.
* - Let \c c be an object of type \c T& * - Let \c c be an object of type \c Type&
* - Let \c e be a value of type \c int * - Let \c e be a value of type \c int
* *
* \par Valid Expressions * \par Valid Expressions
...@@ -64,13 +64,13 @@ namespace containers { ...@@ -64,13 +64,13 @@ namespace containers {
* <th>Description</th> * <th>Description</th>
* </tr> * </tr>
* <tr> * <tr>
* <td>\code{.cpp} Pool<T, b>(i, j) \endcode * <td>\code{.cpp} Pool<Type, b>(i, j) \endcode
* </td> * </td>
* <td>Nothing</td> * <td>Nothing</td>
* <td> * <td>
* Constructs a value pool holding elements of type \c T, where \c b is the * Constructs a value pool holding elements of type \c Type, where \c b is
* bottom element. The bottom element cannot be stored in the pool, it is * the bottom element. The bottom element cannot be stored in the pool, it
* exclusively used to mark empty cells. The pool initially contains * is exclusively used to mark empty cells. The pool initially contains
* \c std::distance(i, j) elements which are copied during construction from * \c std::distance(i, j) elements which are copied during construction from
* the range \c [i, j). A concrete class satisfying the value pool concept * the range \c [i, j). A concrete class satisfying the value pool concept
* might provide additional template parameters for specifying allocators. * might provide additional template parameters for specifying allocators.
...@@ -107,17 +107,17 @@ namespace containers { ...@@ -107,17 +107,17 @@ namespace containers {
* *
* \see LockFreeTreeValuePool * \see LockFreeTreeValuePool
* *
* \tparam T Element type (must support atomic operations such as \c int). * \tparam Type Element type (must support atomic operations such as \c int).
* \tparam Undefined Bottom element (cannot be stored in the pool) * \tparam Undefined Bottom element (cannot be stored in the pool)
* \tparam Allocator Allocator used to allocate the pool array * \tparam Allocator Allocator used to allocate the pool array
*/ */
template<typename T, template<typename Type,
T Undefined, Type Undefined,
class Allocator = embb::base::Allocator< embb::base::Atomic<T> > > class Allocator = embb::base::Allocator< embb::base::Atomic<Type> > >
class WaitFreeArrayValuePool { class WaitFreeArrayValuePool {
private: private:
int size; int size;
embb::base::Atomic<T>* pool; embb::base::Atomic<Type>* pool;
WaitFreeArrayValuePool(); WaitFreeArrayValuePool();
Allocator allocator; Allocator allocator;
...@@ -131,7 +131,7 @@ class WaitFreeArrayValuePool { ...@@ -131,7 +131,7 @@ class WaitFreeArrayValuePool {
/** /**
* Constructs a pool and fills it with the elements in the specified range. * Constructs a pool and fills it with the elements in the specified range.
* *
* \memory Dynamically allocates <tt>n*sizeof(embb::base::Atomic<T>)</tt> * \memory Dynamically allocates <tt>n*sizeof(embb::base::Atomic<Type>)</tt>
* bytes, where <tt>n = std::distance(first, last)</tt> is the number * bytes, where <tt>n = std::distance(first, last)</tt> is the number
* of pool elements. * of pool elements.
* *
...@@ -166,7 +166,7 @@ class WaitFreeArrayValuePool { ...@@ -166,7 +166,7 @@ class WaitFreeArrayValuePool {
* \see CPP_CONCEPTS_VALUE_POOL * \see CPP_CONCEPTS_VALUE_POOL
*/ */
int Allocate( int Allocate(
T & element Type & element
/**< [IN,OUT] Reference to the allocated element. Unchanged, if the /**< [IN,OUT] Reference to the allocated element. Unchanged, if the
operation was not successful. */ operation was not successful. */
); );
...@@ -181,7 +181,7 @@ class WaitFreeArrayValuePool { ...@@ -181,7 +181,7 @@ class WaitFreeArrayValuePool {
* \see CPP_CONCEPTS_VALUE_POOL * \see CPP_CONCEPTS_VALUE_POOL
*/ */
void Free( void Free(
T element, Type element,
/**< [IN] Element to be returned to the pool */ /**< [IN] Element to be returned to the pool */
int index int index
/**< [IN] Index of the element as obtained by Allocate() */ /**< [IN] Index of the element as obtained by Allocate() */
......
...@@ -53,9 +53,9 @@ ...@@ -53,9 +53,9 @@
* *
* \par Requirements * \par Requirements
* - Let \c Queue be the queue class * - Let \c Queue be the queue class
* - Let \c T be the element type of the queue * - Let \c Type be the element type of the queue
* - Let \c capacity be a value of type \c size_t * - Let \c capacity be a value of type \c size_t
* - Let \c element be a reference to an element of type \c T * - Let \c element be a reference to an element of type \c Type
* *
* \par Valid Expressions * \par Valid Expressions
* <table> * <table>
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
* <th>Description</th> * <th>Description</th>
* </tr> * </tr>
* <tr> * <tr>
* <td>\code{.cpp} Queue<T>(capacity) \endcode</td> * <td>\code{.cpp} Queue<Type>(capacity) \endcode</td>
* <td>Nothing</td> * <td>Nothing</td>
* <td> * <td>
* Constructs a queue with capacity \c capacity that holds elements of * Constructs a queue with capacity \c capacity that holds elements of
...@@ -114,10 +114,10 @@ namespace containers { ...@@ -114,10 +114,10 @@ namespace containers {
* *
* \see LockFreeMPMCQueue * \see LockFreeMPMCQueue
* *
* \tparam T Type of the queue elements * \tparam Type Type of the queue elements
* \tparam Allocator Allocator type for allocating queue elements. * \tparam Allocator Allocator type for allocating queue elements.
*/ */
template<typename T, class Allocator = embb::base::Allocator< T > > template<typename Type, class Allocator = embb::base::Allocator< Type > >
class WaitFreeSPSCQueue { class WaitFreeSPSCQueue {
private: private:
/** /**
...@@ -133,7 +133,7 @@ class WaitFreeSPSCQueue { ...@@ -133,7 +133,7 @@ class WaitFreeSPSCQueue {
/** /**
* Array holding the queue elements * Array holding the queue elements
*/ */
T* queue_array; Type* queue_array;
/** /**
* Index of the head in the \c queue_array * Index of the head in the \c queue_array
...@@ -149,7 +149,7 @@ class WaitFreeSPSCQueue { ...@@ -149,7 +149,7 @@ class WaitFreeSPSCQueue {
/** /**
* Creates a queue with the specified capacity. * Creates a queue with the specified capacity.
* *
* \memory Allocates \c capacity elements of type \c T. * \memory Allocates \c capacity elements of type \c Type.
* *
* \notthreadsafe * \notthreadsafe
* *
...@@ -190,7 +190,7 @@ class WaitFreeSPSCQueue { ...@@ -190,7 +190,7 @@ class WaitFreeSPSCQueue {
* \see CPP_CONCEPTS_QUEUE * \see CPP_CONCEPTS_QUEUE
*/ */
bool TryEnqueue( bool TryEnqueue(
T const & element Type const & element
/**< [IN] Const reference to the element that shall be enqueued */ /**< [IN] Const reference to the element that shall be enqueued */
); );
...@@ -208,9 +208,9 @@ class WaitFreeSPSCQueue { ...@@ -208,9 +208,9 @@ class WaitFreeSPSCQueue {
* \see CPP_CONCEPTS_QUEUE * \see CPP_CONCEPTS_QUEUE
*/ */
bool TryDequeue( bool TryDequeue(
T & element Type & element
/**< [IN,OUT] Reference to the dequeued element. Unchanged, if the operation /**< [IN,OUT] Reference to the dequeued element. Unchanged, if the
was not successful. */ operation was not successful. */
); );
}; };
} // namespace containers } // namespace containers
......
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