summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
authorCaolán McNamara <caolan.mcnamara@collabora.com>2024-03-04 20:46:42 +0000
committerCaolán McNamara <caolan.mcnamara@collabora.com>2024-03-05 21:19:21 +0100
commit8fd18bd4616ab06049aa0c760b9248c04373863f (patch)
treecc224964db3d33b2bc3e38ae1b085008dcf7a4f8 /sc/source
parent58d2abd2ed85beed48a7677f2b186914c6f2a6c9 (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.hxx6
-rw-r--r--sc/source/core/tool/interpr1.cxx30
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);
}