Skip to content

Commit f513700

Browse files
authored
Merge pull request #5325 from N-Dekker/MersenneTwisterRandomVariateGenerator-CreateRandomSeed
Allow initializing MersenneTwisterRandomVariateGenerator without mutex locking
2 parents e18f336 + 52856a3 commit f513700

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

Modules/Core/Common/include/itkMersenneTwisterRandomVariateGenerator.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,7 @@ class ITKCommon_EXPORT MersenneTwisterRandomVariateGenerator : public RandomVari
275275
void
276276
SetSeed()
277277
{
278-
// use time() and clock() to generate a unlikely-to-repeat seed.
279-
SetSeed(hash(time(nullptr), clock()));
278+
SetSeed(Self::CreateRandomSeed());
280279
}
281280
/** @ITKEndGrouping */
282281
/** Return the current seed
@@ -324,6 +323,17 @@ class ITKCommon_EXPORT MersenneTwisterRandomVariateGenerator : public RandomVari
324323
static Pointer
325324
CreateInstance();
326325

326+
/** Uses time() and clock() to generate a unlikely-to-repeat seed. */
327+
static IntegerType
328+
CreateRandomSeed()
329+
{
330+
return hash(time(nullptr), clock());
331+
}
332+
333+
/** Internal method to initialize a generator object without mutex locking. */
334+
void
335+
InitializeWithoutMutexLocking(const IntegerType seed);
336+
327337
// Internal state
328338
IntegerType m_State[StateVectorLength];
329339

Modules/Core/Common/src/itkMersenneTwisterRandomVariateGenerator.cxx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ hiBit(const IntegerType u)
3434
{
3535
return u & 0x80000000;
3636
}
37-
IntegerType
3837

38+
IntegerType
3939
loBit(const IntegerType u)
4040
{
4141
return u & 0x00000001;
@@ -98,7 +98,7 @@ MersenneTwisterRandomVariateGenerator::New()
9898
{
9999
MersenneTwisterRandomVariateGenerator::Pointer obj = MersenneTwisterRandomVariateGenerator::CreateInstance();
100100

101-
obj->SetSeed(MersenneTwisterRandomVariateGenerator::GetNextSeed());
101+
obj->InitializeWithoutMutexLocking(MersenneTwisterRandomVariateGenerator::GetNextSeed());
102102
return obj;
103103
}
104104

@@ -111,7 +111,7 @@ MersenneTwisterRandomVariateGenerator::GetInstance()
111111
if (!m_PimplGlobals->m_StaticInstance)
112112
{
113113
m_PimplGlobals->m_StaticInstance = MersenneTwisterRandomVariateGenerator::CreateInstance();
114-
m_PimplGlobals->m_StaticInstance->SetSeed();
114+
m_PimplGlobals->m_StaticInstance->InitializeWithoutMutexLocking(Self::CreateRandomSeed());
115115
}
116116

117117
return m_PimplGlobals->m_StaticInstance;
@@ -126,7 +126,10 @@ MersenneTwisterRandomVariateGenerator::ResetNextSeed()
126126
}
127127

128128

129-
MersenneTwisterRandomVariateGenerator::MersenneTwisterRandomVariateGenerator() { SetSeed(121212); }
129+
MersenneTwisterRandomVariateGenerator::MersenneTwisterRandomVariateGenerator()
130+
{
131+
this->InitializeWithoutMutexLocking(121212);
132+
}
130133

131134
MersenneTwisterRandomVariateGenerator::~MersenneTwisterRandomVariateGenerator() = default;
132135

@@ -162,10 +165,18 @@ MersenneTwisterRandomVariateGenerator::GetNextSeed()
162165
return GetInstance()->m_Seed + m_PimplGlobals->m_StaticDiffer++;
163166
}
164167

168+
165169
void
166170
MersenneTwisterRandomVariateGenerator::Initialize(const IntegerType seed)
167171
{
172+
// This is a public member function, so it must lock the mutex of the instance.
168173
const std::lock_guard<std::mutex> lockGuard(m_InstanceMutex);
174+
this->InitializeWithoutMutexLocking(seed);
175+
}
176+
177+
void
178+
MersenneTwisterRandomVariateGenerator::InitializeWithoutMutexLocking(const IntegerType seed)
179+
{
169180
m_Seed = seed;
170181
// Initialize generator state with seed
171182
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.

0 commit comments

Comments
 (0)