Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
FORMUS3IC_LAS3
/
embb
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
8b6b7369
authored
Jan 26, 2015
by
Marcus Winter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
containers_cpp: revised template argument names
parent
8af3d2c0
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
254 additions
and
239 deletions
+254
-239
containers_cpp/include/embb/containers/internal/lock_free_mpmc_queue-inl.h
+25
-24
containers_cpp/include/embb/containers/internal/lock_free_stack-inl.h
+18
-18
containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h
+46
-32
containers_cpp/include/embb/containers/internal/object_pool-inl.h
+56
-56
containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h
+11
-11
containers_cpp/include/embb/containers/internal/wait_free_spsc_queue-inl.h
+11
-11
containers_cpp/include/embb/containers/lock_free_mpmc_queue.h
+19
-19
containers_cpp/include/embb/containers/lock_free_stack.h
+15
-15
containers_cpp/include/embb/containers/lock_free_tree_value_pool.h
+11
-11
containers_cpp/include/embb/containers/object_pool.h
+15
-15
containers_cpp/include/embb/containers/wait_free_array_value_pool.h
+16
-16
containers_cpp/include/embb/containers/wait_free_spsc_queue.h
+11
-11
No files found.
containers_cpp/include/embb/containers/internal/lock_free_mpmc_queue-inl.h
View file @
8b6b7369
...
...
@@ -62,19 +62,19 @@ T LockFreeMPMCQueueNode<T>::GetElement() {
}
}
// namespace internal
template
<
typename
T
,
typename
ValuePool
>
void
LockFreeMPMCQueue
<
T
,
ValuePool
>::
DeletePointerCallback
(
internal
::
LockFreeMPMCQueueNode
<
T
>*
to_delete
)
{
template
<
typename
T
ype
,
typename
ValuePool
>
void
LockFreeMPMCQueue
<
T
ype
,
ValuePool
>::
DeletePointerCallback
(
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
to_delete
)
{
objectPool
.
Free
(
to_delete
);
}
template
<
typename
T
,
typename
ValuePool
>
LockFreeMPMCQueue
<
T
,
ValuePool
>::~
LockFreeMPMCQueue
()
{
template
<
typename
T
ype
,
typename
ValuePool
>
LockFreeMPMCQueue
<
T
ype
,
ValuePool
>::~
LockFreeMPMCQueue
()
{
// Nothing to do here, did not allocate anything.
}
template
<
typename
T
,
typename
ValuePool
>
LockFreeMPMCQueue
<
T
,
ValuePool
>::
LockFreeMPMCQueue
(
size_t
capacity
)
:
template
<
typename
T
ype
,
typename
ValuePool
>
LockFreeMPMCQueue
<
T
ype
,
ValuePool
>::
LockFreeMPMCQueue
(
size_t
capacity
)
:
capacity
(
capacity
),
// Disable "this is used in base member initializer" warning.
// We explicitly want this.
...
...
@@ -82,7 +82,8 @@ capacity(capacity),
#pragma warning(push)
#pragma warning(disable:4355)
#endif
delete_pointer_callback
(
*
this
,
&
LockFreeMPMCQueue
<
T
>::
DeletePointerCallback
),
delete_pointer_callback
(
*
this
,
&
LockFreeMPMCQueue
<
Type
>::
DeletePointerCallback
),
#ifdef _MSC_VER
#pragma warning(pop)
#endif
...
...
@@ -94,26 +95,26 @@ capacity(capacity),
embb
::
base
::
Thread
::
GetThreadsMaxCount
()
+
capacity
+
1
)
{
// Allocate dummy node to reduce the number of special cases to consider.
internal
::
LockFreeMPMCQueueNode
<
T
>*
dummyNode
=
objectPool
.
Allocate
();
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
dummyNode
=
objectPool
.
Allocate
();
// Initially, head and tail point to the dummy node.
head
=
dummyNode
;
tail
=
dummyNode
;
}
template
<
typename
T
,
typename
ValuePool
>
size_t
LockFreeMPMCQueue
<
T
,
ValuePool
>::
GetCapacity
()
{
template
<
typename
T
ype
,
typename
ValuePool
>
size_t
LockFreeMPMCQueue
<
T
ype
,
ValuePool
>::
GetCapacity
()
{
return
capacity
;
}
template
<
typename
T
,
typename
ValuePool
>
bool
LockFreeMPMCQueue
<
T
,
ValuePool
>::
TryEnqueue
(
T
const
&
element
)
{
template
<
typename
T
ype
,
typename
ValuePool
>
bool
LockFreeMPMCQueue
<
T
ype
,
ValuePool
>::
TryEnqueue
(
Type
const
&
element
)
{
// Get node from the pool containing element to enqueue.
internal
::
LockFreeMPMCQueueNode
<
T
>*
node
=
objectPool
.
Allocate
(
element
);
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
node
=
objectPool
.
Allocate
(
element
);
// Queue full, cannot enqueue
if
(
node
==
NULL
)
return
false
;
internal
::
LockFreeMPMCQueueNode
<
T
>*
my_tail
;
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
my_tail
;
for
(;;)
{
my_tail
=
tail
;
...
...
@@ -124,14 +125,14 @@ bool LockFreeMPMCQueue<T, ValuePool>::TryEnqueue(T const& element) {
continue
;
// Hazard pointer outdated, retry
}
internal
::
LockFreeMPMCQueueNode
<
T
>*
my_tail_next
=
my_tail
->
GetNext
();
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
my_tail_next
=
my_tail
->
GetNext
();
if
(
my_tail
==
tail
)
{
// 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
// tail node to our new node.
if
(
my_tail_next
==
NULL
)
{
internal
::
LockFreeMPMCQueueNode
<
T
>*
expected
=
NULL
;
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
expected
=
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.
if
(
my_tail
->
GetNext
().
CompareAndSwap
(
expected
,
node
))
...
...
@@ -151,13 +152,13 @@ bool LockFreeMPMCQueue<T, ValuePool>::TryEnqueue(T const& element) {
return
true
;
}
template
<
typename
T
,
typename
ValuePool
>
bool
LockFreeMPMCQueue
<
T
,
ValuePool
>::
TryDequeue
(
T
&
element
)
{
internal
::
LockFreeMPMCQueueNode
<
T
>*
my_head
;
internal
::
LockFreeMPMCQueueNode
<
T
>*
my_tail
;
internal
::
LockFreeMPMCQueueNode
<
T
>*
my_next
;
internal
::
LockFreeMPMCQueueNode
<
T
>*
expected
;
T
data
;
template
<
typename
T
ype
,
typename
ValuePool
>
bool
LockFreeMPMCQueue
<
T
ype
,
ValuePool
>::
TryDequeue
(
Type
&
element
)
{
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
my_head
;
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
my_tail
;
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
my_next
;
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
expected
;
T
ype
data
;
for
(;;)
{
my_head
=
head
;
hazardPointer
.
GuardPointer
(
0
,
my_head
);
...
...
containers_cpp/include/embb/containers/internal/lock_free_stack-inl.h
View file @
8b6b7369
...
...
@@ -59,14 +59,14 @@ namespace internal {
}
}
// namespace internal
template
<
typename
T
,
typename
ValuePool
>
void
LockFreeStack
<
T
,
ValuePool
>::
DeletePointerCallback
(
internal
::
LockFreeStackNode
<
T
>*
to_delete
)
{
template
<
typename
T
ype
,
typename
ValuePool
>
void
LockFreeStack
<
T
ype
,
ValuePool
>::
DeletePointerCallback
(
internal
::
LockFreeStackNode
<
T
ype
>*
to_delete
)
{
objectPool
.
Free
(
to_delete
);
}
template
<
typename
T
,
typename
ValuePool
>
LockFreeStack
<
T
,
ValuePool
>::
LockFreeStack
(
size_t
capacity
)
:
template
<
typename
T
ype
,
typename
ValuePool
>
LockFreeStack
<
T
ype
,
ValuePool
>::
LockFreeStack
(
size_t
capacity
)
:
capacity
(
capacity
),
// Disable "this is used in base member initializer" warning.
// We explicitly want this.
...
...
@@ -75,7 +75,7 @@ capacity(capacity),
#pragma warning(disable:4355)
#endif
delete_pointer_callback
(
*
this
,
&
LockFreeStack
<
T
>::
DeletePointerCallback
),
&
LockFreeStack
<
Type
>::
DeletePointerCallback
),
#ifdef _MSC_VER
#pragma warning(pop)
#endif
...
...
@@ -88,19 +88,19 @@ capacity(capacity),
capacity
)
{
}
template
<
typename
T
,
typename
ValuePool
>
size_t
LockFreeStack
<
T
,
ValuePool
>::
GetCapacity
()
{
template
<
typename
T
ype
,
typename
ValuePool
>
size_t
LockFreeStack
<
T
ype
,
ValuePool
>::
GetCapacity
()
{
return
capacity
;
}
template
<
typename
T
,
typename
ValuePool
>
LockFreeStack
<
T
,
ValuePool
>::~
LockFreeStack
()
{
template
<
typename
T
ype
,
typename
ValuePool
>
LockFreeStack
<
T
ype
,
ValuePool
>::~
LockFreeStack
()
{
// Nothing to do here, did not allocate anything.
}
template
<
typename
T
,
typename
ValuePool
>
bool
LockFreeStack
<
T
,
ValuePool
>::
TryPush
(
T
const
&
element
)
{
internal
::
LockFreeStackNode
<
T
>*
newNode
=
template
<
typename
T
ype
,
typename
ValuePool
>
bool
LockFreeStack
<
T
ype
,
ValuePool
>::
TryPush
(
Type
const
&
element
)
{
internal
::
LockFreeStackNode
<
T
ype
>*
newNode
=
objectPool
.
Allocate
(
element
);
// Stack full, cannot push
...
...
@@ -108,16 +108,16 @@ bool LockFreeStack< T, ValuePool >::TryPush(T const& element) {
return
false
;
for
(;;)
{
internal
::
LockFreeStackNode
<
T
>*
top_cached
=
top
;
internal
::
LockFreeStackNode
<
T
ype
>*
top_cached
=
top
;
newNode
->
SetNext
(
top_cached
);
if
(
top
.
CompareAndSwap
(
top_cached
,
newNode
))
return
true
;
}
}
template
<
typename
T
,
typename
ValuePool
>
bool
LockFreeStack
<
T
,
ValuePool
>::
TryPop
(
T
&
element
)
{
internal
::
LockFreeStackNode
<
T
>*
top_cached
=
top
;
template
<
typename
T
ype
,
typename
ValuePool
>
bool
LockFreeStack
<
T
ype
,
ValuePool
>::
TryPop
(
Type
&
element
)
{
internal
::
LockFreeStackNode
<
T
ype
>*
top_cached
=
top
;
for
(;;)
{
top_cached
=
top
;
...
...
@@ -146,7 +146,7 @@ bool LockFreeStack< T, ValuePool >::TryPop(T & element) {
}
}
T
data
=
top_cached
->
GetElement
();
T
ype
data
=
top_cached
->
GetElement
();
// We don't need to read from this reference anymore, unguard it
hazardPointer
.
GuardPointer
(
0
,
NULL
);
...
...
containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h
View file @
8b6b7369
...
...
@@ -29,39 +29,44 @@
namespace
embb
{
namespace
containers
{
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
GetSmallestPowerByTwoValue
(
int
value
)
{
int
result
=
1
;
while
(
result
<
value
)
result
<<=
1
;
return
result
;
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
bool
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
IsLeaf
(
int
node
)
{
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
bool
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
IsLeaf
(
int
node
)
{
if
(
node
>=
size
-
1
&&
node
<=
2
*
size
-
1
)
{
return
true
;
}
return
false
;
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
bool
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
bool
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
IsValid
(
int
node
)
{
return
(
node
>=
0
&&
node
<=
2
*
size
-
1
);
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
GetLeftChildIndex
(
int
node
)
{
int
index
=
2
*
node
+
1
;
assert
(
IsValid
(
index
));
return
index
;
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
GetRightChildIndex
(
int
node
)
{
int
index
=
2
*
node
+
2
;
assert
(
IsValid
(
index
));
...
...
@@ -75,16 +80,18 @@ NodeIndexToPoolIndex(int node) {
return
(
node
-
(
size
-
1
));
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
PoolIndexToNodeIndex
(
int
index
)
{
int
node
=
index
+
(
size
-
1
);
assert
(
IsLeaf
(
node
));
return
node
;
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
bool
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
bool
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
IsRoot
(
int
node
)
{
return
(
0
==
node
);
}
...
...
@@ -97,14 +104,15 @@ GetParentNode(int node) {
return
parent
;
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
allocate_rec
(
int
node
,
T
&
element
)
{
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
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
(
IsLeaf
(
node
))
{
int
pool_index
=
NodeIndexToPoolIndex
(
node
);
T
expected
=
pool
[
pool_index
];
T
ype
expected
=
pool
[
pool_index
];
if
(
expected
==
Undefined
)
return
-
1
;
...
...
@@ -120,7 +128,7 @@ allocate_rec(int node, T& element) {
int
desired
;
// Try to decrement node value.
// This is the point, where the algorithm becomes not wait-free. We have to
// atomically decrement the value in the node if
f
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.
do
{
current
=
tree
[
node
];
...
...
@@ -141,8 +149,9 @@ allocate_rec(int node, T& element) {
return
rightResult
;
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
void
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
void
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
Fill
(
int
node
,
int
elementsToStore
,
int
power2Value
)
{
if
(
IsLeaf
(
node
))
return
;
...
...
@@ -165,15 +174,17 @@ Fill(int node, int elementsToStore, int power2Value) {
}
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
Allocate
(
T
&
element
)
{
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
int
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
Allocate
(
Type
&
element
)
{
return
allocate_rec
(
0
,
element
);
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
void
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
Free
(
T
element
,
int
index
)
{
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
void
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
Free
(
Type
element
,
int
index
)
{
assert
(
element
!=
Undefined
);
// Put the element back
...
...
@@ -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
>
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
LockFreeTreeValuePool
<
T
ype
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
LockFreeTreeValuePool
(
ForwardIterator
first
,
ForwardIterator
last
)
{
// Number of elements to store
real_size
=
static_cast
<
int
>
(
::
std
::
distance
(
first
,
last
));
...
...
@@ -218,12 +230,14 @@ LockFreeTreeValuePool(ForwardIterator first, ForwardIterator last) {
Fill
(
0
,
static_cast
<
int
>
(
::
std
::
distance
(
first
,
last
)),
size
);
}
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
LockFreeTreeValuePool
<
T
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
template
<
typename
Type
,
Type
Undefined
,
class
PoolAllocator
,
class
TreeAllocator
>
LockFreeTreeValuePool
<
Type
,
Undefined
,
PoolAllocator
,
TreeAllocator
>::
~
LockFreeTreeValuePool
()
{
poolAllocator
.
deallocate
(
pool
,
static_cast
<
size_t
>
(
real_size
));
treeAllocator
.
deallocate
(
tree
,
static_cast
<
size_t
>
(
tree_size
));
}
}
// namespace containers
}
// namespace embb
...
...
containers_cpp/include/embb/containers/internal/object_pool-inl.h
View file @
8b6b7369
...
...
@@ -29,60 +29,60 @@
namespace
embb
{
namespace
containers
{
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
ReturningTrueIterator
(
size_t
count_value
)
:
count_value
(
count_value
),
ret_value
(
true
)
{}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
typename
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
typename
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
self_type
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
operator
++
()
{
self_type
i
=
*
this
;
count_value
++
;
return
i
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
typename
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
self_type
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
typename
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
self_type
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
operator
++
(
int
)
{
count_value
++
;
return
*
this
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
typename
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
reference
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
typename
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
reference
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
operator
*
()
{
return
ret_value
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
typename
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
pointer
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
typename
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
pointer
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
operator
->
()
{
return
&
ret_value
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
bool
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
bool
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
operator
==
(
const
self_type
&
rhs
)
{
return
count_value
==
rhs
.
count_value
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
bool
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
bool
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ReturningTrueIterator
::
operator
!=
(
const
self_type
&
rhs
)
{
return
count_value
!=
rhs
.
count_value
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
bool
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
IsContained
(
const
T
&
obj
)
const
{
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
bool
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
IsContained
(
const
T
ype
&
obj
)
const
{
if
((
&
obj
<
&
objects
[
0
])
||
(
&
obj
>
&
objects
[
capacity
-
1
]))
{
return
false
;
}
else
{
...
...
@@ -90,104 +90,104 @@ IsContained(const T &obj) const {
}
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
int
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
GetIndexOfObject
(
const
T
&
obj
)
const
{
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
int
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
GetIndexOfObject
(
const
T
ype
&
obj
)
const
{
assert
(
IsContained
(
obj
));
return
(
static_cast
<
int
>
(
&
obj
-
&
objects
[
0
]));
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
T
*
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
AllocateRaw
()
{
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
T
ype
*
ObjectPool
<
Type
,
ValuePool
,
ObjectAllocator
>::
AllocateRaw
()
{
bool
val
;
int
allocated_index
=
p
.
Allocate
(
val
);
if
(
allocated_index
==
-
1
)
{
return
NULL
;
}
else
{
T
*
ret_pointer
=
&
(
objects
[
allocated_index
]);
T
ype
*
ret_pointer
=
&
(
objects
[
allocated_index
]);
return
ret_pointer
;
}
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
size_t
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
GetCapacity
()
{
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
size_t
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
GetCapacity
()
{
return
capacity
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
ObjectPool
(
size_t
capacity
)
:
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
ObjectPool
(
size_t
capacity
)
:
capacity
(
capacity
),
p
(
ReturningTrueIterator
(
0
),
ReturningTrueIterator
(
capacity
))
{
// Allocate the objects (without construction, just get the memory)
objects
=
objectAllocator
.
allocate
(
capacity
);
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
void
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
Free
(
T
*
obj
)
{
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
void
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::
Free
(
Type
*
obj
)
{
int
index
=
GetIndexOfObject
(
*
obj
);
obj
->~
T
();
obj
->~
T
ype
();
p
.
Free
(
true
,
index
);
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
T
*
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
Allocate
()
{
T
*
rawObject
=
AllocateRaw
();
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
T
ype
*
ObjectPool
<
Type
,
ValuePool
,
ObjectAllocator
>::
Allocate
()
{
T
ype
*
rawObject
=
AllocateRaw
();
if
(
rawObject
!=
NULL
)
new
(
rawObject
)
T
();
new
(
rawObject
)
T
ype
();
return
rawObject
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
template
<
typename
Param1
>
T
*
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
Allocate
(
T
ype
*
ObjectPool
<
Type
,
ValuePool
,
ObjectAllocator
>::
Allocate
(
Param1
const
&
param1
)
{
T
*
rawObject
=
AllocateRaw
();
T
ype
*
rawObject
=
AllocateRaw
();
if
(
rawObject
!=
NULL
)
new
(
rawObject
)
T
(
param1
);
new
(
rawObject
)
T
ype
(
param1
);
return
rawObject
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
template
<
typename
Param1
,
typename
Param2
>
T
*
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
Allocate
(
T
ype
*
ObjectPool
<
Type
,
ValuePool
,
ObjectAllocator
>::
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
)
{
T
*
rawObject
=
AllocateRaw
();
T
ype
*
rawObject
=
AllocateRaw
();
if
(
rawObject
!=
NULL
)
new
(
rawObject
)
T
(
param1
,
param2
);
new
(
rawObject
)
T
ype
(
param1
,
param2
);
return
rawObject
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
template
<
typename
Param1
,
typename
Param2
,
typename
Param3
>
T
*
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
Allocate
(
T
ype
*
ObjectPool
<
Type
,
ValuePool
,
ObjectAllocator
>::
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
Param3
const
&
param3
)
{
T
*
rawObject
=
AllocateRaw
();
T
ype
*
rawObject
=
AllocateRaw
();
if
(
rawObject
!=
NULL
)
new
(
rawObject
)
T
(
param1
,
param2
,
param3
);
new
(
rawObject
)
T
ype
(
param1
,
param2
,
param3
);
return
rawObject
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
template
<
typename
Param1
,
typename
Param2
,
typename
Param3
,
typename
Param4
>
T
*
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::
Allocate
(
T
ype
*
ObjectPool
<
Type
,
ValuePool
,
ObjectAllocator
>::
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
Param3
const
&
param3
,
Param4
const
&
param4
)
{
T
*
rawObject
=
AllocateRaw
();
T
ype
*
rawObject
=
AllocateRaw
();
if
(
rawObject
!=
NULL
)
new
(
rawObject
)
T
(
param1
,
param2
,
param3
,
param4
);
new
(
rawObject
)
T
ype
(
param1
,
param2
,
param3
,
param4
);
return
rawObject
;
}
template
<
class
T
,
typename
ValuePool
,
class
ObjectAllocator
>
ObjectPool
<
T
,
ValuePool
,
ObjectAllocator
>::~
ObjectPool
()
{
template
<
class
T
ype
,
typename
ValuePool
,
class
ObjectAllocator
>
ObjectPool
<
T
ype
,
ValuePool
,
ObjectAllocator
>::~
ObjectPool
()
{
// Deallocate the objects
objectAllocator
.
deallocate
(
objects
,
capacity
);
}
...
...
containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h
View file @
8b6b7369
...
...
@@ -29,20 +29,20 @@
namespace
embb
{
namespace
containers
{
template
<
typename
T
,
T
Undefined
,
class
Allocator
>
void
WaitFreeArrayValuePool
<
T
,
Undefined
,
Allocator
>::
Free
(
T
element
,
int
index
)
{
template
<
typename
T
ype
,
Type
Undefined
,
class
Allocator
>
void
WaitFreeArrayValuePool
<
T
ype
,
Undefined
,
Allocator
>::
Free
(
T
ype
element
,
int
index
)
{
assert
(
element
!=
Undefined
);
// Just put back the element
pool
[
index
].
Store
(
element
);
}
template
<
typename
T
,
T
Undefined
,
class
Allocator
>
int
WaitFreeArrayValuePool
<
T
,
Undefined
,
Allocator
>::
Allocate
(
T
&
element
)
{
template
<
typename
T
ype
,
Type
Undefined
,
class
Allocator
>
int
WaitFreeArrayValuePool
<
T
ype
,
Undefined
,
Allocator
>::
Allocate
(
T
ype
&
element
)
{
for
(
int
i
=
0
;
i
!=
size
;
++
i
)
{
T
expected
;
T
ype
expected
;
// If the memory cell is not available, go ahead
if
(
Undefined
==
(
expected
=
pool
[
i
].
Load
()))
...
...
@@ -58,9 +58,9 @@ Allocate(T & element) {
return
-
1
;
}
template
<
typename
T
,
T
Undefined
,
class
Allocator
>
template
<
typename
T
ype
,
Type
Undefined
,
class
Allocator
>
template
<
typename
ForwardIterator
>
WaitFreeArrayValuePool
<
T
,
Undefined
,
Allocator
>::
WaitFreeArrayValuePool
<
T
ype
,
Undefined
,
Allocator
>::
WaitFreeArrayValuePool
(
ForwardIterator
first
,
ForwardIterator
last
)
{
size_t
dist
=
static_cast
<
size_t
>
(
std
::
distance
(
first
,
last
));
...
...
@@ -77,8 +77,8 @@ WaitFreeArrayValuePool(ForwardIterator first, ForwardIterator last) {
}
}
template
<
typename
T
,
T
Undefined
,
class
Allocator
>
WaitFreeArrayValuePool
<
T
,
Undefined
,
Allocator
>::~
WaitFreeArrayValuePool
()
{
template
<
typename
T
ype
,
Type
Undefined
,
class
Allocator
>
WaitFreeArrayValuePool
<
T
ype
,
Undefined
,
Allocator
>::~
WaitFreeArrayValuePool
()
{
allocator
.
deallocate
(
pool
,
(
size_t
)
size
);
}
}
// namespace containers
...
...
containers_cpp/include/embb/containers/internal/wait_free_spsc_queue-inl.h
View file @
8b6b7369
...
...
@@ -36,21 +36,21 @@
namespace
embb
{
namespace
containers
{
template
<
typename
T
,
class
Allocator
>
WaitFreeSPSCQueue
<
T
,
Allocator
>::
WaitFreeSPSCQueue
(
size_t
capacity
)
:
template
<
typename
T
ype
,
class
Allocator
>
WaitFreeSPSCQueue
<
T
ype
,
Allocator
>::
WaitFreeSPSCQueue
(
size_t
capacity
)
:
capacity
(
capacity
),
head_index
(
0
),
tail_index
(
0
)
{
queue_array
=
allocator
.
allocate
(
capacity
);
}
template
<
typename
T
,
class
Allocator
>
size_t
WaitFreeSPSCQueue
<
T
,
Allocator
>::
GetCapacity
()
{
template
<
typename
T
ype
,
class
Allocator
>
size_t
WaitFreeSPSCQueue
<
T
ype
,
Allocator
>::
GetCapacity
()
{
return
capacity
;
}
template
<
typename
T
,
class
Allocator
>
bool
WaitFreeSPSCQueue
<
T
,
Allocator
>::
TryEnqueue
(
T
const
&
element
)
{
template
<
typename
T
ype
,
class
Allocator
>
bool
WaitFreeSPSCQueue
<
T
ype
,
Allocator
>::
TryEnqueue
(
Type
const
&
element
)
{
if
(
head_index
-
tail_index
==
capacity
)
return
false
;
...
...
@@ -59,19 +59,19 @@ bool WaitFreeSPSCQueue<T, Allocator>::TryEnqueue(T const & element) {
return
true
;
}
template
<
typename
T
,
class
Allocator
>
bool
WaitFreeSPSCQueue
<
T
,
Allocator
>::
TryDequeue
(
T
&
element
)
{
template
<
typename
T
ype
,
class
Allocator
>
bool
WaitFreeSPSCQueue
<
T
ype
,
Allocator
>::
TryDequeue
(
Type
&
element
)
{
if
(
tail_index
-
head_index
==
0
)
return
false
;
T
x
=
queue_array
[
head_index
%
capacity
];
T
ype
x
=
queue_array
[
head_index
%
capacity
];
this
->
head_index
++
;
element
=
x
;
return
true
;
}
template
<
typename
T
,
class
Allocator
>
WaitFreeSPSCQueue
<
T
,
Allocator
>::~
WaitFreeSPSCQueue
()
{
template
<
typename
T
ype
,
class
Allocator
>
WaitFreeSPSCQueue
<
T
ype
,
Allocator
>::~
WaitFreeSPSCQueue
()
{
allocator
.
deallocate
(
queue_array
,
capacity
);
}
}
// namespace containers
...
...
containers_cpp/include/embb/containers/lock_free_mpmc_queue.h
View file @
8b6b7369
...
...
@@ -46,20 +46,20 @@ namespace internal {
* Single linked lists, contains the element (\c element) and a pointer to the
* next node (\c next).
*
* \tparam T Element type
* \tparam T
ype
Element type
*/
template
<
typename
T
>
template
<
typename
Type
>
class
LockFreeMPMCQueueNode
{
private
:
/**
* Pointer to the next node
*/
embb
::
base
::
Atomic
<
LockFreeMPMCQueueNode
<
T
>*
>
next
;
embb
::
base
::
Atomic
<
LockFreeMPMCQueueNode
<
T
ype
>*
>
next
;
/**
* The stored element
*/
T
element
;
T
ype
element
;
public
:
/**
...
...
@@ -73,7 +73,7 @@ class LockFreeMPMCQueueNode {
* Creates a queue node
*/
LockFreeMPMCQueueNode
(
T
const
&
element
T
ype
const
&
element
/**< [IN] The element of this queue node */
);
/**
...
...
@@ -81,12 +81,12 @@ class LockFreeMPMCQueueNode {
*
* \return The next pointer
*/
embb
::
base
::
Atomic
<
LockFreeMPMCQueueNode
<
T
>*
>
&
GetNext
();
embb
::
base
::
Atomic
<
LockFreeMPMCQueueNode
<
T
ype
>*
>
&
GetNext
();
/**
* Returns the element held by this node
*/
T
GetElement
();
T
ype
GetElement
();
};
}
// namespace internal
...
...
@@ -99,11 +99,11 @@ class LockFreeMPMCQueueNode {
*
* \see WaitFreeSPSCQueue
*
* \tparam T Type of the queue elements
* \tparam T
ype
Type of the queue elements
* \tparam ValuePool Type of the value pool used as basis for the ObjectPool
* which stores the elements.
*/
template
<
typename
T
,
template
<
typename
T
ype
,
typename
ValuePool
=
embb
::
containers
::
LockFreeTreeValuePool
<
bool
,
false
>
>
class
LockFreeMPMCQueue
{
...
...
@@ -120,35 +120,35 @@ class LockFreeMPMCQueue {
* Callback to the method that is called by hazard pointers if a pointer is
* not hazardous anymore, i.e., can safely be reused.
*/
embb
::
base
::
Function
<
void
,
internal
::
LockFreeMPMCQueueNode
<
T
>*
>
embb
::
base
::
Function
<
void
,
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
>
delete_pointer_callback
;
/**
* The hazard pointer object, used for memory management.
*/
embb
::
containers
::
internal
::
HazardPointer
<
internal
::
LockFreeMPMCQueueNode
<
T
>*
>
hazardPointer
;
<
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
>
hazardPointer
;
/**
* The object pool, used for lock-free memory allocation.
*/
ObjectPool
<
internal
::
LockFreeMPMCQueueNode
<
T
>
,
ValuePool
>
objectPool
;
ObjectPool
<
internal
::
LockFreeMPMCQueueNode
<
T
ype
>
,
ValuePool
>
objectPool
;
/**
* Atomic pointer to the head node of the queue
*/
embb
::
base
::
Atomic
<
internal
::
LockFreeMPMCQueueNode
<
T
>*
>
head
;
embb
::
base
::
Atomic
<
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
>
head
;
/**
* Atomic pointer to the tail node of the queue
*/
embb
::
base
::
Atomic
<
internal
::
LockFreeMPMCQueueNode
<
T
>*
>
tail
;
embb
::
base
::
Atomic
<
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
>
tail
;
/**
* The callback function, used to cleanup non-hazardous pointers.
* \see delete_pointer_callback
*/
void
DeletePointerCallback
(
internal
::
LockFreeMPMCQueueNode
<
T
>*
to_delete
);
void
DeletePointerCallback
(
internal
::
LockFreeMPMCQueueNode
<
T
ype
>*
to_delete
);
public
:
/**
...
...
@@ -157,8 +157,8 @@ class LockFreeMPMCQueue {
* \memory
* 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
* elements of size <tt>sizeof(T)</tt>, and \c capacity+1 elements of size
* <tt>sizeof(T)</tt> are allocated.
* elements of size <tt>sizeof(T
ype
)</tt>, and \c capacity+1 elements of size
* <tt>sizeof(T
ype
)</tt> are allocated.
*
* \notthreadsafe
*
...
...
@@ -198,7 +198,7 @@ class LockFreeMPMCQueue {
* \see CPP_CONCEPTS_QUEUE
*/
bool
TryEnqueue
(
T
const
&
element
T
ype
const
&
element
/**< [IN] Const reference to the element that shall be enqueued */
);
/**
...
...
@@ -212,7 +212,7 @@ class LockFreeMPMCQueue {
* \see CPP_CONCEPTS_QUEUE
*/
bool
TryDequeue
(
T
&
element
T
ype
&
element
/**< [IN, OUT] Reference to the dequeued element.
Unchanged, if the operation
was not successful. */
);
...
...
containers_cpp/include/embb/containers/lock_free_stack.h
View file @
8b6b7369
...
...
@@ -53,9 +53,9 @@
*
* \par Requirements
* - Let \c Stack be the stack class
* - Let \c T be the element type of the stack
* - Let \c T
ype
be the element type of the stack
* - 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 T
ype
*
* \par Valid Expressions
* <table>
...
...
@@ -65,11 +65,11 @@
* <th>Description</th>
* </tr>
* <tr>
* <td>\code{.cpp} Stack<T>(capacity) \endcode</td>
* <td>\code{.cpp} Stack<T
ype
>(capacity) \endcode</td>
* <td>Nothing</td>
* <td>
* Constructs a stack with capacity \c capacity that holds elements of
* type \c T.
* type \c T
ype
.
* </td>
* </tr>
* <tr>
...
...
@@ -165,11 +165,11 @@ class LockFreeStackNode {
*
* \ingroup CPP_CONTAINERS_STACKS
*
* \tparam T Type of the stack elements
* \tparam T
ype
Type of the stack elements
* \tparam ValuePool Type of the value pool used as basis for the ObjectPool
* which stores the elements.
*/
template
<
typename
T
,
template
<
typename
T
ype
,
typename
ValuePool
=
embb
::
containers
::
LockFreeTreeValuePool
<
bool
,
false
>
>
class
LockFreeStack
{
private
:
...
...
@@ -183,29 +183,29 @@ class LockFreeStack {
* Callback to the method that is called by hazard pointers if a pointer is
* not hazardous anymore, i.e., can safely be reused.
*/
embb
::
base
::
Function
<
void
,
internal
::
LockFreeStackNode
<
T
>*>
embb
::
base
::
Function
<
void
,
internal
::
LockFreeStackNode
<
T
ype
>*>
delete_pointer_callback
;
/**
* The hazard pointer object, used for memory management.
*/
internal
::
HazardPointer
<
internal
::
LockFreeStackNode
<
T
>*>
hazardPointer
;
internal
::
HazardPointer
<
internal
::
LockFreeStackNode
<
T
ype
>*>
hazardPointer
;
/**
* The callback function, used to cleanup non-hazardous pointers.
* \see delete_pointer_callback
*/
void
DeletePointerCallback
(
internal
::
LockFreeStackNode
<
T
>*
to_delete
);
void
DeletePointerCallback
(
internal
::
LockFreeStackNode
<
T
ype
>*
to_delete
);
/**
* The object pool, used for lock-free memory allocation.
*/
ObjectPool
<
internal
::
LockFreeStackNode
<
T
>
,
ValuePool
>
objectPool
;
ObjectPool
<
internal
::
LockFreeStackNode
<
T
ype
>
,
ValuePool
>
objectPool
;
/**
* 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
<
T
ype
>*>
top
;
public
:
/**
...
...
@@ -214,8 +214,8 @@ class LockFreeStack {
* \memory
* 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
* elements of size <tt>sizeof(T)</tt>, and \c capacity elements of size
* <tt>sizeof(T)</tt> are allocated.
* elements of size <tt>sizeof(T
ype
)</tt>, and \c capacity elements of size
* <tt>sizeof(T
ype
)</tt> are allocated.
*
* \notthreadsafe
*
...
...
@@ -256,7 +256,7 @@ class LockFreeStack {
* \see CPP_CONCEPTS_STACK
*/
bool
TryPush
(
T
const
&
element
T
ype
const
&
element
/**< [IN] Const reference to the element that shall be pushed */
);
...
...
@@ -271,7 +271,7 @@ class LockFreeStack {
* \see CPP_CONCEPTS_STACK
*/
bool
TryPop
(
T
&
element
T
ype
&
element
/**< [IN,OUT] Reference to the popped element. Unchanged, if the operation
was not successful. */
);
...
...
containers_cpp/include/embb/containers/lock_free_tree_value_pool.h
View file @
8b6b7369
...
...
@@ -41,15 +41,15 @@ namespace containers {
*
* \see WaitFreeArrayValuePool
*
* \tparam T Element type (must support atomic operations such as \c int).
* \tparam T
ype
Element type (must support atomic operations such as \c int).
* \tparam Undefined Bottom element (cannot be stored in the pool)
* \tparam PoolAllocator Allocator used to allocate the pool array
* \tparam TreeAllocator Allocator used to allocate the array representing the
* binary tree.
*/
template
<
typename
T
,
T
Undefined
,
class
PoolAllocator
=
embb
::
base
::
Allocator
<
embb
::
base
::
Atomic
<
T
>
>
,
template
<
typename
T
ype
,
T
ype
Undefined
,
class
PoolAllocator
=
embb
::
base
::
Allocator
<
embb
::
base
::
Atomic
<
T
ype
>
>
,
class
TreeAllocator
=
embb
::
base
::
Allocator
<
embb
::
base
::
Atomic
<
int
>
>
>
class
LockFreeTreeValuePool
{
...
...
@@ -95,7 +95,7 @@ class LockFreeTreeValuePool {
*
* The algorithm for allocating an element starts at the root node and
* recursively traverses the tree. It tries to decrement a node (a decrement
* is actually a conditional decrement, i.e., a node is decremented if
f
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
* wait-free anymore, as this cannot be implemented atomically.) and if
* successful, calls itself on the left child, if not successful, on the right
...
...
@@ -135,7 +135,7 @@ class LockFreeTreeValuePool {
embb
::
base
::
Atomic
<
int
>*
tree
;
// The actual pool
embb
::
base
::
Atomic
<
T
>*
pool
;
embb
::
base
::
Atomic
<
T
ype
>*
pool
;
PoolAllocator
poolAllocator
;
TreeAllocator
treeAllocator
;
...
...
@@ -235,7 +235,7 @@ class LockFreeTreeValuePool {
int
allocate_rec
(
int
node
,
/**< [IN] Node index */
T
&
element
T
ype
&
element
/**< [IN,OUT] Allocated element, if there is any */
);
...
...
@@ -260,8 +260,8 @@ class LockFreeTreeValuePool {
*
* \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,
* <tt>((2^k)-1) * sizeof(embb::Atomic<int>) +
n*sizeof(embb::Atomic<T>)</tt>
* bytes of memory are allocated.
* <tt>((2^k)-1) * sizeof(embb::Atomic<int>) +
*
n*sizeof(embb::Atomic<Type>)</tt>
bytes of memory are allocated.
*
* \notthreadsafe
*
...
...
@@ -294,7 +294,7 @@ class LockFreeTreeValuePool {
* \see CPP_CONCEPTS_VALUE_POOL
*/
int
Allocate
(
T
&
element
T
ype
&
element
/**< [IN,OUT] Reference to the allocated element. Unchanged, if the
operation was not successful. */
);
...
...
@@ -309,7 +309,7 @@ class LockFreeTreeValuePool {
* \see CPP_CONCEPTS_VALUE_POOL
*/
void
Free
(
T
element
,
T
ype
element
,
/**< [IN] Element to be returned to the pool */
int
index
/**< [IN] Index of the element as obtained by Allocate() */
...
...
containers_cpp/include/embb/containers/object_pool.h
View file @
8b6b7369
...
...
@@ -48,15 +48,15 @@ namespace containers {
*
* \ingroup CPP_CONTAINERS_POOLS
*
* \tparam T Element type
* \tparam T
ype
Element type
* \tparam ValuePool Type of the underlying value pool, determines whether
* the object pool is wait-free or lock-free
* \tparam ObjectAllocator Type of allocator used to allocate objects
*/
template
<
class
T
,
template
<
class
T
ype
,
typename
ValuePool
=
embb
::
containers
::
WaitFreeArrayValuePool
<
bool
,
false
>
,
class
ObjectAllocator
=
embb
::
base
::
Allocator
<
T
>
>
class
ObjectAllocator
=
embb
::
base
::
Allocator
<
T
ype
>
>
class
ObjectPool
{
private
:
/**
...
...
@@ -67,7 +67,7 @@ class ObjectPool {
/**
* Array holding the allocated object
*/
T
*
objects
;
T
ype
*
objects
;
/**
* Capacity of the object pool
...
...
@@ -105,15 +105,15 @@ class ObjectPool {
bool
ret_value
;
};
bool
IsContained
(
const
T
&
obj
)
const
;
int
GetIndexOfObject
(
const
T
&
obj
)
const
;
T
*
AllocateRaw
();
bool
IsContained
(
const
T
ype
&
obj
)
const
;
int
GetIndexOfObject
(
const
T
ype
&
obj
)
const
;
T
ype
*
AllocateRaw
();
public
:
/**
* 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 T
ype
.
*
* \notthreadsafe
*/
...
...
@@ -147,7 +147,7 @@ class ObjectPool {
* \note The element must have been allocated with Allocate().
*/
void
Free
(
T
*
obj
T
ype
*
obj
/**< [IN] Pointer to the object to be freed */
);
...
...
@@ -162,22 +162,22 @@ class ObjectPool {
*
* \param ... Arguments of arbitrary type, passed to the object's constructor
*/
T
*
Allocate
(...);
T
ype
*
Allocate
(...);
#else
T
*
Allocate
();
T
ype
*
Allocate
();
template
<
typename
Param1
>
T
*
Allocate
(
Param1
const
&
param1
);
T
ype
*
Allocate
(
Param1
const
&
param1
);
template
<
typename
Param1
,
typename
Param2
>
T
*
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
);
T
ype
*
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
);
template
<
typename
Param1
,
typename
Param2
,
typename
Param3
>
T
*
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
T
ype
*
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
Param3
const
&
param3
);
template
<
typename
Param1
,
typename
Param2
,
typename
Param3
,
typename
Param4
>
T
*
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
T
ype
*
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
Param3
const
&
param3
,
Param4
const
&
param4
);
#endif
...
...
containers_cpp/include/embb/containers/wait_free_array_value_pool.h
View file @
8b6b7369
...
...
@@ -48,11 +48,11 @@ namespace containers {
*
* \par Requirements
* - Let \c Pool be the pool class
* - Let \c T be the element type of the pool. Atomic operations must be
* possible on \c T.
* - Let \c b, d be objects of type \c T
* - Let \c T
ype
be the element type of the pool. Atomic operations must be
* possible on \c T
ype
.
* - Let \c b, d be objects of type \c T
ype
* - 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 T
ype
&
* - Let \c e be a value of type \c int
*
* \par Valid Expressions
...
...
@@ -64,13 +64,13 @@ namespace containers {
* <th>Description</th>
* </tr>
* <tr>
* <td>\code{.cpp} Pool<T, b>(i, j) \endcode
* <td>\code{.cpp} Pool<T
ype
, b>(i, j) \endcode
* </td>
* <td>Nothing</td>
* <td>
* Constructs a value pool holding elements of type \c T
, where \c b is the
*
bottom element. The bottom element cannot be stored in the pool, it is
* exclusively used to mark empty cells. The pool initially contains
* Constructs a value pool holding elements of type \c T
ype, where \c b is
*
the bottom element. The bottom element cannot be stored in the pool, it
*
is
exclusively used to mark empty cells. The pool initially contains
* \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
* might provide additional template parameters for specifying allocators.
...
...
@@ -107,17 +107,17 @@ namespace containers {
*
* \see LockFreeTreeValuePool
*
* \tparam T Element type (must support atomic operations such as \c int).
* \tparam T
ype
Element type (must support atomic operations such as \c int).
* \tparam Undefined Bottom element (cannot be stored in the pool)
* \tparam Allocator Allocator used to allocate the pool array
*/
template
<
typename
T
,
T
Undefined
,
class
Allocator
=
embb
::
base
::
Allocator
<
embb
::
base
::
Atomic
<
T
>
>
>
template
<
typename
T
ype
,
T
ype
Undefined
,
class
Allocator
=
embb
::
base
::
Allocator
<
embb
::
base
::
Atomic
<
T
ype
>
>
>
class
WaitFreeArrayValuePool
{
private
:
int
size
;
embb
::
base
::
Atomic
<
T
>*
pool
;
embb
::
base
::
Atomic
<
T
ype
>*
pool
;
WaitFreeArrayValuePool
();
Allocator
allocator
;
...
...
@@ -131,7 +131,7 @@ class WaitFreeArrayValuePool {
/**
* 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<T
ype
>)</tt>
* bytes, where <tt>n = std::distance(first, last)</tt> is the number
* of pool elements.
*
...
...
@@ -166,7 +166,7 @@ class WaitFreeArrayValuePool {
* \see CPP_CONCEPTS_VALUE_POOL
*/
int
Allocate
(
T
&
element
T
ype
&
element
/**< [IN,OUT] Reference to the allocated element. Unchanged, if the
operation was not successful. */
);
...
...
@@ -181,7 +181,7 @@ class WaitFreeArrayValuePool {
* \see CPP_CONCEPTS_VALUE_POOL
*/
void
Free
(
T
element
,
T
ype
element
,
/**< [IN] Element to be returned to the pool */
int
index
/**< [IN] Index of the element as obtained by Allocate() */
...
...
containers_cpp/include/embb/containers/wait_free_spsc_queue.h
View file @
8b6b7369
...
...
@@ -53,9 +53,9 @@
*
* \par Requirements
* - Let \c Queue be the queue class
* - Let \c T be the element type of the queue
* - Let \c T
ype
be the element type of the queue
* - 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 T
ype
*
* \par Valid Expressions
* <table>
...
...
@@ -65,7 +65,7 @@
* <th>Description</th>
* </tr>
* <tr>
* <td>\code{.cpp} Queue<T>(capacity) \endcode</td>
* <td>\code{.cpp} Queue<T
ype
>(capacity) \endcode</td>
* <td>Nothing</td>
* <td>
* Constructs a queue with capacity \c capacity that holds elements of
...
...
@@ -114,10 +114,10 @@ namespace containers {
*
* \see LockFreeMPMCQueue
*
* \tparam T Type of the queue elements
* \tparam T
ype
Type of the queue elements
* \tparam Allocator Allocator type for allocating queue elements.
*/
template
<
typename
T
,
class
Allocator
=
embb
::
base
::
Allocator
<
T
>
>
template
<
typename
T
ype
,
class
Allocator
=
embb
::
base
::
Allocator
<
Type
>
>
class
WaitFreeSPSCQueue
{
private
:
/**
...
...
@@ -133,7 +133,7 @@ class WaitFreeSPSCQueue {
/**
* Array holding the queue elements
*/
T
*
queue_array
;
T
ype
*
queue_array
;
/**
* Index of the head in the \c queue_array
...
...
@@ -149,7 +149,7 @@ class WaitFreeSPSCQueue {
/**
* Creates a queue with the specified capacity.
*
* \memory Allocates \c capacity elements of type \c T.
* \memory Allocates \c capacity elements of type \c T
ype
.
*
* \notthreadsafe
*
...
...
@@ -190,7 +190,7 @@ class WaitFreeSPSCQueue {
* \see CPP_CONCEPTS_QUEUE
*/
bool
TryEnqueue
(
T
const
&
element
T
ype
const
&
element
/**< [IN] Const reference to the element that shall be enqueued */
);
...
...
@@ -208,9 +208,9 @@ class WaitFreeSPSCQueue {
* \see CPP_CONCEPTS_QUEUE
*/
bool
TryDequeue
(
T
&
element
/**< [IN,OUT] Reference to the dequeued element. Unchanged, if the
operation
was not successful. */
T
ype
&
element
/**< [IN,OUT] Reference to the dequeued element. Unchanged, if the
operation
was not successful. */
);
};
}
// namespace containers
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment