Skip to content

Commit

Permalink
ENH: using standard library's mutex primitives
Browse files Browse the repository at this point in the history
When ITK was conceived about 20 years ago, standard library was not fully
and properly implemented by all the target compilers. It also did not include
threading primitives. So decision was made for ITK to abstract away low level
operations based on Posix threads. By mid 2000s, most compilers had good
support of then-current standard library and language standard (C++03).
The last piece of the puzzle was C++11 language revision and accompanying
standard library. It took some years for all major compilers to support it,
but it includes all the threading primitives which existed in ITK.

So today, we refactor all classes to use std::mutex and friends directly.

Change-Id: I63de1b6ff1b8bcc52bc759fd5da27d8bba5b1a01
  • Loading branch information
dzenanz committed Oct 31, 2018
1 parent 4df4b69 commit d0a8534
Show file tree
Hide file tree
Showing 68 changed files with 263 additions and 296 deletions.
8 changes: 4 additions & 4 deletions Modules/Core/Common/include/itkBuildInformation.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include "itkMacro.h"
#include "itkObject.h"
#include "itkSimpleFastMutexLock.h"
#include <mutex>

namespace itk
{
Expand Down Expand Up @@ -93,9 +93,9 @@ class ITKCommon_EXPORT BuildInformation final: public Object
BuildInformation();

/** To lock on the internal variables */
static SimpleFastMutexLock m_Mutex;
static Pointer m_InformationInstance;
static MapType m_Map;
static std::mutex m_Mutex;
static Pointer m_InformationInstance;
static MapType m_Map;
}; // end of class
} // end namespace itk
#endif
2 changes: 1 addition & 1 deletion Modules/Core/Common/include/itkImageBase.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

#include "itkImageBase.h"

#include "itkFastMutexLock.h"
#include <mutex>
#include "itkProcessObject.h"
#include "itkSpatialOrientation.h"
#include <cstring>
Expand Down
4 changes: 2 additions & 2 deletions Modules/Core/Common/include/itkLoggerThreadWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include <thread>

#include "itkObjectFactory.h"
#include "itkSimpleFastMutexLock.h"
#include <mutex>

