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
df279e99
authored
Apr 14, 2015
by
Tobias Fuchs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
containers_cpp: interface of IndexedObjectPool conforming to ObjectPool
parent
d3a090c3
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
184 additions
and
101 deletions
+184
-101
containers_cpp/include/embb/containers/internal/indexed_object_pool-inl.h
+89
-28
containers_cpp/include/embb/containers/internal/indexed_object_pool.h
+42
-17
containers_cpp/include/embb/containers/internal/wait_free_mpmc_queue-inl.h
+48
-51
containers_cpp/include/embb/containers/wait_free_mpmc_queue.h
+5
-5
No files found.
containers_cpp/include/embb/containers/internal/indexed_object_pool-inl.h
View file @
df279e99
...
...
@@ -33,9 +33,9 @@ namespace embb {
namespace
containers
{
namespace
internal
{
template
<
typename
T
,
class
IndexPool
,
class
Allocator
>
template
<
typename
T
ype
,
class
IndexPool
,
class
Allocator
>
template
<
typename
RAI
>
IndexedObjectPool
<
T
,
IndexPool
,
Allocator
>::
IndexedObjectPool
<
T
ype
,
IndexPool
,
Allocator
>::
IndexedObjectPool
(
RAI
first
,
RAI
last
)
:
size_
(
static_cast
<
size_t
>
(
std
::
distance
(
first
,
last
))),
indexPool
(
internal
::
ReturningTrueIterator
(
0
),
...
...
@@ -50,9 +50,9 @@ IndexedObjectPool(RAI first, RAI last) :
}
}
template
<
typename
T
,
class
IndexPool
,
class
Allocator
>
IndexedObjectPool
<
T
,
IndexPool
,
Allocator
>::
IndexedObjectPool
(
size_t
size
,
const
T
&
defaultInstance
)
:
template
<
typename
T
ype
,
class
IndexPool
,
class
Allocator
>
IndexedObjectPool
<
T
ype
,
IndexPool
,
Allocator
>::
IndexedObjectPool
(
size_t
size
,
const
T
ype
&
defaultInstance
)
:
size_
(
size
),
indexPool
(
internal
::
ReturningTrueIterator
(
0
),
internal
::
ReturningTrueIterator
(
size_
))
{
...
...
@@ -66,42 +66,103 @@ IndexedObjectPool(size_t size, const T & defaultInstance) :
}
}
template
<
typename
T
,
class
IndexPool
,
class
Allocator
>
IndexedObjectPool
<
T
,
IndexPool
,
Allocator
>::
template
<
typename
T
ype
,
class
IndexPool
,
class
Allocator
>
IndexedObjectPool
<
T
ype
,
IndexPool
,
Allocator
>::
~
IndexedObjectPool
()
{
allocator
.
deallocate
(
elements
,
size_
);
}
template
<
typename
T
,
class
IndexPool
,
class
Allocator
>
int
IndexedObjectPool
<
T
,
IndexPool
,
Allocator
>::
Allocate
(
T
&
element
)
{
// Reserve a pool index:
bool
reservedFlag
;
int
index
=
indexPool
.
Allocate
(
reservedFlag
);
// Assign element to be allocated at pool index.
// Index returned from index pool is -1 if no index
// is available.
if
(
index
>=
0
)
{
element
=
elements
[
index
];
}
return
index
;
}
template
<
typename
T
,
class
IndexPool
,
class
Allocator
>
void
IndexedObjectPool
<
T
,
IndexPool
,
Allocator
>::
template
<
typename
Type
,
class
IndexPool
,
class
Allocator
>
void
IndexedObjectPool
<
Type
,
IndexPool
,
Allocator
>::
Free
(
int
elementIndex
)
{
// Call the referenced element's destructor:
elements
[
elementIndex
].
~
T
();
elements
[
elementIndex
].
~
T
ype
();
// Release index of the element for reuse:
indexPool
.
Free
(
true
,
elementIndex
);
}
template
<
typename
T
,
class
IndexPool
,
class
Allocator
>
T
&
IndexedObjectPool
<
T
,
IndexPool
,
Allocator
>::
operator
[](
size_
t
elementIndex
)
{
template
<
typename
T
ype
,
class
IndexPool
,
class
Allocator
>
T
ype
&
IndexedObjectPool
<
Type
,
IndexPool
,
Allocator
>::
operator
[](
in
t
elementIndex
)
{
return
elements
[
elementIndex
];
}
template
<
class
Type
,
typename
ValuePool
,
class
ObjectAllocator
>
int
IndexedObjectPool
<
Type
,
ValuePool
,
ObjectAllocator
>::
AllocateRaw
(
Type
*
&
newElement
)
{
newElement
=
NULL
;
// Reserve a pool index:
bool
val
;
int
allocated_index
=
indexPool
.
Allocate
(
val
);
if
(
allocated_index
>=
0
)
{
// Return pointer to reserved element:
Type
*
ret_pointer
=
&
(
elements
[
allocated_index
]);
newElement
=
ret_pointer
;
}
return
allocated_index
;
}
template
<
typename
Type
,
class
IndexPool
,
class
Allocator
>
int
IndexedObjectPool
<
Type
,
IndexPool
,
Allocator
>::
Allocate
()
{
Type
*
raw_object
=
NULL
;
int
element_index
=
AllocateRaw
(
raw_object
);
if
(
element_index
>=
0
&&
raw_object
!=
NULL
)
{
new
(
raw_object
)
Type
();
}
return
element_index
;
}
template
<
typename
Type
,
class
IndexPool
,
class
Allocator
>
template
<
typename
Param1
>
int
IndexedObjectPool
<
Type
,
IndexPool
,
Allocator
>::
Allocate
(
Param1
const
&
param1
)
{
Type
*
raw_object
=
NULL
;
int
element_index
=
AllocateRaw
(
raw_object
);
if
(
element_index
>=
0
&&
raw_object
!=
NULL
)
{
new
(
raw_object
)
Type
(
param1
);
}
return
element_index
;
}
template
<
typename
Type
,
class
IndexPool
,
class
Allocator
>
template
<
typename
Param1
,
typename
Param2
>
int
IndexedObjectPool
<
Type
,
IndexPool
,
Allocator
>::
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
)
{
Type
*
raw_object
=
NULL
;
int
element_index
=
AllocateRaw
(
raw_object
);
if
(
element_index
>=
0
&&
raw_object
!=
NULL
)
{
new
(
raw_object
)
Type
(
param1
,
param2
);
}
return
element_index
;
}
template
<
typename
Type
,
class
IndexPool
,
class
Allocator
>
template
<
typename
Param1
,
typename
Param2
,
typename
Param3
>
int
IndexedObjectPool
<
Type
,
IndexPool
,
Allocator
>::
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
Param3
const
&
param3
)
{
Type
*
raw_object
=
NULL
;
int
element_index
=
AllocateRaw
(
raw_object
);
if
(
element_index
>=
0
&&
raw_object
!=
NULL
)
{
new
(
raw_object
)
Type
(
param1
,
param2
,
param3
);
}
return
element_index
;
}
template
<
typename
Type
,
class
IndexPool
,
class
Allocator
>
template
<
typename
Param1
,
typename
Param2
,
typename
Param3
,
typename
Param4
>
int
IndexedObjectPool
<
Type
,
IndexPool
,
Allocator
>::
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
Param3
const
&
param3
,
Param4
const
&
param4
)
{
Type
*
raw_object
=
NULL
;
int
element_index
=
AllocateRaw
(
raw_object
);
if
(
element_index
>=
0
&&
raw_object
!=
NULL
)
{
new
(
raw_object
)
Type
(
param1
,
param2
,
param3
,
param4
);
}
return
element_index
;
}
}
// namespace internal
}
// namespace containers
}
// namespace embb
...
...
containers_cpp/include/embb/containers/internal/indexed_object_pool.h
View file @
df279e99
...
...
@@ -38,14 +38,14 @@ namespace containers {
namespace
internal
{
template
<
typename
T
,
typename
T
ype
,
class
IndexPool
=
LockFreeTreeValuePool
<
bool
,
false
>
,
class
Allocator
=
embb
::
base
::
Allocator
<
T
>
>
class
IndexedObjectPool
{
private
:
const
size_t
size_
;
T
*
elements
;
T
ype
*
elements
;
Allocator
allocator
;
IndexPool
indexPool
;
IndexedObjectPool
();
...
...
@@ -53,10 +53,13 @@ class IndexedObjectPool {
IndexedObjectPool
(
const
IndexedObjectPool
&
);
// Prevent assignment
IndexedObjectPool
&
operator
=
(
const
IndexedObjectPool
&
);
// Allocates pool index and resolves pointer to reserved element
int
AllocateRaw
(
Type
*
&
newElement
);
public
:
/**
* \see value_pool_concept
* Creates an indexed object pool, initializing all pool elements
* with elements from given range.
*
* \notthreadsafe
*
...
...
@@ -73,8 +76,9 @@ class IndexedObjectPool {
);
/**
* \see value_pool_concept
*
* Creates an indexed object pool of size \c capacity, initializing
* all pool elements with given default instance.
*
* \notthreadsafe
*
* \memory dynamically allocates
...
...
@@ -84,7 +88,7 @@ class IndexedObjectPool {
IndexedObjectPool
(
size_t
size
,
/**< [IN] Number of elements the pool is filled with */
const
T
&
defaultInstance
const
T
ype
&
defaultInstance
/**< [IN] Default instance to initialize pool elements with */
);
...
...
@@ -94,16 +98,6 @@ class IndexedObjectPool {
~
IndexedObjectPool
();
/**
* Request element and index from pool.
*
* \return index of element
*
* \see object_pool_concept
*
*/
int
Allocate
(
T
&
element
);
/**
* Return element and index to the pool.
*
* \see value_pool_concept
...
...
@@ -117,7 +111,38 @@ class IndexedObjectPool {
* \see object_pool_concept
*
*/
T
&
operator
[](
size_t
elementIndex
);
Type
&
operator
[](
int
elementIndex
);
#ifdef DOXYGEN
/**
* Allocates an element from the pool.
*
* If the underlying value pool is wait-free/lock-free, this operation is
* also wait-free/lock-free, respectively.
*
* \return Index of the allocated object if successful, otherwise \c -1.
*
* \param ... Arguments of arbitrary type, passed to the object's constructor
*/
int
Allocate
(...);
#else
int
Allocate
();
template
<
typename
Param1
>
int
Allocate
(
Param1
const
&
param1
);
template
<
typename
Param1
,
typename
Param2
>
int
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
);
template
<
typename
Param1
,
typename
Param2
,
typename
Param3
>
int
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
Param3
const
&
param3
);
template
<
typename
Param1
,
typename
Param2
,
typename
Param3
,
typename
Param4
>
int
Allocate
(
Param1
const
&
param1
,
Param2
const
&
param2
,
Param3
const
&
param3
,
Param4
const
&
param4
);
#endif
};
}
// namespace internal
...
...
containers_cpp/include/embb/containers/internal/wait_free_mpmc_queue-inl.h
View file @
df279e99
...
...
@@ -90,7 +90,7 @@ bool WaitFreeMPMCQueueNode<Type>::CASNext(
}
template
<
typename
Type
>
bool
WaitFreeMPMCQueueNode
<
Type
>::
Next
_
IsNull
()
const
{
bool
WaitFreeMPMCQueueNode
<
Type
>::
NextIsNull
()
const
{
return
next_idx
.
Load
()
==
UndefinedIndex
;
}
...
...
@@ -112,8 +112,8 @@ const uint32_t WaitFreeMPMCQueueNode<Type>::UndefinedIndex = 0x3fffffff;
}
// namespace internal
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
OperationDesc
::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
OperationDesc
::
OperationDesc
(
bool
pending
,
bool
enqueue
,
...
...
@@ -133,8 +133,8 @@ OperationDesc(
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
OperationDesc
::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
OperationDesc
::
OperationDesc
(
index_t
raw
)
:
Raw
(
raw
)
{
Pending
=
(
raw
&
PENDING_FLAG_MASK
)
?
true
:
false
;
Enqueue
=
(
raw
&
ENQUEUE_FLAG_MASK
)
?
true
:
false
;
...
...
@@ -142,8 +142,8 @@ OperationDesc(index_t raw) : Raw(raw) {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
WaitFreeMPMCQueue
(
size_t
capacity
)
:
max_size_
(
capacity
),
// Disable "this is used in base member initializer" warning.
...
...
@@ -178,9 +178,10 @@ WaitFreeMPMCQueue(size_t capacity)
"Maximum size of queue exceeded"
);
}
// Allocate sentinel node:
Node_t
sentinelNode
;
assert
(
sentinelNode
.
NextPoolIdx
()
==
Node_t
::
UndefinedIndex
);
int
sentinelNodePoolIndex
=
nodePool
.
Allocate
(
sentinelNode
);
int
sentinelNodePoolIndex
=
nodePool
.
Allocate
();
assert
(
nodePool
[
sentinelNodePoolIndex
].
NextPoolIdx
()
==
Node_t
::
UndefinedIndex
);
if
(
sentinelNodePoolIndex
<
0
)
{
EMBB_THROW
(
embb
::
base
::
NoMemoryException
,
"Allocation of sentinel node failed"
);
...
...
@@ -209,8 +210,8 @@ WaitFreeMPMCQueue(size_t capacity)
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
~
WaitFreeMPMCQueue
()
{
// Dequeue until queue is empty:
Type
val
;
...
...
@@ -221,8 +222,8 @@ WaitFreeMPMCQueue<Type, NodeAllocator, OpAllocator, ValuePool>::
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
inline
bool
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
inline
bool
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
LoadAccessorThreadIndex
(
index_t
&
retIndexValue
)
{
unsigned
int
tmpIndexValue
;
// For conversion size32_t <-> unsigned int
if
(
embb_internal_thread_index
(
&
tmpIndexValue
)
==
EMBB_SUCCESS
)
{
...
...
@@ -238,8 +239,8 @@ LoadAccessorThreadIndex(index_t & retIndexValue) {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
inline
size_t
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
inline
size_t
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
RetiredListMaxSize
(
size_t
nThreads
)
{
return
static_cast
<
size_t
>
(
1
.
25
*
...
...
@@ -247,8 +248,8 @@ RetiredListMaxSize(size_t nThreads) {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
bool
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
bool
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
TryEnqueue
(
Type
const
&
element
)
{
index_t
accessorId
=
Node_t
::
UndefinedIndex
;
if
(
!
LoadAccessorThreadIndex
(
accessorId
))
{
...
...
@@ -256,14 +257,10 @@ TryEnqueue(Type const & element) {
"Invalid thread ID."
);
}
// Register new node in pool:
Node_t
poolNode
;
int
nodeIndex
=
nodePool
.
Allocate
(
poolNode
);
int
nodeIndex
=
nodePool
.
Allocate
(
element
,
accessorId
);
if
(
nodeIndex
<
0
)
{
return
false
;
// Queue is at capacity
}
// Initialize node in pool:
Node_t
newNode
(
element
,
accessorId
);
nodePool
[
static_cast
<
index_t
>
(
nodeIndex
)]
=
newNode
;
OperationDesc
enqOp
(
true
,
// pending
true
,
// enqueue
...
...
@@ -276,8 +273,8 @@ TryEnqueue(Type const & element) {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
bool
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
bool
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
TryDequeue
(
Type
&
retElement
)
{
index_t
accessorId
=
static_cast
<
index_t
>
(
-
1
);
if
(
!
LoadAccessorThreadIndex
(
accessorId
))
{
...
...
@@ -313,11 +310,11 @@ TryDequeue(Type & retElement) {
retElement
=
Type
();
return
false
;
}
Node_t
&
node
=
nodePool
[
nodeIdx
];
Node_t
&
node
=
nodePool
[
static_cast
<
int
>
(
nodeIdx
)
];
assert
(
node
.
DequeueAID
().
Load
()
==
accessorId
);
// Return value of node next to node dequeued in this operation:
index_t
nextNodeIdx
=
node
.
NextPoolIdx
();
retElement
=
nodePool
[
nextNodeIdx
].
Value
();
retElement
=
nodePool
[
static_cast
<
int
>
(
nextNodeIdx
)
].
Value
();
// Value is safe. Mark node as non-pending and available for reclamation by
// setting this operation's node index to UndefinedIndex:
OperationDesc
noOp
(
...
...
@@ -338,14 +335,14 @@ TryDequeue(Type & retElement) {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
void
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
void
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
HelpEnqueue
(
unsigned
int
accessorId
)
{
while
(
IsPending
(
accessorId
))
{
index_t
lastIdx
=
tailIdx
.
Load
();
// Guard tail:
hp
.
GuardPointer
(
0
,
lastIdx
);
Node_t
&
lastNode
=
nodePool
[
lastIdx
];
Node_t
&
lastNode
=
nodePool
[
static_cast
<
int
>
(
lastIdx
)
];
index_t
nextIdx
=
lastNode
.
NextPoolIdx
();
if
(
lastIdx
==
tailIdx
.
Load
())
{
// Last node still is tail
...
...
@@ -369,17 +366,17 @@ HelpEnqueue(unsigned int accessorId) {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
void
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
void
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
HelpFinishEnqueue
()
{
// Load node pointed at by tail:
index_t
lastIdx
=
tailIdx
.
Load
();
// Guard tail:
hp
.
GuardPointer
(
0
,
lastIdx
);
// Load tail->next:
Node_t
&
lastNode
=
nodePool
[
lastIdx
];
Node_t
&
lastNode
=
nodePool
[
static_cast
<
int
>
(
lastIdx
)
];
index_t
nextIdx
=
lastNode
.
NextPoolIdx
();
Node_t
&
nextNode
=
nodePool
[
nextIdx
];
Node_t
&
nextNode
=
nodePool
[
static_cast
<
int
>
(
nextIdx
)
];
// tail->next not undefined => unfinished ENQ
if
(
nextIdx
!=
Node_t
::
UndefinedIndex
)
{
// Load accessor id from last (non-tail) element in list:
...
...
@@ -408,15 +405,15 @@ HelpFinishEnqueue() {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
void
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
void
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
HelpDequeue
(
index_t
accessorId
)
{
while
(
IsPending
(
accessorId
))
{
index_t
firstIdx
=
headIdx
.
Load
();
// Guard head:
hp
.
GuardPointer
(
0
,
firstIdx
);
// Order matters for these assignments:
Node_t
&
first
=
nodePool
[
firstIdx
];
Node_t
&
first
=
nodePool
[
static_cast
<
int
>
(
firstIdx
)
];
index_t
lastIdx
=
tailIdx
.
Load
();
index_t
nextIdx
=
first
.
NextPoolIdx
();
// Guard head->next:
...
...
@@ -499,19 +496,19 @@ HelpDequeue(index_t accessorId) {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
void
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
void
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
HelpFinishDequeue
()
{
index_t
firstIdx
=
headIdx
.
Load
();
// Guard head:
hp
.
GuardPointer
(
0
,
firstIdx
);
Node_t
&
first
=
nodePool
[
firstIdx
];
Node_t
&
first
=
nodePool
[
static_cast
<
int
>
(
firstIdx
)
];
index_t
nextIdx
=
first
.
NextPoolIdx
();
// Guard and head->next
// Actually not necessary, as head->next will only change from Undefined
// to a node index value, but not back to Undefined.
hp
.
GuardPointer
(
1
,
nextIdx
);
if
(
nextIdx
!=
nodePool
[
firstIdx
].
NextPoolIdx
())
{
if
(
nextIdx
!=
nodePool
[
static_cast
<
int
>
(
firstIdx
)
].
NextPoolIdx
())
{
return
;
}
index_t
accessorId
=
first
.
DequeueAID
().
Load
();
...
...
@@ -542,8 +539,8 @@ HelpFinishDequeue() {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
void
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
void
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
Help
()
{
// Fairness guarantee in every thread:
// "Every other thread will help my operation before helping its
...
...
@@ -572,8 +569,8 @@ Help() {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
void
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
void
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
DeleteNodeCallback
(
index_t
releasedNodeIndex
)
{
if
(
!
NodeIsPending
(
releasedNodeIndex
))
{
nodePool
.
Free
(
static_cast
<
int
>
(
releasedNodeIndex
));
...
...
@@ -581,16 +578,16 @@ DeleteNodeCallback(index_t releasedNodeIndex) {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
inline
size_t
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
inline
size_t
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
GetCapacity
()
{
return
max_size_
;
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
inline
bool
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
inline
bool
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
NodeIsPending
(
index_t
nodeIdx
)
{
for
(
unsigned
int
accessorId
=
0
;
accessorId
<
num_states
;
++
accessorId
)
{
if
(
OperationDesc
(
operationDescriptions
[
accessorId
].
Load
()).
NodeIndex
==
...
...
@@ -602,8 +599,8 @@ NodeIsPending(index_t nodeIdx) {
}
template
<
typename
Type
,
class
NodeAllocator
,
class
OpAllocator
,
class
ValuePool
>
inline
bool
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>::
typename
Type
,
class
ValuePool
,
class
NodeAllocator
,
class
OpAllocator
>
inline
bool
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>::
IsPending
(
unsigned
int
accessorId
)
{
OperationDesc
opDesc
(
operationDescriptions
[
accessorId
].
Load
());
return
opDesc
.
Pending
;
...
...
containers_cpp/include/embb/containers/wait_free_mpmc_queue.h
View file @
df279e99
...
...
@@ -127,7 +127,7 @@ class WaitFreeMPMCQueueNode {
/**< [IN] New pointer value to set */
);
inline
bool
Next
_
IsNull
()
const
;
inline
bool
NextIsNull
()
const
;
inline
uint32_t
EnqueueAID
()
const
;
...
...
@@ -155,18 +155,18 @@ class WaitFreeMPMCQueueNode {
*/
template
<
typename
Type
,
class
ValuePool
=
WaitFreeArrayValuePool
<
bool
,
false
>
,
class
NodeAllocator
=
embb
::
base
::
AllocatorCacheAligned
<
internal
::
WaitFreeMPMCQueueNode
<
Type
>
>
,
class
OpAllocator
=
embb
::
base
::
AllocatorCacheAligned
<
embb
::
base
::
Atomic
<
uint32_t
>
>
,
class
ValuePool
=
WaitFreeArrayValuePool
<
bool
,
false
>
embb
::
base
::
AllocatorCacheAligned
<
embb
::
base
::
Atomic
<
uint32_t
>
>
>
class
WaitFreeMPMCQueue
{
private
:
typedef
internal
::
WaitFreeMPMCQueueNode
<
Type
>
Node_t
;
typedef
typename
internal
::
WaitFreeMPMCQueueNode
<
Type
>::
index_t
index_t
;
typedef
WaitFreeMPMCQueue
<
Type
,
NodeAllocator
,
OpAllocator
,
ValuePool
>
self_t
;
typedef
WaitFreeMPMCQueue
<
Type
,
ValuePool
,
NodeAllocator
,
OpAllocator
>
self_t
;
typedef
internal
::
IndexedObjectPool
<
internal
::
WaitFreeMPMCQueueNode
<
Type
>
,
ValuePool
,
NodeAllocator
>
NodePool_t
;
...
...
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