Skip to content

Commit

Permalink
STYLE: Replace std::unique_lock with std::lock_guard in Filter.hxx files
Browse files Browse the repository at this point in the history
Removed explicit `unlock()` calls. Instead, just made sure that the `lock_guard`
variables go out of scope as soon as other threads are allowed to merge data.

Follow-up to pull request #4168
commit 1094cdd
"STYLE: Replace `std::unique_lock` with `std::lock_guard` in ThreadPool"
  • Loading branch information
N-Dekker authored and dzenanz committed Aug 24, 2023
1 parent ff64d3c commit 3335e69
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 66 deletions.
Expand Up @@ -120,28 +120,23 @@ LabelOverlapMeasuresImageFilter<TLabelImage>::ThreadedStreamedGenerateData(const
// local copy, this thread may do multiple merges.
while (true)
{

MapType tomerge{};
{
std::unique_lock<std::mutex> lock(m_Mutex);
const std::lock_guard<std::mutex> lockGuard(m_Mutex);

if (m_LabelSetMeasures.empty())
{
swap(m_LabelSetMeasures, localStatistics);
break;
}
else
{
// copy the output map to thread local storage
MapType tomerge;
swap(m_LabelSetMeasures, tomerge);

// allow other threads to merge data
lock.unlock();
// Move the data of the output map to the local `tomerge` and clear the output map.
swap(m_LabelSetMeasures, tomerge);

// Merge tomerge into localStatistics, locally
MergeMap(localStatistics, tomerge);
}
} // release lock
} // release lock, allow other threads to merge data

// Merge tomerge into localStatistics, locally
MergeMap(localStatistics, tomerge);
}
}

Expand Down
Expand Up @@ -257,28 +257,23 @@ LabelStatisticsImageFilter<TInputImage, TLabelImage>::ThreadedStreamedGenerateDa
// local copy, this thread may do multiple merges.
while (true)
{

MapType tomerge{};
{
std::unique_lock<std::mutex> lock(m_Mutex);
const std::lock_guard<std::mutex> lockGuard(m_Mutex);

if (m_LabelStatistics.empty())
{
swap(m_LabelStatistics, localStatistics);
break;
}
else
{
// copy the output map to thread local storage
MapType tomerge;
swap(m_LabelStatistics, tomerge);

// allow other threads to merge data
lock.unlock();
// Move the data of the output map to the local `tomerge` and clear the output map.
swap(m_LabelStatistics, tomerge);

// Merge tomerge into localStatistics, locally
MergeMap(localStatistics, tomerge);
}
} // release lock
} // release lock, allow other threads to merge data

// Merge tomerge into localStatistics, locally
MergeMap(localStatistics, tomerge);
}
}

Expand Down
40 changes: 18 additions & 22 deletions Modules/Numerics/Statistics/include/itkImageToHistogramFilter.hxx
Expand Up @@ -263,39 +263,35 @@ ImageToHistogramFilter<TImage>::ThreadedMergeHistogram(HistogramPointer && histo
{
while (true)
{

std::unique_lock<std::mutex> lock(m_Mutex);

if (m_MergeHistogram.IsNull())
{
m_MergeHistogram = std::move(histogram);
return;
}
else
HistogramPointer tomergeHistogram{};
{
const std::lock_guard<std::mutex> lockGuard(m_Mutex);

if (m_MergeHistogram.IsNull())
{
m_MergeHistogram = std::move(histogram);
return;
}

// merge/reduce the local results with current values in m_MergeHistogram

// take ownership locally
HistogramPointer tomergeHistogram;
swap(m_MergeHistogram, tomergeHistogram);

// allow other threads to merge data
lock.unlock();
} // release lock, allow other threads to merge data

using HistogramIterator = typename HistogramType::ConstIterator;
using HistogramIterator = typename HistogramType::ConstIterator;

HistogramIterator hit = tomergeHistogram->Begin();
HistogramIterator end = tomergeHistogram->End();
HistogramIterator hit = tomergeHistogram->Begin();
HistogramIterator end = tomergeHistogram->End();

typename HistogramType::IndexType index;
typename HistogramType::IndexType index;

while (hit != end)
{
histogram->GetIndex(hit.GetMeasurementVector(), index);
histogram->IncreaseFrequencyOfIndex(index, hit.GetFrequency());
++hit;
}
while (hit != end)
{
histogram->GetIndex(hit.GetMeasurementVector(), index);
histogram->IncreaseFrequencyOfIndex(index, hit.GetFrequency());
++hit;
}
}
}
Expand Down
Expand Up @@ -96,29 +96,27 @@ RelabelComponentImageFilter<TInputImage, TOutputImage>::ParallelComputeLabels(co
// local copy, this thread may do multiple merges.
while (true)
{
std::unique_lock<std::mutex> lock(m_Mutex);

if (m_SizeMap.empty())
{
swap(m_SizeMap, localSizeMap);
break;
}
else
MapType toMerge{};
{
// copy the output map to thread local storage
MapType toMerge;
swap(m_SizeMap, toMerge);

// allow other threads to merge data
lock.unlock();
const std::lock_guard<std::mutex> lockGuard(m_Mutex);

// Merge toMerge into localSizeMap, locally
for (auto & sizePair : toMerge)
if (m_SizeMap.empty())
{
localSizeMap[sizePair.first] += sizePair.second;
swap(m_SizeMap, localSizeMap);
break;
}

// Move the data of the output map to the local `toMerge` and clear the output map.
swap(m_SizeMap, toMerge);

} // release lock, allow other threads to merge data

// Merge toMerge into localSizeMap, locally
for (auto & sizePair : toMerge)
{
localSizeMap[sizePair.first] += sizePair.second;
}
} // release lock
}
}


Expand Down

0 comments on commit 3335e69

Please sign in to comment.