diff options
author | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-03-04 20:46:42 +0000 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-03-05 21:19:21 +0100 |
commit | 8fd18bd4616ab06049aa0c760b9248c04373863f (patch) | |
tree | cc224964db3d33b2bc3e38ae1b085008dcf7a4f8 /sc/source | |
parent | 58d2abd2ed85beed48a7677f2b186914c6f2a6c9 (diff) |
tdf#160056 comphelper::rng takes a mutex for every random number
Change-Id: Ic4b50a9ea9e9eda62ca0877337462354b3fe3675
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164403
Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 30 |
2 files changed, 27 insertions, 9 deletions
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index ebff66afafe0..b92833b9535d 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -35,6 +35,7 @@ #include <map> #include <memory> +#include <random> #include <vector> #include <limits> #include <ostream> @@ -231,6 +232,7 @@ private: ScCalcConfig maCalcConfig; formula::FormulaTokenIterator aCode; + std::optional<std::mt19937> oRNG; ScAddress aPos; ScTokenArray* pArr; ScInterpreterContext& mrContext; @@ -552,6 +554,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! @@ -576,7 +580,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 f6c5409bdbc3..0a9ee65ff37c 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); } |