[Libreoffice-commits] core.git: Branch 'feature/calc-parallel' - 2 commits - include/svl sc/inc sc/source svl/source

Dennis Francis dennis.francis at collabora.co.uk
Fri Nov 17 12:53:35 UTC 2017


 include/svl/zforlist.hxx             |    2 ++
 sc/inc/column.hxx                    |    2 +-
 sc/inc/document.hxx                  |    9 ++++++---
 sc/inc/formulacell.hxx               |    2 +-
 sc/inc/interpretercontext.hxx        |   14 +++++++++++++-
 sc/inc/table.hxx                     |    2 +-
 sc/source/core/data/column2.cxx      |    2 +-
 sc/source/core/data/documen2.cxx     |    1 +
 sc/source/core/data/documen8.cxx     |    2 +-
 sc/source/core/data/formulacell.cxx  |    7 ++-----
 sc/source/core/data/table1.cxx       |    2 +-
 sc/source/core/inc/interpre.hxx      |    7 ++-----
 sc/source/core/tool/formulagroup.cxx |   15 +++++++++++----
 sc/source/core/tool/interpr4.cxx     |   22 +++++++---------------
 svl/source/numbers/zforlist.cxx      |    2 ++
 15 files changed, 52 insertions(+), 39 deletions(-)

New commits:
commit a50e4be42932985e78864a710836d1b3abbeca33
Author: Dennis Francis <dennis.francis at collabora.co.uk>
Date:   Fri Nov 17 18:20:31 2017 +0530

    Share SvNumberFormatter across worker threads...
    
    ... and use a mutex to protect SvNumberFormatter::IsNumberFormat()
    
    Change-Id: I6a015609062da1a92b84e514de7b304ece92052e

diff --git a/include/svl/zforlist.hxx b/include/svl/zforlist.hxx
index 969d0007380a..e5bac1dfc896 100644
--- a/include/svl/zforlist.hxx
+++ b/include/svl/zforlist.hxx
@@ -829,6 +829,8 @@ private:
     SVL_DLLPRIVATE static sal_uInt16            nSystemCurrencyPosition;
     SVL_DLLPRIVATE static SvNumberFormatterRegistry_Impl* pFormatterRegistry;
 
+    ::osl::Mutex maInstanceMutex;
+
     // get the registry, create one if none exists
     SVL_DLLPRIVATE static SvNumberFormatterRegistry_Impl& GetFormatterRegistry();
 
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index d8f0483f2f54..dde15e97ad0e 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -4399,10 +4399,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
 
             virtual void doWork() override
             {
-                std::unique_ptr<SvNumberFormatter> pFormatterForThisThread
-                    (new SvNumberFormatter(mpFormatter->GetComponentContext(),
-                                           mpFormatter->GetLanguage()));
-                ScInterpreterContext aContext(*mpDocument, pFormatterForThisThread.get());
+                ScInterpreterContext aContext(*mpDocument, mpFormatter);
 
                 mpDocument->CalculateInColumnInThread(aContext, mrTopPos, mnLength, mnThisThread, mnThreadsTotal).MergeBackIntoNonThreadedData(mpDocument->maNonThreaded);
             }
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index f4c236827a01..e7d23daa2a70 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -1077,6 +1077,8 @@ bool SvNumberFormatter::IsNumberFormat(const OUString& sString,
                                        sal_uInt32& F_Index,
                                        double& fOutNumber)
 {
+    ::osl::MutexGuard aGuard( maInstanceMutex );
+
     short FType;
     const SvNumberformat* pFormat = ImpSubstituteEntry( GetFormatEntry(F_Index));
     if (!pFormat)
commit 0572b9f65efbc5036aec99348fe263330717bc4f
Author: Dennis Francis <dennis.francis at collabora.co.uk>
Date:   Fri Nov 17 15:30:35 2017 +0530

    Move token-cache for doubles to ScInterpreterContext...
    
    ...from ScInterpreter and in the s/w interpreter, create
    a ScInterpreterContext for each thread for passing into
    per thread ScInterpreter constructor.
    
    Change-Id: I4e0abce043c7e1e70859efb2e5001fc284f416a9

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 44bee716bf18..acd899e7658a 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -583,7 +583,7 @@ public:
     void SetFormulaResults( SCROW nRow, const double* pResults, size_t nLen );
     void SetFormulaResults( SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen );
 
-    void CalculateInThread( const ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal );
+    void CalculateInThread( ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal );
     void HandleStuffAfterParallelCalculation( SCROW nRow, size_t nLen );
 
     void SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 04544fe5a64e..0061f5a1e47f 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -462,6 +462,8 @@ private:
     // plain thread_local static member.
     thread_local static ScDocumentThreadSpecific maThreadSpecific;
 
+    mutable ScInterpreterContext maInterpreterContext;
+
     sal_uInt16              nSrcVer;                        // file version (load/save)
     sal_uInt16              nFormulaTrackCount;
     HardRecalcState         eHardRecalcState;               // off, temporary, eternal
@@ -564,10 +566,11 @@ public:
 
     SC_DLLPUBLIC void  InitDrawLayer( SfxObjectShell* pDocShell = nullptr );
 
-    ScInterpreterContext GetNonThreadedContext() const
+    ScInterpreterContext& GetNonThreadedContext() const
     {
         // GetFormatTable() asserts that we are not in a threaded calculation
-        return ScInterpreterContext(*this, GetFormatTable());
+        maInterpreterContext.mpFormatter = GetFormatTable();
+        return maInterpreterContext;
     }
 
     SC_DLLPUBLIC sfx2::LinkManager*       GetLinkManager();
@@ -2063,7 +2066,7 @@ public:
     void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const double* pResults, size_t nLen );
     void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const formula::FormulaConstTokenRef* pResults, size_t nLen );
 
