Commit d3a090c3 by Tobias Fuchs

containers_cpp: reactivated reclamation condition, adjusted node pool size in WaitFreeMPMCQueue

parent a0d83966
...@@ -163,9 +163,12 @@ WaitFreeMPMCQueue(size_t capacity) ...@@ -163,9 +163,12 @@ WaitFreeMPMCQueue(size_t capacity)
// Node pool size, with respect to the maximum number of // Node pool size, with respect to the maximum number of
// retired nodes not eligible for reuse due to hazard pointers: // retired nodes not eligible for reuse due to hazard pointers:
node_pool_size( node_pool_size(
// numThreads caused trouble here // Nodes in hazard pointers' retired lists
(hp.GetRetiredListMaxSize() * (hp.GetRetiredListMaxSize() *
embb::base::Thread::GetThreadsMaxCount()) + embb::base::Thread::GetThreadsMaxCount()) +
// Nodes guarded in operation descriptions
embb::base::Thread::GetThreadsMaxCount() +
// Actual capacity + 1 sentinel node
max_size_ + 1), max_size_ + 1),
nodePool(node_pool_size, nullNode) { nodePool(node_pool_size, nullNode) {
// Assert width of binary representation of operation description // Assert width of binary representation of operation description
...@@ -504,17 +507,19 @@ HelpFinishDequeue() { ...@@ -504,17 +507,19 @@ HelpFinishDequeue() {
hp.GuardPointer(0, firstIdx); hp.GuardPointer(0, firstIdx);
Node_t & first = nodePool[firstIdx]; Node_t & first = nodePool[firstIdx];
index_t nextIdx = first.NextPoolIdx(); index_t nextIdx = first.NextPoolIdx();
// Guard and head->next: // 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); hp.GuardPointer(1, nextIdx);
if (nextIdx != nodePool[firstIdx].NextPoolIdx()) {
return;
}
index_t accessorId = first.DequeueAID().Load(); index_t accessorId = first.DequeueAID().Load();
if (accessorId != Node_t::UndefinedIndex) { if (accessorId != Node_t::UndefinedIndex) {
// head.DeqeueueAID is set to the accessor id that won the last CAS // head.DeqeueueAID is set to the accessor id that won the last CAS
// in HelpDequeue // in HelpDequeue
OperationDesc curOp(operationDescriptions[accessorId].Load()); OperationDesc curOp(operationDescriptions[accessorId].Load());
if (firstIdx == headIdx.Load() && if (firstIdx == headIdx.Load() &&
// This check is missing in the original publication but required
// to validate head->next:
nextIdx == first.NextPoolIdx() &&
nextIdx != Node_t::UndefinedIndex) { nextIdx != Node_t::UndefinedIndex) {
// Set state of helped operation to NONPENDING: // Set state of helped operation to NONPENDING:
OperationDesc newOp( OperationDesc newOp(
...@@ -570,7 +575,9 @@ template< ...@@ -570,7 +575,9 @@ template<
typename Type, class NodeAllocator, class OpAllocator, class ValuePool > typename Type, class NodeAllocator, class OpAllocator, class ValuePool >
void WaitFreeMPMCQueue<Type, NodeAllocator, OpAllocator, ValuePool>:: void WaitFreeMPMCQueue<Type, NodeAllocator, OpAllocator, ValuePool>::
DeleteNodeCallback(index_t releasedNodeIndex) { DeleteNodeCallback(index_t releasedNodeIndex) {
nodePool.Free(static_cast<int>(releasedNodeIndex)); if (!NodeIsPending(releasedNodeIndex)) {
nodePool.Free(static_cast<int>(releasedNodeIndex));
}
} }
template< template<
...@@ -580,6 +587,20 @@ GetCapacity() { ...@@ -580,6 +587,20 @@ GetCapacity() {
return max_size_; return max_size_;
} }
template<
typename Type, class NodeAllocator, class OpAllocator, class ValuePool >
inline bool WaitFreeMPMCQueue<Type, NodeAllocator, OpAllocator, ValuePool>::
NodeIsPending(index_t nodeIdx) {
for (unsigned int accessorId = 0; accessorId < num_states; ++accessorId) {
if (OperationDesc(operationDescriptions[accessorId].Load()).NodeIndex ==
nodeIdx) {
return true;
}
}
return false;
}
template< template<
typename Type, class NodeAllocator, class OpAllocator, class ValuePool > typename Type, class NodeAllocator, class OpAllocator, class ValuePool >
inline bool WaitFreeMPMCQueue<Type, NodeAllocator, OpAllocator, ValuePool>:: inline bool WaitFreeMPMCQueue<Type, NodeAllocator, OpAllocator, ValuePool>::
......
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