mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Fix potential deadlock in distributed contour tree
The `HierarchicalAugmenter` used in the distributed contour tree filter attempts to save memory by releasing buffers used to send and receive data after the DIY enqueues and dequeues are posted. This works as long as the DIY serialization process copies the data in the arrays. However, changes are coming where the data is sent directly from the buffers. These changes cause a deadlock because the enqueue places a read lock until the data is sent while the release tried to get a write lock. The solution is simply to "forget" the array rather than explicitly delete it. In this case, the array will automatically be deleted once everyone is done with it.
This commit is contained in:
parent
c9b4e9b7f2
commit
58fc4d8267
@ -467,8 +467,12 @@ void HierarchicalAugmenter<FieldType>::RetrieveInAttachmentPoints()
|
||||
template <typename FieldType>
|
||||
void HierarchicalAugmenter<FieldType>::ReleaseSwapArrays()
|
||||
{ // ReleaseSwapArrays()
|
||||
this->OutData.ReleaseResources();
|
||||
this->InData.ReleaseResources();
|
||||
// Rather than explicitly delete the arrays, we are going to "forget" them and
|
||||
// just release our reference count on them. If no one else is using them, the
|
||||
// memory will actually be deleted. But if an array is being used, it will
|
||||
// continue to be managed until it is not.
|
||||
this->OutData = decltype(this->OutData){};
|
||||
this->InData = decltype(this->InData){};
|
||||
} // ReleaseSwapArrays()
|
||||
|
||||
|
||||
|
@ -127,7 +127,10 @@ public:
|
||||
blockData->HierarchicalAugmenter.PrepareOutAttachmentPoints(round);
|
||||
// TODO/FIXME: Correct function? Correct round?
|
||||
rp.enqueue(target, blockData->HierarchicalAugmenter.OutData);
|
||||
// TODO/FIXME: Is it save to already release HierarchicalAugmenter.OutData (and InData) here. Don't we free the arrays before the other block had the chance to complete its rp.dequeue?
|
||||
// Note: HierarchicalAugmenter.ReleaseSwapArrays() does not necessarily delete the
|
||||
// arrays. Rather, it releases the reference to them. If, for example, the data
|
||||
// for HierarchicalAugmenter.OutData is still in flight, the data will continue to
|
||||
// exist until it is sent.
|
||||
blockData->HierarchicalAugmenter.ReleaseSwapArrays();
|
||||
}
|
||||
}
|
||||
|
@ -101,34 +101,13 @@ public:
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~HierarchicalAugmenterInOutData();
|
||||
|
||||
/// Clear all arrays
|
||||
void ReleaseResources();
|
||||
~HierarchicalAugmenterInOutData() = default;
|
||||
|
||||
/// Print contents fo this objects
|
||||
std::string DebugPrint(std::string message, const char* fileName, long lineNum);
|
||||
|
||||
}; // class HierarchicalAugmenterInOutData
|
||||
|
||||
template <typename FieldType>
|
||||
HierarchicalAugmenterInOutData<FieldType>::~HierarchicalAugmenterInOutData()
|
||||
{
|
||||
this->ReleaseResources();
|
||||
}
|
||||
|
||||
// routine to release memory used for out arrays
|
||||
template <typename FieldType>
|
||||
void HierarchicalAugmenterInOutData<FieldType>::ReleaseResources()
|
||||
{ // ReleaseResources()
|
||||
this->GlobalRegularIds.ReleaseResources();
|
||||
this->DataValues.ReleaseResources();
|
||||
this->SupernodeIds.ReleaseResources();
|
||||
this->Superparents.ReleaseResources();
|
||||
this->SuperparentRounds.ReleaseResources();
|
||||
this->WhichRounds.ReleaseResources();
|
||||
} // ReleaseResources()
|
||||
|
||||
template <typename FieldType>
|
||||
std::string HierarchicalAugmenterInOutData<FieldType>::DebugPrint(std::string message,
|
||||
const char* fileName,
|
||||
|
Loading…
Reference in New Issue
Block a user