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);
 }

Reply via email to