sc/source/core/inc/interpre.hxx | 6 +++++- sc/source/core/tool/interpr1.cxx | 30 ++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 9 deletions(-)
New commits: commit 0cc4ed1a0323356cc91192a9097be0aa08857efd Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Mon Mar 4 20:46:42 2024 +0000 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Wed Mar 6 18:58:47 2024 +0100 tdf#160056 comphelper::rng takes a mutex for every random number Change-Id: Ic4b50a9ea9e9eda62ca0877337462354b3fe3675 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164382 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Andras Timar <andras.ti...@collabora.com> diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 64b9a8ae5b2c..ffaac09e1d89 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -34,6 +34,7 @@ #include <map> #include <memory> +#include <random> #include <vector> #include <limits> #include <ostream> @@ -180,6 +181,7 @@ private: ScCalcConfig maCalcConfig; formula::FormulaTokenIterator aCode; + std::optional<std::mt19937> oRNG; ScAddress aPos; ScTokenArray* pArr; ScInterpreterContext& mrContext; @@ -497,6 +499,8 @@ private: // Returns true if last jump was executed and result matrix pushed. bool JumpMatrix( short nStackLevel ); + std::mt19937& GetRNG(); + double Compare( ScQueryOp eOp ); /** @param pOptions NULL means case sensitivity document option is to be used! @@ -521,7 +525,7 @@ private: void ScPi(); void ScRandom(); void ScRandbetween(); - void ScRandomImpl( const std::function<double( double fFirst, double fLast )>& RandomFunc, + void ScRandomImpl( const std::function<double( std::mt19937& rRng, double fFirst, double fLast )>& RandomFunc, double fFirst, double fLast ); void ScTrue(); void ScFalse(); diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 8412c0355ed0..f5a69a0e7159 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -1737,7 +1737,7 @@ void ScInterpreter::ScPi() PushDouble(M_PI); } -void ScInterpreter::ScRandomImpl( const std::function<double( double fFirst, double fLast )>& RandomFunc, +void ScInterpreter::ScRandomImpl( const std::function<double( std::mt19937& rRng, double fFirst, double fLast )>& RandomFunc, double fFirst, double fLast ) { if (bMatrixFormula) @@ -1764,7 +1764,7 @@ void ScInterpreter::ScRandomImpl( const std::function<double( double fFirst, dou // default are executed in array context unless // FA.setPropertyValue("IsArrayFunction",False) was set, return a // scalar double instead of a 1x1 matrix object. tdf#128218 - PushDouble( RandomFunc( fFirst, fLast)); + PushDouble( RandomFunc( GetRNG(), fFirst, fLast)); return; } @@ -1785,7 +1785,7 @@ void ScInterpreter::ScRandomImpl( const std::function<double( double fFirst, dou { for (SCROW j=0; j < nRows; ++j) { - pResMat->PutDouble( RandomFunc( fFirst, fLast), + pResMat->PutDouble( RandomFunc( GetRNG(), fFirst, fLast), static_cast<SCSIZE>(i), static_cast<SCSIZE>(j)); } } @@ -1794,15 +1794,28 @@ void ScInterpreter::ScRandomImpl( const std::function<double( double fFirst, dou } else { - PushDouble( RandomFunc( fFirst, fLast)); + PushDouble( RandomFunc( GetRNG(), fFirst, fLast)); } } +std::mt19937& ScInterpreter::GetRNG() +{ + if (!oRNG) + { + // create a per-interpreter Random Number Generator, seeded from the global rng, so we don't have + // to lock a mutex to generate a random number + unsigned int nSeed(comphelper::rng::uniform_uint_distribution(0, std::numeric_limits<sal_uInt32>::max())); + oRNG = std::mt19937(nSeed); + } + return *oRNG; +} + void ScInterpreter::ScRandom() { - auto RandomFunc = []( double, double ) + auto RandomFunc = [](std::mt19937& rRNG, double, double) { - return comphelper::rng::uniform_real_distribution(); + std::uniform_real_distribution<double> dist(0.0, 1.0); + return dist(rRNG); }; ScRandomImpl( RandomFunc, 0.0, 0.0); } @@ -1822,9 +1835,10 @@ void ScInterpreter::ScRandbetween() return; } fMax = std::nextafter( fMax+1, -DBL_MAX); - auto RandomFunc = []( double fFirst, double fLast ) + auto RandomFunc = [](std::mt19937& rRNG, double fFirst, double fLast) { - return floor( comphelper::rng::uniform_real_distribution( fFirst, fLast)); + std::uniform_real_distribution<double> dist(fFirst, fLast); + return floor(dist(rRNG)); }; ScRandomImpl( RandomFunc, fMin, fMax); }