Skip to content

Commit

Permalink
[core] Use Mersenne Twister engine with C++11
Browse files Browse the repository at this point in the history
instead of the std::random_device.
Fixed max value probability for the default (C++03) rand().
  • Loading branch information
maxsharabayko committed Oct 13, 2021
1 parent ac6ec62 commit 489c5fc
Showing 1 changed file with 12 additions and 7 deletions.
19 changes: 12 additions & 7 deletions srtcore/sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,11 @@ bool srt::sync::CGlobEvent::waitForEvent()
namespace srt
{
#if HAVE_CXX11
static std::random_device& randomDevice()
static std::mt19937& randomGen()
{
static std::random_device s_RandomDevice;
return s_RandomDevice;
static std::mt19937 s_GenMT19937(s_RandomDevice());
return s_GenMT19937;
}
#elif defined(_WIN32) && defined(__MINGW32__)
static void initRandSeed()
Expand All @@ -300,7 +301,7 @@ static pthread_once_t s_InitRandSeedOnce = PTHREAD_ONCE_INIT;
static unsigned int genRandSeed()
{
// Duration::count() does not depend on any global objects,
// therefore it is preferred over count)microseconds(..).
// therefore it is preferred over count_microseconds(..).
const int64_t seed = sync::steady_clock::now().time_since_epoch().count();
return (unsigned int) seed;
}
Expand All @@ -325,7 +326,7 @@ int srt::sync::genRandomInt(int minVal, int maxVal)
sync::ScopedLock lck(s_mtxRandomDevice);
#if HAVE_CXX11
uniform_int_distribution<> dis(minVal, maxVal);
return dis(randomDevice());
return dis(randomGen());
#else
#if defined(__MINGW32__)
// No rand_r(..) for MinGW.
Expand All @@ -342,9 +343,13 @@ int srt::sync::genRandomInt(int minVal, int maxVal)
#endif

// Map onto [minVal, maxVal].
// Note. The probablity to get maxVal as the result is minuscule.
const int res = minVal + static_cast<int>((maxVal - minVal) * rand_0_1);
return res;
// Note. There is a minuscule probablity to get maxVal+1 as the result.
// So we have to use long long to handle cases when maxVal = INT32_MAX.
// Also we must check 'res' does not exceed maxVal,
// which may happen if rand_0_1 = 1, even though the chances are low.
const long long llMaxVal = maxVal;
const int res = minVal + static_cast<int>((llMaxVal + 1 - minVal) * rand_0_1);
return min(res, maxVal);
#endif // HAVE_CXX11
}

0 comments on commit 489c5fc

Please sign in to comment.