namespace itk
{
Expand Down Expand Up @@ -131,7 +131,7 @@ class ITK_TEMPLATE_EXPORT LoggerThreadWrapper:public SimpleLoggerType

OutputContainerType m_OutputQ;

mutable SimpleFastMutexLock m_Mutex;
mutable std::mutex m_Mutex;

DelayType m_Delay;

Expand Down
40 changes: 20 additions & 20 deletions Modules/Core/Common/include/itkLoggerThreadWrapper.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ namespace itk
template< typename SimpleLoggerType >
void LoggerThreadWrapper< SimpleLoggerType >::SetPriorityLevel(PriorityLevelType level)
{
this->m_Mutex.Lock();
this->m_Mutex.lock();
this->m_OperationQ.push(SET_PRIORITY_LEVEL);
this->m_LevelQ.push(level);
this->m_Mutex.Unlock();
this->m_Mutex.unlock();
}

/** Get the priority level for the current logger. Only messages that have
Expand All @@ -42,69 +42,69 @@ void LoggerThreadWrapper< SimpleLoggerType >::SetPriorityLevel(PriorityLevelType
template< typename SimpleLoggerType >
typename SimpleLoggerType::PriorityLevelType LoggerThreadWrapper< SimpleLoggerType >::GetPriorityLevel() const
{
this->m_Mutex.Lock();
this->m_Mutex.lock();
PriorityLevelType level = this->m_PriorityLevel;
this->m_Mutex.Unlock();
this->m_Mutex.unlock();
return level;
}

template< typename SimpleLoggerType >
void LoggerThreadWrapper< SimpleLoggerType >::SetLevelForFlushing(PriorityLevelType level)
{
this->m_Mutex.Lock();
this->m_Mutex.lock();
this->m_LevelForFlushing = level;
this->m_OperationQ.push(SET_LEVEL_FOR_FLUSHING);
this->m_LevelQ.push(level);
this->m_Mutex.Unlock();
this->m_Mutex.unlock();
}

template< typename SimpleLoggerType >
typename SimpleLoggerType::PriorityLevelType LoggerThreadWrapper< SimpleLoggerType >::GetLevelForFlushing() const
{
this->m_Mutex.Lock();
this->m_Mutex.lock();
PriorityLevelType level = this->m_LevelForFlushing;
this->m_Mutex.Unlock();
this->m_Mutex.unlock();
return level;
}

template< typename SimpleLoggerType >
void LoggerThreadWrapper< SimpleLoggerType >::SetDelay(DelayType delay)
{
this->m_Mutex.Lock();
this->m_Mutex.lock();
this->m_Delay = delay;
this->m_Mutex.Unlock();
this->m_Mutex.unlock();
}

template< typename SimpleLoggerType >
typename LoggerThreadWrapper< SimpleLoggerType >::DelayType LoggerThreadWrapper< SimpleLoggerType >::GetDelay() const
{
this->m_Mutex.Lock();
this->m_Mutex.lock();
DelayType delay = this->m_Delay;
this->m_Mutex.Unlock();
this->m_Mutex.unlock();
return delay;
}

/** Adds an output stream to the MultipleLogOutput for writing. */
template< typename SimpleLoggerType >
void LoggerThreadWrapper< SimpleLoggerType >::AddLogOutput(OutputType *output)
{
this->m_Mutex.Lock();
this->m_Mutex.lock();
this->m_OperationQ.push(ADD_LOG_OUTPUT);
this->m_OutputQ.push(output);
this->m_Mutex.Unlock();
this->m_Mutex.unlock();
}

template< typename SimpleLoggerType >
void LoggerThreadWrapper< SimpleLoggerType >::Write(PriorityLevelType level, std::string const & content)
{
this->m_Mutex.Lock();
this->m_Mutex.lock();
if ( this->m_PriorityLevel >= level )
{
this->m_OperationQ.push(WRITE);
this->m_MessageQ.push(content);
this->m_LevelQ.push(level);
}
this->m_Mutex.Unlock();
this->m_Mutex.unlock();
if ( this->m_LevelForFlushing >= level )
{
this->Flush();
Expand All @@ -114,7 +114,7 @@ void LoggerThreadWrapper< SimpleLoggerType >::Write(PriorityLevelType level, std
template< typename SimpleLoggerType >
void LoggerThreadWrapper< SimpleLoggerType >::Flush()
{
this->m_Mutex.Lock();
this->m_Mutex.lock();

while ( !this->m_OperationQ.empty() )
{
Expand Down Expand Up @@ -144,7 +144,7 @@ void LoggerThreadWrapper< SimpleLoggerType >::Flush()
}
this->SimpleLoggerType::Flush();
this->m_Output->Flush();
this->m_Mutex.Unlock();
this->m_Mutex.unlock();
}

/** Constructor */
Expand Down Expand Up @@ -175,7 +175,7 @@ LoggerThreadWrapper< SimpleLoggerType >
{
while ( !m_TerminationRequested )
{
m_Mutex.Lock();
m_Mutex.lock();
while ( !m_OperationQ.empty() )
{
switch ( m_OperationQ.front() )
Expand Down Expand Up @@ -203,7 +203,7 @@ LoggerThreadWrapper< SimpleLoggerType >
}
m_OperationQ.pop();
}
m_Mutex.Unlock();
m_Mutex.unlock();
SimpleLoggerType::Flush();
itksys::SystemTools::Delay(this->GetDelay());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#include "itkRandomVariateGeneratorBase.h"
#include "itkIntTypes.h"
#include "itkMath.h"
#include "itkMutexLockHolder.h"
#include "itkSimpleFastMutexLock.h"
#include <mutex>
#include <mutex>
#include <climits>
#include <ctime>

Expand Down Expand Up @@ -282,12 +282,12 @@ class ITKCommon_EXPORT MersenneTwisterRandomVariateGenerator:
static Pointer CreateInstance();

// Local lock to enable concurrent access to singleton
SimpleFastMutexLock m_InstanceLock;
std::mutex m_InstanceLock;

// Static/Global Variable need to be thread-safely accessed
static Pointer m_StaticInstance;
static SimpleFastMutexLock m_StaticInstanceLock;
static IntegerType m_StaticDiffer;
static Pointer m_StaticInstance;
static std::recursive_mutex m_StaticInstanceLock;
static IntegerType m_StaticDiffer;

}; // end of class

Expand All @@ -296,7 +296,7 @@ class ITKCommon_EXPORT MersenneTwisterRandomVariateGenerator:
inline void
MersenneTwisterRandomVariateGenerator::Initialize(const IntegerType seed)
{
MutexLockHolder<SimpleFastMutexLock> mutexHolder(m_InstanceLock);
std::lock_guard<std::mutex> mutexHolder(m_InstanceLock);
this->m_Seed = seed;
// Initialize generator state with seed
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
Expand Down Expand Up @@ -367,7 +367,7 @@ MersenneTwisterRandomVariateGenerator::SetSeed()
inline MersenneTwisterRandomVariateGenerator::IntegerType
MersenneTwisterRandomVariateGenerator::GetSeed()
{
MutexLockHolder<SimpleFastMutexLock> mutexHolder(m_InstanceLock);
std::lock_guard<std::mutex> mutexHolder(m_InstanceLock);
volatile IntegerType seed = this->m_Seed;
return seed;
}
Expand Down
8 changes: 5 additions & 3 deletions Modules/Core/Common/include/itkPlatformMultiThreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
#define itkPlatformMultiThreader_h

#include "itkMultiThreaderBase.h"
#include "itkMutexLock.h"
#include <mutex>
#include <memory>

namespace itk
{
Expand Down Expand Up @@ -143,7 +144,7 @@ It can affect all MultiThreaderBase's derived classes in ITK");
struct WorkUnitInfo: MultiThreaderBase::WorkUnitInfo
{
int *ActiveFlag;
MutexLock::Pointer ActiveFlagLock;
std::shared_ptr< std::mutex > ActiveFlagLock;
};

protected:
Expand All @@ -160,7 +161,8 @@ It can affect all MultiThreaderBase's derived classes in ITK");
/** Storage of MutexFunctions and ints used to control spawned
* threads and the spawned thread ids. */
int m_SpawnedThreadActiveFlag[ITK_MAX_THREADS];
MutexLock::Pointer m_SpawnedThreadActiveFlagLock[ITK_MAX_THREADS];
std::shared_ptr< std::mutex >
m_SpawnedThreadActiveFlagLock[ITK_MAX_THREADS];
ThreadProcessIdType m_SpawnedThreadProcessID[ITK_MAX_THREADS];
WorkUnitInfo m_SpawnedThreadInfoArray[ITK_MAX_THREADS];

Expand Down
4 changes: 2 additions & 2 deletions Modules/Core/Common/include/itkStdStreamLogOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <iostream>
#include <string>

#include "itkSimpleFastMutexLock.h"
#include <mutex>
#include "itkLogOutput.h"

namespace itk
Expand Down Expand Up @@ -86,7 +86,7 @@ class ITKCommon_EXPORT StdStreamLogOutput:public LogOutput

StreamPointerType m_Stream;

SimpleFastMutexLock m_Mutex;
std::mutex m_Mutex;
};
}

Expand Down
4 changes: 2 additions & 2 deletions Modules/Core/Common/include/itkThreadLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#define itkThreadLogger_h

#include "itkLogger.h"
#include "itkSimpleFastMutexLock.h"
#include <mutex>

#include <string>
#include <queue>
Expand Down Expand Up @@ -137,7 +137,7 @@ class ITKCommon_EXPORT ThreadLogger:public Logger

OutputContainerType m_OutputQ;

mutable SimpleFastMutexLock m_Mutex;
mutable std::mutex m_Mutex;

DelayType m_Delay;

Expand Down
2 changes: 1 addition & 1 deletion Modules/Core/Common/include/itkThreadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class ITKCommon_EXPORT ThreadPool : public Object

ThreadIdType GetMaximumNumberOfThreads() const
{
return m_Threads.size();
return static_cast< ThreadIdType >( m_Threads.size() );
}

/** The approximate number of idle threads. */
Expand Down
7 changes: 2 additions & 5 deletions Modules/Core/Common/src/itkBuildInformation.cxx.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
*=========================================================================*/

#include "itkBuildInformation.h"
#include "itkSimpleFastMutexLock.h"
#include "itkMutexLockHolder.h"
#include "itkObjectFactory.h"

#include <algorithm>
Expand All @@ -35,7 +33,7 @@ m_Map.emplace(

namespace itk {

SimpleFastMutexLock BuildInformation::m_Mutex;
std::mutex BuildInformation::m_Mutex;
BuildInformation::Pointer BuildInformation::m_InformationInstance;
BuildInformation::MapType BuildInformation::m_Map;

Expand All @@ -50,7 +48,7 @@ BuildInformation::Pointer
BuildInformation
::GetInstance()
{
MutexLockHolder<SimpleFastMutexLock> mutexHolder(m_Mutex);
std::lock_guard<std::mutex> mutexHolder(m_Mutex);
if (m_InformationInstance.IsNull())
{
m_InformationInstance = ObjectFactory<Self>::Create();
Expand Down Expand Up @@ -108,7 +106,6 @@ BuildInformation::GetAllKeys()
BuildInformation
::BuildInformation()
{
MutexLockHolder<SimpleFastMutexLock> mutexHolder(m_Mutex);
m_InformationInstance = this; //threads need this
m_InformationInstance->UnRegister(); // Remove extra reference

Expand Down
8 changes: 4 additions & 4 deletions Modules/Core/Common/src/itkImageSourceCommon.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@

#include "itkImageRegionSplitterSlowDimension.h"
#include "itkImageSourceCommon.h"
#include "itkSimpleFastMutexLock.h"
#include "itkMutexLockHolder.h"
#include <mutex>
#include <mutex>

namespace itk
{

namespace
{
SimpleFastMutexLock globalDefaultSplitterLock;
std::mutex globalDefaultSplitterLock;
ImageRegionSplitterBase::Pointer globalDefaultSplitter;
}

Expand All @@ -36,7 +36,7 @@ const ImageRegionSplitterBase* ImageSourceCommon::GetGlobalDefaultSplitter()
{
// thread safe lazy initialization, prevent race condition on
// setting, with an atomic set if null.
MutexLockHolder< SimpleFastMutexLock > lock(globalDefaultSplitterLock);
std::lock_guard< std::mutex > lock(globalDefaultSplitterLock);
if ( globalDefaultSplitter.IsNull() )
{
globalDefaultSplitter = ImageRegionSplitterSlowDimension::New().GetPointer();
Expand Down
2 changes: 1 addition & 1 deletion Modules/Core/Common/src/itkLightObject.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*=========================================================================*/
#include "itkLightObject.h"
#include "itkObjectFactory.h"
#include "itkFastMutexLock.h"
#include <mutex>

// Better name demanging for gcc
#if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 )
Expand Down
Loading

0 comments on commit d0a8534

Please sign in to comment.