-    ScDocumentThreadSpecific CalculateInColumnInThread( const ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
+    ScDocumentThreadSpecific CalculateInColumnInThread( ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
     void HandleStuffAfterParallelCalculation( const ScAddress& rTopPos, size_t nLen );
 
     /**
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 0185e2629010..e75416de8e56 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -150,7 +150,7 @@ public:
                         SCITP_FROM_ITERATION,
                         SCITP_CLOSE_ITERATION_CIRCLE
                     };
-                    void InterpretTail( const ScInterpreterContext&, ScInterpretTailParameter );
+                    void InterpretTail( ScInterpreterContext&, ScInterpretTailParameter );
 
     void            HandleStuffAfterParallelCalculation();
 
diff --git a/sc/inc/interpretercontext.hxx b/sc/inc/interpretercontext.hxx
index cbf05349ca5f..ff52267dfb26 100644
--- a/sc/inc/interpretercontext.hxx
+++ b/sc/inc/interpretercontext.hxx
@@ -10,6 +10,11 @@
 #ifndef INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
 #define INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
 
+#include <vector>
+#include <formula/token.hxx>
+
+#define TOKEN_CACHE_SIZE 8
+
 class ScDocument;
 class SvNumberFormatter;
 
@@ -17,15 +22,22 @@ struct ScInterpreterContext
 {
     const ScDocument& mrDoc;
     SvNumberFormatter* mpFormatter;
+    size_t mnTokenCachePos;
+    std::vector<formula::FormulaToken*> maTokens;
 
     ScInterpreterContext(const ScDocument& rDoc, SvNumberFormatter* pFormatter) :
         mrDoc(rDoc),
-        mpFormatter(pFormatter)
+        mpFormatter(pFormatter),
+        mnTokenCachePos(0),
+        maTokens(TOKEN_CACHE_SIZE, nullptr)
     {
     }
 
     ~ScInterpreterContext()
     {
+        for ( auto p : maTokens )
+            if ( p )
+                p->DecRef();
     }
 
     SvNumberFormatter* GetFormatTable() const
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 1f77ae4d2e39..3721e2226a5a 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -998,7 +998,7 @@ public:
     void SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen );
     void SetFormulaResults( SCCOL nCol, SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen );
 
-    void CalculateInColumnInThread( const ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
+    void CalculateInColumnInThread( ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
     void HandleStuffAfterParallelCalculation( SCCOL nCol, SCROW nRow, size_t nLen);
 
     /**
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index f436d4b11bea..5b309ca977da 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2877,7 +2877,7 @@ void ScColumn::SetFormulaResults( SCROW nRow, const formula::FormulaConstTokenRe
     }
 }
 
-void ScColumn::CalculateInThread( const ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
+void ScColumn::CalculateInThread( ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
 {
     assert(pDocument->mbThreadedGroupCalcInProgress);
 
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index b15ee591a7e2..9bf0fcf73194 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -177,6 +177,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
         nInterpretLevel(0),
         nMacroInterpretLevel(0),
         nInterpreterTableOpLevel(0),
+        maInterpreterContext( *this, nullptr ),
         nSrcVer( SC_CURRENT_VERSION ),
         nFormulaTrackCount(0),
         eHardRecalcState(HardRecalcState::OFF),
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 8bf1de3fb191..c7be637fb073 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -427,7 +427,7 @@ void ScDocument::SetFormulaResults(
     pTab->SetFormulaResults(rTopPos.Col(), rTopPos.Row(), pResults, nLen);
 }
 
-ScDocumentThreadSpecific ScDocument::CalculateInColumnInThread( const ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
+ScDocumentThreadSpecific ScDocument::CalculateInColumnInThread( ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
 {
     ScTable* pTab = FetchTable(rTopPos.Tab());
     if (!pTab)
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 199996478302..d8f0483f2f54 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1750,7 +1750,7 @@ class StackCleaner
 };
 }
 
-void ScFormulaCell::InterpretTail( const ScInterpreterContext& rContext, ScInterpretTailParameter eTailParam )
+void ScFormulaCell::InterpretTail( ScInterpreterContext& rContext, ScInterpretTailParameter eTailParam )
 {
     RecursionCounter aRecursionCounter( pDocument->GetRecursionHelper(), this);
     nSeenInIteration = pDocument->GetRecursionHelper().GetIteration();
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index e43ab0efc7ac..0b23c7474e91 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2338,7 +2338,7 @@ void ScTable::SetFormulaResults(
     aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
 }
 
-void ScTable::CalculateInColumnInThread( const ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
+void ScTable::CalculateInColumnInThread( ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
 {
     if (!ValidCol(nCol))
         return;
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 2ee692f1bc10..dd84867fa96f 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -97,7 +97,6 @@ class SharedStringPool;
 }
 
 #define MAXSTACK      (4096 / sizeof(formula::FormulaToken*))
-#define TOKEN_CACHE_SIZE 8
 
 class ScTokenStack
 {
@@ -200,7 +199,7 @@ private:
     formula::FormulaTokenIterator aCode;
     ScAddress   aPos;
     ScTokenArray& rArr;
-    const ScInterpreterContext& mrContext;
+    ScInterpreterContext& mrContext;
     ScDocument* pDok;
     sfx2::LinkManager* mpLinkManager;
     svl::SharedStringPool& mrStrPool;
@@ -230,8 +229,6 @@ private:
     bool        bMatrixFormula;         // formula cell is a matrix formula
 
     VolatileType meVolatileType;
-    size_t       mnTokenCachePos;
-    std::vector<formula::FormulaToken*> maTokenCache;
 
     /// Merge global and document specific settings.
     void MergeCalcConfig();
@@ -994,7 +991,7 @@ private:
     double GetTInv( double fAlpha, double fSize, int nType );
 
 public:
-    ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, const ScInterpreterContext& rContext,
+    ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, ScInterpreterContext& rContext,
                     const ScAddress&, ScTokenArray& );
     ~ScInterpreter();
 
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 326392f6099e..3acc38d68051 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -155,6 +155,7 @@ public:
                             ScAddress aBatchTopPos,
                             const ScAddress& rTopPos,
                             ScDocument& rDoc,
+                            SvNumberFormatter* pFormatter,
                             std::vector<formula::FormulaConstTokenRef>& rRes,
                             SCROW nIndex,
                             SCROW nLastIndex) :
@@ -162,6 +163,7 @@ public:
         maBatchTopPos(aBatchTopPos),
         mrTopPos(rTopPos),
         mrDoc(rDoc),
+        mpFormatter(pFormatter),
         mrResults(rRes),
         mnIdx(nIndex),
         mnLastIdx(nLastIndex)
@@ -296,7 +298,8 @@ public:
 
             ScCompiler aComp(&mrDoc, maBatchTopPos, aCode2);
             aComp.CompileTokenArray();
-            ScInterpreter aInterpreter(pDest, &mrDoc, mrDoc.GetNonThreadedContext(), maBatchTopPos, aCode2);
+            ScInterpreterContext aContext(mrDoc, mpFormatter);
+            ScInterpreter aInterpreter(pDest, &mrDoc, aContext, maBatchTopPos, aCode2);
             aInterpreter.Interpret();
             mrResults[i] = aInterpreter.GetResultToken();
         } // Row iteration for loop end
@@ -307,6 +310,7 @@ private:
     ScAddress maBatchTopPos;
     const ScAddress& mrTopPos;
     ScDocument& mrDoc;
+    SvNumberFormatter* mpFormatter;
     std::vector<formula::FormulaConstTokenRef>& mrResults;
     SCROW mnIdx;
     SCROW mnLastIdx;
@@ -333,11 +337,12 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
                  ScAddress aBatchTopPos,
                  const ScAddress& rTopPos2,
                  ScDocument& rDoc2,
+                 SvNumberFormatter* pFormatter2,
                  std::vector<formula::FormulaConstTokenRef>& rRes,
                  SCROW nIndex,
                  SCROW nLastIndex) :
             comphelper::ThreadTask(rTag),
-            maSWIFunc(rCode2, aBatchTopPos, rTopPos2, rDoc2, rRes, nIndex, nLastIndex)
+            maSWIFunc(rCode2, aBatchTopPos, rTopPos2, rDoc2, pFormatter2, rRes, nIndex, nLastIndex)
         {
         }
         virtual void doWork() override
@@ -353,6 +358,8 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
 
     bool bUseThreading = !bThreadingProhibited && officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get();
 
+    SvNumberFormatter* pFormatter = rDoc.GetNonThreadedContext().GetFormatTable();
+
     if (bUseThreading)
     {
         comphelper::ThreadPool& rThreadPool(comphelper::ThreadPool::getSharedOptimalPool());
@@ -381,7 +388,7 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
             if ( nRemaining )
                 --nRemaining;
             SCROW nLast = nStart + nCount - 1;
-            rThreadPool.pushTask(new Executor(aTag, rCode, aTmpPos, rTopPos, rDoc, aResults, nStart, nLast));
+            rThreadPool.pushTask(new Executor(aTag, rCode, aTmpPos, rTopPos, rDoc, pFormatter, aResults, nStart, nLast));
             aTmpPos.IncRow(nCount);
             nLeft -= nCount;
             nStart = nLast + 1;
@@ -392,7 +399,7 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
     }
     else
     {
-        SoftwareInterpreterFunc aSWIFunc(rCode, aTmpPos, rTopPos, rDoc, aResults, 0, xGroup->mnLength - 1);
+        SoftwareInterpreterFunc aSWIFunc(rCode, aTmpPos, rTopPos, rDoc, pFormatter, aResults, 0, xGroup->mnLength - 1);
         aSWIFunc();
     }
 
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 68ec8df0bcb8..5ff2e5826f4a 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1730,15 +1730,13 @@ void ScInterpreter::QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr
 
 formula::FormulaToken* ScInterpreter::CreateFormulaDoubleToken( double fVal, short nFmt )
 {
-    if ( maTokenCache.size() != TOKEN_CACHE_SIZE )
-        maTokenCache.resize( TOKEN_CACHE_SIZE );
+    assert( mrContext.maTokens.size() == TOKEN_CACHE_SIZE );
 
     // Find a spare token
-    for ( auto p : maTokenCache )
+    for ( auto p : mrContext.maTokens )
     {
         if (p && p->GetRef() == 1)
         {
-            p->IncRef();
             p->GetDoubleAsReference() = fVal;
             p->SetDoubleType( nFmt );
             return p;
@@ -1747,12 +1745,11 @@ formula::FormulaToken* ScInterpreter::CreateFormulaDoubleToken( double fVal, sho
 
     // Allocate a new token
     auto p = new FormulaTypedDoubleToken( fVal, nFmt );
-    size_t pos = (mnTokenCachePos++) % TOKEN_CACHE_SIZE;
-    if ( maTokenCache[pos] )
-        maTokenCache[pos]->DecRef();
-    maTokenCache[pos] = p;
+    if ( mrContext.maTokens[mrContext.mnTokenCachePos] )
+        mrContext.maTokens[mrContext.mnTokenCachePos]->DecRef();
+    mrContext.maTokens[mrContext.mnTokenCachePos] = p;
     p->IncRef();
-
+    mrContext.mnTokenCachePos = (mrContext.mnTokenCachePos + 1) % TOKEN_CACHE_SIZE;
     return p;
 }
 
@@ -3810,7 +3807,7 @@ void ScInterpreter::ScTTT()
     PushError(FormulaError::NoValue);
 }
 
-ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, const ScInterpreterContext& rContext,
+ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, ScInterpreterContext& rContext,
         const ScAddress& rPos, ScTokenArray& r )
     : aCode(r)
     , aPos(rPos)
@@ -3870,11 +3867,6 @@ ScInterpreter::~ScInterpreter()
     else
         delete pStackObj;
     delete pTokenMatrixMap;
-
-    for ( auto p : maTokenCache )
-        if ( p && p->GetRef() == 1 )
-            p->DecRef();
-
 }
 
 ScCalcConfig& ScInterpreter::GetOrCreateGlobalConfig()


More information about the Libreoffice-commits mailing list