[Libreoffice-commits] core.git: Branch 'feature/calc-parallel' - 1151 commits - accessibility/inc accessibility/source android/source apple_remote/source avmedia/inc avmedia/Library_avmedia.mk avmedia/Library_avmediaogl.mk avmedia/Library_avmediavlc.mk avmedia/Module_avmedia.mk avmedia/source basctl/source basctl/uiconfig basegfx/source basegfx/test basic/qa basic/source bean/native binaryurp/source bin/gbuild-to-ide bin/gbuild-to-ideNS bin/lo-all-static-libs bridges/inc bridges/Library_cpp_uno.mk bridges/source canvas/source chart2/inc chart2/qa chart2/source chart2/uiconfig codemaker/source comphelper/qa comphelper/source compilerplugins/clang config_host/config_features.h.in config_host/config_global.h.in config_host/config_gpgme.h.in config_host/config_lgpl.h.in config_host.mk.in configmgr/source configure.ac connectivity/qa connectivity/source cppcanvas/Library_cppcanvas.mk cppcanvas/source cppuhelper/source cppu/qa cppu/source cpputools/source cui/inc cui/source cui/uiconfig dbaccess/inc db access/source dbaccess/uiconfig desktop/inc desktop/qa desktop/source desktop/win32 dictionaries distro-configs/LibreOfficeFlatpak.conf distro-configs/LibreOfficeiOS.conf distro-configs/LibreOfficeOssFuzz.conf download.lst drawinglayer/inc drawinglayer/source dtrans/source editeng/CppunitTest_editeng_core.mk editeng/inc editeng/Library_editeng.mk editeng/qa editeng/source embeddedobj/source embedserv/source emfio/inc emfio/source extensions/source extensions/uiconfig external/coinmp external/collada2gltf external/curl external/expat external/firebird external/gpgme external/hyphen external/icu external/lcms2 external/libabw external/libassuan external/libcdr external/libebook external/libepubgen external/libetonyek external/libexttextcat external/libfreehand external/libgltf external/libgpg-error external/libjpeg-turbo external/liblangtag external/libmspub external/libmwaw external/libodfgen external/liborcus external/libpagemaker external/libqxp external/librevenge external/libstar office external/libvisio external/libwpd external/libwpg external/libwps external/libxml2 external/libxslt external/libzmf external/Module_external.mk external/nss external/opencollada external/pdfium external/redland extras/Package_tplpresnt.mk extras/source filter/qa filter/source filter/uiconfig forms/source formula/inc formula/source formula/uiconfig fpicker/source framework/inc framework/qa framework/source .git-hooks/pre-commit helpcompiler/inc helpcompiler/source helpcontent2 hwpfilter/source i18nlangtag/source i18npool/inc i18npool/source i18npool/util i18nutil/source icon-themes/breeze icon-themes/breeze_dark icon-themes/breeze_svg icon-themes/galaxy icon-themes/sifr icon-themes/sifr_dark icon-themes/sifr_svg icon-themes/tango idlc/inc idlc/source idl/inc idl/source include/avmedia include/basegfx include/basic include/codemaker include/com include/comphelper include/cppcanvas include/cppu include/cppuhelper include/editeng include/filter include/formula include/i18nlangtag include/i18nutil include/jvmaccess include/jvmfwk include/LibreOfficeKit include/o3tl include/oox include/osl include/registry include/rtl include/sal include/salhelper include/sax include/sfx2 include/svl include/svtools include/svx include/systools include/test include/toolkit include/tools include/typelib include/ucbhelper include/uno include/unotools include/vbahelper include/vcl include/xmloff include/xmlreader io/qa ios/CustomTarget_iOS.mk ios/.gitignore ios/LibreOfficeKit ios/LibreOfficeLight ios/loApp.xcconfig.in ios/loKit.xcconfig.in io/source javaunohelper/source jurt/source jvmaccess/source jvmfwk/inc jvmfwk/plugins jvmfwk/source l10ntools/inc l10ntools/source libreofficekit/Module_libreofficekit.mk libreofficekit/qa libreofficekit/source lingucomponent/Library_hyphen.mk lingucomponent/Library_lnth.mk lingucomponent/Library_MacOSXSpell.mk lingucomponent/Library_spell.mk lingucomponent/source linguistic/source lotuswordpro/inc lotuswordpro/Library_lwpft.mk lotuswordpro/so urce Makefile.fetch Makefile.in mysqlc/source o3tl/CppunitTest_o3tl_tests.mk o3tl/qa odk/examples odk/qa odk/source offapi/com offapi/UnoApi_offapi.mk officecfg/qa officecfg/registry onlineupdate/inc oox/inc oox/qa oox/source opencl/source package/inc package/source postprocess/Rdb_services.mk pyuno/source pyuno/zipcore qadevOOo/Jar_OOoRunner.mk qadevOOo/objdsc qadevOOo/runner qadevOOo/tests readlicense_oo/license README.md registry/source registry/tools remotebridges/source reportdesign/source reportdesign/uiconfig RepositoryExternal.mk Repository.mk sal/cppunittester salhelper/qa salhelper/source sal/osl sal/qa sal/rtl sal/textenc sax/inc sax/qa sax/source scaddins/source sccomp/source sc/CppunitTest_sc_arealinksobj.mk sc/CppunitTest_sc_cellrangesobj.mk sc/CppunitTest_sc_databaserangeobj.mk sc/CppunitTest_sc_datapilottableobj.mk sc/CppunitTest_sc_filterdescriptorbaseobj.mk sc/CppunitTest_sc_namedrangeobj.mk sc/CppunitTest_sc_namedrangesobj.mk sc/CppunitTest_sc_subtotaldescriptorba seobj.mk sc/CppunitTest_sc_subtotalfieldobj.mk sc/CppunitTest_sc_tablesheetobj.mk sc/inc sc/Module_sc.mk scp2/source sc/qa sc/README sc/res scripting/source sc/sdi sc/source sc/uiconfig sc/UIConfig_scalc.mk sdext/source sd/inc sd/Library_sdfilt.mk sd/qa sd/sdi sd/source sd/uiconfig setup_native/source sfx2/classification sfx2/CppunitTest_sfx2_misc.mk sfx2/Module_sfx2.mk sfx2/qa sfx2/sdi sfx2/source sfx2/uiconfig shell/inc shell/qa shell/source slideshow/source smoketest/smoketest.cxx smoketest/smoketest_too.cxx solenv/bin solenv/clang-cl solenv/CompilerTest_compilerplugins_clang.mk solenv/flatpak-manifest.in solenv/gbuild soltools/cpp sot/source starmath/inc starmath/qa starmath/source stoc/source store/source svgio/inc svgio/source svl/qa svl/source svtools/inc svtools/qa svtools/source svx/inc svx/sdi svx/source svx/uiconfig sw/CppunitTest_sw_ooxmlexport10.mk sw/CppunitTest_sw_ooxmlexport11.mk sw/CppunitTest_sw_uiwriter.mk sw/inc sw/Module_sw.mk sw/qa sw/sdi sw/source sw/uiconfig sw/UIConfig_swriter.mk test/Library_subsequenttest.mk test/source testtools/source toolkit/inc toolkit/source tools/qa tools/source translations ucbhelper/source ucb/qa ucb/source udkapi/com uitest/writer_tests UnoControls/inc UnoControls/source unodevtools/inc unodevtools/source unoidl/source unotest/source unotools/qa unotools/source unoxml/inc unoxml/source uui/source vbahelper/source vcl/backendtest vcl/CustomTarget_kde5_moc.mk vcl/Executable_602fuzzer.mk vcl/Executable_bmpfuzzer.mk vcl/Executable_cgmfuzzer.mk vcl/Executable_dxffuzzer.mk vcl/Executable_epsfuzzer.mk vcl/Executable_giffuzzer.mk vcl/Executable_hwpfuzzer.mk vcl/Executable_jpgfuzzer.mk vcl/Executable_lwpfuzzer.mk vcl/Executable_metfuzzer.mk vcl/Executable_olefuzzer.mk vcl/Executable_pcdfuzzer.mk vcl/Executable_pctfuzzer.mk vcl/Executable_pcxfuzzer.mk vcl/Executable_pngfuzzer.mk vcl/Executable_ppmfuzzer.mk vcl/Executable_pptfuzzer.mk vcl/Executable_psdfuzzer.mk vcl/Executable_qpwfuzzer.mk vcl/Executable_rasfuzzer.mk v cl/Executable_rtffuzzer.mk vcl/Executable_slkfuzzer.mk vcl/Executable_svmfuzzer.mk vcl/Executable_tgafuzzer.mk vcl/Executable_tiffuzzer.mk vcl/Executable_wmffuzzer.mk vcl/Executable_ww2fuzzer.mk vcl/Executable_ww6fuzzer.mk vcl/Executable_ww8fuzzer.mk vcl/Executable_xbmfuzzer.mk vcl/Executable_xpmfuzzer.mk vcl/headless vcl/inc vcl/ios vcl/Library_vcl.mk vcl/Library_vclplug_kde5.mk vcl/Module_vcl.mk vcl/opengl vcl/osx vcl/qa vcl/quartz vcl/README.scheduler vcl/source vcl/uiconfig vcl/unx vcl/win vcl/workben winaccessibility/inc winaccessibility/source wizards/source writerfilter/source writerperfect/inc writerperfect/qa writerperfect/source xmlhelp/source xmloff/inc xmloff/qa xmloff/source xmlscript/source xmlsecurity/inc xmlsecurity/source xmlsecurity/uiconfig
Tor Lillqvist
tml at collabora.com
Tue Oct 31 10:33:18 UTC 2017
Rebased ref, commits from common ancestor:
commit a0e25475cee4cce0dbd082d1c893bd711d7a9962
Author: Tor Lillqvist <tml at collabora.com>
Date: Mon Oct 16 18:40:51 2017 +0300
Add OFFSET to blacklist for threaded calculation
Change-Id: Ia1aaf40aa4e8e6f41ca190272365528bf37bf130
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index db28d42ebcf3..43f0825b3f1e 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1341,6 +1341,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
static const std::set<OpCode> aThreadedCalcBlackList({
ocIndirect,
ocMacro,
+ ocOffset,
ocTableOp
});
commit babc1820b780689b41097a9dc0346f0c1288bf90
Author: Tor Lillqvist <tml at collabora.com>
Date: Mon Oct 16 18:31:07 2017 +0300
Add INDIRECT to blacklist for threaded calculation
Change-Id: I9a2066c396802551c3eda2c8db32b6d1a4171dfd
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index fe007d680b30..db28d42ebcf3 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1339,6 +1339,7 @@ bool ScTokenArray::AddFormulaToken(
void ScTokenArray::CheckToken( const FormulaToken& r )
{
static const std::set<OpCode> aThreadedCalcBlackList({
+ ocIndirect,
ocMacro,
ocTableOp
});
commit 6c74f5ad2696446261a7b902c284c95fa6ad1949
Author: Tor Lillqvist <tml at collabora.com>
Date: Mon Oct 16 18:28:24 2017 +0300
Check whether ScTokenArray::CheckToken() has disabled threading of the group
Otherwise the aThreadedCalcBlackList check in CheckToken() has no
effect, we would still attempt the threaded code path.
Change-Id: I08dc2dd174459615ab8a11dbb819e39fc5437d10
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 002d72dbad88..61b0f5a87702 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -4345,7 +4345,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
return false;
}
- if (!bThreadingProhibited && !ScCalcConfig::isOpenCLEnabled() && officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get())
+ if (!bThreadingProhibited && !ScCalcConfig::isOpenCLEnabled() && pCode->GetVectorState() != FormulaVectorDisabledNotInSubSet && officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get())
{
// iterate over code in the formula ...
// ensure all input is pre-calculated -
commit 9e7bf2c755ee3cb01572d36141d6ea7cc6dc18ab
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Oct 4 22:55:19 2017 +0300
Avoid unused private field warning in the NDEBUG case
Change-Id: I5e37b9a8325af35a15c01409f9eaa2f92459cc28
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 73f450dc8163..a53258a2fb70 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6747,6 +6747,7 @@ ScMutationGuard::ScMutationGuard(ScDocument* pDocument, ScMutationGuardFlags nFl
mpDocument(pDocument),
mnFlags(nFlags)
{
+ (void) mpDocument;
for (unsigned b = 0; b < static_cast<std::size_t>(ScMutationGuardFlags::N); b++)
{
if (static_cast<std::size_t>(mnFlags) & (1 << b))
commit 6442b4ccb2b7845918d99eebfaf786a2665fc04c
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Oct 4 16:55:59 2017 +0300
Move ScDocument::GetNonThreadedContext() inline
Did not have any impact on performance, though.
Change-Id: I7e769b4a74e0ff9e0aabfb7e291fc4b987441954
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index c86d48b6c3cf..04544fe5a64e 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -564,7 +564,11 @@ public:
SC_DLLPUBLIC void InitDrawLayer( SfxObjectShell* pDocShell = nullptr );
- SC_DLLPUBLIC ScInterpreterContext GetNonThreadedContext() const;
+ ScInterpreterContext GetNonThreadedContext() const
+ {
+ // GetFormatTable() asserts that we are not in a threaded calculation
+ return ScInterpreterContext(*this, GetFormatTable());
+ }
SC_DLLPUBLIC sfx2::LinkManager* GetLinkManager();
SC_DLLPUBLIC const sfx2::LinkManager* GetLinkManager() const;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 0df71931c355..73f450dc8163 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6769,13 +6769,6 @@ ScMutationGuard::~ScMutationGuard()
#endif
}
-ScInterpreterContext ScDocument::GetNonThreadedContext() const
-{
- // GetFormatTable() asserts that we are not in a threaded calculation
- ScInterpreterContext aResult(*this, GetFormatTable());
- return aResult;
-}
-
thread_local ScDocumentThreadSpecific ScDocument::maThreadSpecific;
ScRecursionHelper& ScDocument::GetRecursionHelper()
commit 4cfe1747eb16f62fda4150efe27a7a522e726216
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Oct 4 13:11:10 2017 +0300
Display the threaded calculation state in Help:About
Change-Id: I299e555392bb4b09325ad2c92f843b1e12ee4d31
diff --git a/cui/source/dialogs/about.cxx b/cui/source/dialogs/about.cxx
index a7d219407249..c9ba680c8609 100644
--- a/cui/source/dialogs/about.cxx
+++ b/cui/source/dialogs/about.cxx
@@ -53,6 +53,7 @@
#include <opencl/openclwrapper.hxx>
#endif
#include <officecfg/Office/Common.hxx>
+#include <officecfg/Office/Calc.hxx>
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
@@ -334,19 +335,31 @@ OUString AboutDialog::GetVersionString()
sVersion += m_aLocaleStr.replaceAll("$LOCALE", aLocaleStr);
}
-#if HAVE_FEATURE_OPENCL
OUString aCalcMode = "Calc: "; // Calc calculation mode
+
+#if HAVE_FEATURE_OPENCL
bool bSWInterp = officecfg::Office::Common::Misc::UseSwInterpreter::get();
bool bOpenCL = openclwrapper::GPUEnv::isOpenCLEnabled();
if (bOpenCL)
aCalcMode += "CL";
else if (bSWInterp)
aCalcMode += "group";
- else
- aCalcMode += "single";
- sVersion += "; " + aCalcMode;
+#else
+ const bool bOpenCL = false;
#endif
+ static const bool bThreadingProhibited = std::getenv("SC_NO_THREADED_CALCULATION");
+ bool bThreadedCalc = officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get();
+
+ if (!bThreadingProhibited && !bOpenCL && bThreadedCalc)
+ {
+ if (!aCalcMode.endsWith(" "))
+ aCalcMode += " ";
+ aCalcMode += "threaded";
+ }
+
+ sVersion += "; " + aCalcMode;
+
return sVersion;
}
commit f72a7976662e8851ccff18c05e8d207dfae0ca4b
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Oct 4 12:40:20 2017 +0300
Make threaded calculation the default (when OpenCL is not used)
Introduce a configuration setting to turn it off. For now, can also be
turned off with the environment variable SC_NO_THREADED_CALCULATION,
but that is probably not something we want to keep or guarantee
staility of. (LO looks at way too many environment variables already.)
Change-Id: I469cde259eda72cc2d630814a25f707f1210b0ab
diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
index b1feca1825c6..72ac33b99413 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
@@ -1416,6 +1416,12 @@
<info>
<desc>Contains settings for how to calculate formulae.</desc>
</info>
+ <prop oor:name="UseThreadedCalculationForFormulaGroups" oor:type="xs:boolean" oor:nillable="false">
+ <info>
+ <desc>Whether to use threaded calculation of forumula groups when applicable.</desc>
+ </info>
+ <value>true</value>
+ </prop>
<!-- Note: The default values below probably must correspond
to those assigned in setOpenCLConfigToDefault() in
sc/source/core/tool/calcconfig.cxx
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 2d6d49bc191a..002d72dbad88 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -54,6 +54,7 @@
#include <svl/intitem.hxx>
#include <o3tl/make_unique.hxx>
#include <rtl/strbuf.hxx>
+#include <officecfg/Office/Calc.hxx>
#include <formulagroup.hxx>
#include <listenercontext.hxx>
#include <types.hxx>
@@ -4326,11 +4327,10 @@ bool ScFormulaCell::InterpretFormulaGroup()
return false;
}
- static const bool bThreadingRequested = std::getenv("CPU_THREADED_CALCULATION");
+ static const bool bThreadingProhibited = std::getenv("SC_NO_THREADED_CALCULATION");
// To temporarilu use threading for sc unit tests regardless of the size of the formula group,
- // add the condition !std::getenv("LO_TESTNAME") below (with &&), and run with
- // CPU_THREADED_CALCULATION=yes
+ // add the condition !std::getenv("LO_TESTNAME") below (with &&)
if (GetWeight() < ScInterpreter::GetGlobalConfig().mnOpenCLMinimumFormulaGroupSize)
{
mxGroup->meCalcState = sc::GroupCalcDisabled;
@@ -4345,7 +4345,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
return false;
}
- if (!ScCalcConfig::isOpenCLEnabled() && bThreadingRequested)
+ if (!bThreadingProhibited && !ScCalcConfig::isOpenCLEnabled() && officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get())
{
// iterate over code in the formula ...
// ensure all input is pre-calculated -
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index d0ebe0ca2e76..fe007d680b30 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -25,6 +25,7 @@
#include <tools/mempool.hxx>
#include <osl/diagnose.h>
#include <sfx2/docfile.hxx>
+#include <officecfg/Office/Calc.hxx>
#include <token.hxx>
#include <tokenarray.hxx>
@@ -1346,11 +1347,11 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
// It's already disabled. No more checking needed.
return;
- static const bool bThreadingRequested = std::getenv("CPU_THREADED_CALCULATION");
+ static const bool bThreadingProhibited = std::getenv("SC_NO_THREADED_CALCULATION");
OpCode eOp = r.GetOpCode();
- if (!ScCalcConfig::isOpenCLEnabled() && bThreadingRequested)
+ if (!bThreadingProhibited && !ScCalcConfig::isOpenCLEnabled() && officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get())
{
if (aThreadedCalcBlackList.count(eOp))
{
commit 9b01b676860e421d2b7438f33439e80597943d0a
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Oct 4 10:55:13 2017 +0300
Need more ScInterpreterContexts
Change-Id: I1dd679156661bb5cb025ca6cb46d19783524d5a4
diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx
index 0f513c231327..00f399fab47c 100644
--- a/sc/source/core/tool/interpr6.cxx
+++ b/sc/source/core/tool/interpr6.cxx
@@ -846,7 +846,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
nFuncFmtIndex = aAction.getNumberFormat();
}
- nFuncFmtType = pDok->GetFormatTable()->GetType( nFuncFmtIndex );
+ nFuncFmtType = mrContext.GetFormatTable()->GetType( nFuncFmtIndex );
}
else
{
commit cc12cf3a86e04e4bffecd0209db2dfb8530e0d4e
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Oct 4 08:48:05 2017 +0300
-Werror,-Wunused-parameter
Change-Id: If10c6a58f5b6f196f3644f6c592dd6d1dc0d860c
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 62f4baa471c3..0df71931c355 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6794,13 +6794,13 @@ ScRecursionHelper& ScDocument::GetRecursionHelper()
}
}
-void ScDocumentThreadSpecific::SetupFromNonThreadedData(const ScDocumentThreadSpecific& rNonThreadedData)
+void ScDocumentThreadSpecific::SetupFromNonThreadedData(const ScDocumentThreadSpecific& /*rNonThreadedData*/)
{
// What about the recursion helper?
// Copy the lookup cache?
}
-void ScDocumentThreadSpecific::MergeBackIntoNonThreadedData(ScDocumentThreadSpecific& rNonThreadedData)
+void ScDocumentThreadSpecific::MergeBackIntoNonThreadedData(ScDocumentThreadSpecific& /*rNonThreadedData*/)
{
// What about recursion helper and lookup cache?
}
commit 93030470bbf89cff4156435b849198fe5973f459
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Oct 4 08:47:02 2017 +0300
-Werror,-Wsign-compare
Change-Id: Ide03e0ae1fe97e1a09a767908a981a1e803a3474
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index f15107bc3fe7..62f4baa471c3 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6747,7 +6747,7 @@ ScMutationGuard::ScMutationGuard(ScDocument* pDocument, ScMutationGuardFlags nFl
mpDocument(pDocument),
mnFlags(nFlags)
{
- for (auto b = 0; b < static_cast<std::size_t>(ScMutationGuardFlags::N); b++)
+ for (unsigned b = 0; b < static_cast<std::size_t>(ScMutationGuardFlags::N); b++)
{
if (static_cast<std::size_t>(mnFlags) & (1 << b))
{
@@ -6759,7 +6759,7 @@ ScMutationGuard::ScMutationGuard(ScDocument* pDocument, ScMutationGuardFlags nFl
ScMutationGuard::~ScMutationGuard()
{
#ifndef NDEBUG
- for (auto b = 0; b < static_cast<std::size_t>(ScMutationGuardFlags::N); b++)
+ for (unsigned b = 0; b < static_cast<std::size_t>(ScMutationGuardFlags::N); b++)
{
if (static_cast<std::size_t>(mnFlags) & (1 << b))
{
commit f66c6fab8791d52b97337570510bca415feaa961
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Oct 4 00:12:31 2017 +0300
Introduce ScInterpreterContext
When calculating a formula group in multiple threads in parallel, we
need to use separate SvNumberFormatters in the threads. Possibly later
also other things that need to be thread-local can be handled through
the ScInterpreterContext.
Why handle some thread-local things through the
ScDocument::maNonThreaded and ScDocument::maThreadSpecific mechanism,
and others through this ScInterpreterContext? Good question.
Change-Id: I372e5fbd9a19785f55f0faf4a4bedc5fc1ef3e03
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 67bc6c348c5e..44bee716bf18 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -106,6 +106,7 @@ class ScDocumentImport;
class ScHint;
enum class ScMF;
struct ScFilterEntries;
+struct ScInterpreterContext;
struct ScNeededSizeOptions
{
@@ -447,7 +448,7 @@ public:
const ScPatternAttr* GetPattern( SCROW nRow ) const;
const ScPatternAttr* GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const;
- sal_uInt32 GetNumberFormat( SCROW nRow ) const;
+ sal_uInt32 GetNumberFormat( const ScInterpreterContext& rContext, SCROW nRow ) const;
sal_uInt32 GetNumberFormat( SCROW nStartRow, SCROW nEndRow ) const;
void MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, bool bDeep ) const;
@@ -582,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( SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
+ void CalculateInThread( const 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/dociter.hxx b/sc/inc/dociter.hxx
index 544e64ebc9c1..904f471c3c4f 100644
--- a/sc/inc/dociter.hxx
+++ b/sc/inc/dociter.hxx
@@ -45,6 +45,7 @@ struct ScQueryParam;
struct ScDBQueryParamInternal;
struct ScDBQueryParamMatrix;
class ScFormulaCell;
+struct ScInterpreterContext;
class ScValueIterator // walk through all values in an area
{
@@ -84,7 +85,7 @@ public:
ScDocument* pDocument, const ScRange& rRange, SubtotalFlags nSubTotalFlags = SubtotalFlags::NONE,
bool bTextAsZero = false );
- void GetCurNumFmtInfo( short& nType, sal_uLong& nIndex );
+ void GetCurNumFmtInfo( const ScInterpreterContext& rContext, short& nType, sal_uLong& nIndex );
/// Does NOT reset rValue if no value found!
bool GetFirst( double& rValue, FormulaError& rErr );
@@ -125,7 +126,7 @@ private:
{
typedef std::pair<sc::CellStoreType::const_iterator,size_t> PositionType;
public:
- DataAccessInternal(ScDBQueryParamInternal* pParam, ScDocument* pDoc);
+ DataAccessInternal(ScDBQueryParamInternal* pParam, ScDocument* pDoc, const ScInterpreterContext& rContext);
virtual ~DataAccessInternal() override;
virtual bool getCurrent(Value& rValue) override;
virtual bool getFirst(Value& rValue) override;
@@ -139,6 +140,7 @@ private:
PositionType maCurPos;
ScDBQueryParamInternal* mpParam;
ScDocument* mpDoc;
+ const ScInterpreterContext& mrContext;
const ScAttrArray* pAttrArray;
sal_uLong nNumFormat; // for CalcAsShown
sal_uLong nNumFmtIndex;
@@ -171,7 +173,7 @@ private:
::std::unique_ptr<DataAccess> mpData;
public:
- ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam);
+ ScDBQueryDataIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, ScDBQueryParamBase* pParam);
/// Does NOT reset rValue if no value found!
bool GetFirst(Value& rValue);
/// Does NOT reset rValue if no value found!
@@ -266,6 +268,7 @@ class ScQueryCellIterator // walk through all non-empty cells in an ar
std::unique_ptr<ScQueryParam> mpParam;
ScDocument* pDoc;
+ const ScInterpreterContext& mrContext;
SCTAB nTab;
SCCOL nCol;
SCROW nRow;
@@ -292,7 +295,7 @@ class ScQueryCellIterator // walk through all non-empty cells in an ar
bool BinarySearch();
public:
- ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
+ ScQueryCellIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, SCTAB nTable,
const ScQueryParam& aParam, bool bMod);
// when !bMod, the QueryParam has to be filled
// (bIsString)
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index e85b4ba29365..c86d48b6c3cf 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -26,6 +26,7 @@
#include <com/sun/star/uno/Reference.hxx>
#include <vcl/vclptr.hxx>
#include "scdllapi.h"
+#include "interpretercontext.hxx"
#include "rangelst.hxx"
#include "rangenam.hxx"
#include "tabopparams.hxx"
@@ -563,6 +564,8 @@ public:
SC_DLLPUBLIC void InitDrawLayer( SfxObjectShell* pDocShell = nullptr );
+ SC_DLLPUBLIC ScInterpreterContext GetNonThreadedContext() const;
+
SC_DLLPUBLIC sfx2::LinkManager* GetLinkManager();
SC_DLLPUBLIC const sfx2::LinkManager* GetLinkManager() const;
@@ -1118,10 +1121,10 @@ public:
SC_DLLPUBLIC void GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab,
sal_uInt32& rFormat ) const;
sal_uInt32 GetNumberFormat( const ScRange& rRange ) const;
- SC_DLLPUBLIC sal_uInt32 GetNumberFormat( const ScAddress& ) const;
+ SC_DLLPUBLIC sal_uInt32 GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& ) const;
void SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberFormat );
- void GetNumberFormatInfo( short& nType, sal_uLong& nIndex, const ScAddress& rPos ) const;
+ void GetNumberFormatInfo( const ScInterpreterContext& rContext, short& nType, sal_uLong& nIndex, const ScAddress& rPos ) const;
SC_DLLPUBLIC const ScFormulaCell* GetFormulaCell( const ScAddress& rPos ) const;
SC_DLLPUBLIC ScFormulaCell* GetFormulaCell( const ScAddress& rPos );
SC_DLLPUBLIC void GetFormula( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rFormula ) const;
@@ -2056,7 +2059,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 ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
+ ScDocumentThreadSpecific CalculateInColumnInThread( const 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 40fe21598e28..0185e2629010 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -30,7 +30,7 @@
#include <svl/listener.hxx>
#include "types.hxx"
-
+#include "interpretercontext.hxx"
#include "formularesult.hxx"
namespace sc {
@@ -150,7 +150,7 @@ public:
SCITP_FROM_ITERATION,
SCITP_CLOSE_ITERATION_CIRCLE
};
- void InterpretTail( ScInterpretTailParameter );
+ void InterpretTail( const ScInterpreterContext&, ScInterpretTailParameter );
void HandleStuffAfterParallelCalculation();
diff --git a/sc/inc/interpretercontext.hxx b/sc/inc/interpretercontext.hxx
new file mode 100644
index 000000000000..cbf05349ca5f
--- /dev/null
+++ b/sc/inc/interpretercontext.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
+#define INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
+
+class ScDocument;
+class SvNumberFormatter;
+
+struct ScInterpreterContext
+{
+ const ScDocument& mrDoc;
+ SvNumberFormatter* mpFormatter;
+
+ ScInterpreterContext(const ScDocument& rDoc, SvNumberFormatter* pFormatter) :
+ mrDoc(rDoc),
+ mpFormatter(pFormatter)
+ {
+ }
+
+ ~ScInterpreterContext()
+ {
+ }
+
+ SvNumberFormatter* GetFormatTable() const
+ {
+ return mpFormatter;
+ }
+};
+
+#endif // INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 9b04a4d019a4..1f77ae4d2e39 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -116,6 +116,7 @@ class ScRangeName;
class ScDBData;
class ScDocumentImport;
class ScHint;
+struct ScInterpreterContext;
class ScColumnsRange final
{
@@ -672,7 +673,7 @@ public:
const ScPatternAttr* GetPattern( SCCOL nCol, SCROW nRow ) const;
const ScPatternAttr* GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const;
- sal_uInt32 GetNumberFormat( const ScAddress& rPos ) const;
+ sal_uInt32 GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& rPos ) const;
sal_uInt32 GetNumberFormat( SCCOL nCol, SCROW nRow ) const;
sal_uInt32 GetNumberFormat( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const;
@@ -997,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( SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
+ void CalculateInColumnInThread( const 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/column.cxx b/sc/source/core/data/column.cxx
index 48a551462c60..11bd7010ce32 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -418,9 +418,9 @@ sal_uInt32 ScColumn::GetNumberFormat( SCROW nStartRow, SCROW nEndRow ) const
return nFormat;
}
-sal_uInt32 ScColumn::GetNumberFormat( SCROW nRow ) const
+sal_uInt32 ScColumn::GetNumberFormat( const ScInterpreterContext& rContext, SCROW nRow ) const
{
- return pAttrArray->GetPattern( nRow )->GetNumberFormat( pDocument->GetFormatTable() );
+ return pAttrArray->GetPattern( nRow )->GetNumberFormat( rContext.GetFormatTable() );
}
SCROW ScColumn::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged )
@@ -1151,7 +1151,7 @@ void ScColumn::CopyStaticToDocument(
// Dont' forget to copy the number formats over. Charts may reference them.
for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
{
- sal_uInt32 nNumFmt = GetNumberFormat(nRow);
+ sal_uInt32 nNumFmt = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
SvNumberFormatterMergeMap::const_iterator itNum = rMap.find(nNumFmt);
if (itNum != rMap.end())
nNumFmt = itNum->second;
@@ -2887,7 +2887,7 @@ public:
void operator() (size_t nRow, ScFormulaCell* pCell)
{
- sal_uInt32 nFormat = mrCol.GetNumberFormat(nRow);
+ sal_uInt32 nFormat = mrCol.GetNumberFormat(mrCol.GetDoc().GetNonThreadedContext(), nRow);
if( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
// Non-default number format is set.
pCell->SetNeedNumberFormat(false);
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 705b5ed83ae5..f436d4b11bea 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2877,8 +2877,10 @@ void ScColumn::SetFormulaResults( SCROW nRow, const formula::FormulaConstTokenRe
}
}
-void ScColumn::CalculateInThread( SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
+void ScColumn::CalculateInThread( const ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
{
+ assert(pDocument->mbThreadedGroupCalcInProgress);
+
sc::CellStoreType::position_type aPos = maCells.position(nRow);
sc::CellStoreType::iterator it = aPos.first;
if (it->type != sc::element_type_formula)
@@ -2901,8 +2903,7 @@ void ScColumn::CalculateInThread( SCROW nRow, size_t nLen, unsigned nThisThread,
ScFormulaCell& rCell = **itCell;
// Here we don't call IncInterpretLevel() and DecInterpretLevel() as this call site is
// always in a threaded calculation.
- assert(pDocument->mbThreadedGroupCalcInProgress);
- rCell.InterpretTail(ScFormulaCell::SCITP_NORMAL);
+ rCell.InterpretTail(rContext, ScFormulaCell::SCITP_NORMAL);
}
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 646210a8e679..9a5a57205436 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1700,7 +1700,7 @@ bool ScColumn::ParseString(
if (!aParam.mpNumFormatter)
aParam.mpNumFormatter = pDocument->GetFormatTable();
- nIndex = nOldIndex = GetNumberFormat( nRow );
+ nIndex = nOldIndex = GetNumberFormat( pDocument->GetNonThreadedContext(), nRow );
if ( rString.getLength() > 1
&& aParam.mpNumFormatter->GetType(nIndex) != css::util::NumberFormat::TEXT )
cFirstChar = rString[0];
@@ -1922,7 +1922,7 @@ void ScColumn::SetFormula( SCROW nRow, const ScTokenArray& rArray, formula::Form
sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, rArray, eGram);
- sal_uInt32 nCellFormat = GetNumberFormat(nRow);
+ sal_uInt32 nCellFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
pCell->SetNeedNumberFormat(true);
it = maCells.set(it, nRow, pCell);
@@ -1939,7 +1939,7 @@ void ScColumn::SetFormula( SCROW nRow, const OUString& rFormula, formula::Formul
sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, rFormula, eGram);
- sal_uInt32 nCellFormat = GetNumberFormat(nRow);
+ sal_uInt32 nCellFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
pCell->SetNeedNumberFormat(true);
it = maCells.set(it, nRow, pCell);
@@ -1954,7 +1954,7 @@ ScFormulaCell* ScColumn::SetFormulaCell(
SCROW nRow, ScFormulaCell* pCell, sc::StartListeningType eListenType )
{
sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
- sal_uInt32 nCellFormat = GetNumberFormat(nRow);
+ sal_uInt32 nCellFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
pCell->SetNeedNumberFormat(true);
it = maCells.set(it, nRow, pCell);
@@ -1971,7 +1971,7 @@ void ScColumn::SetFormulaCell(
sc::StartListeningType eListenType )
{
rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow);
- sal_uInt32 nCellFormat = GetNumberFormat(nRow);
+ sal_uInt32 nCellFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
pCell->SetNeedNumberFormat(true);
rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pCell);
@@ -2002,7 +2002,7 @@ bool ScColumn::SetFormulaCells( SCROW nRow, std::vector<ScFormulaCell*>& rCells
for (size_t i = 0, n = rCells.size(); i < n; ++i)
{
SCROW nThisRow = nRow + i;
- sal_uInt32 nFmt = GetNumberFormat(nThisRow);
+ sal_uInt32 nFmt = GetNumberFormat(pDocument->GetNonThreadedContext(), nThisRow);
if ((nFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
rCells[i]->SetNeedNumberFormat(true);
}
@@ -2055,7 +2055,7 @@ class FilterEntriesHandler
{
SvNumberFormatter* pFormatter = mrColumn.GetDoc().GetFormatTable();
OUString aStr;
- sal_uLong nFormat = mrColumn.GetNumberFormat(nRow);
+ sal_uLong nFormat = mrColumn.GetNumberFormat(mrColumn.GetDoc().GetNonThreadedContext(), nRow);
ScCellFormat::GetInputString(rCell, nFormat, aStr, *pFormatter, &mrColumn.GetDoc());
if (rCell.hasString())
@@ -2543,7 +2543,7 @@ void ScColumn::GetString( SCROW nRow, OUString& rString ) const
if (aCell.meType == CELLTYPE_FORMULA)
aCell.mpFormula->MaybeInterpret();
- sal_uLong nFormat = GetNumberFormat(nRow);
+ sal_uLong nFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
Color* pColor = nullptr;
ScCellFormat::GetString(aCell, nFormat, rString, &pColor, *(pDocument->GetFormatTable()), pDocument);
}
@@ -2564,7 +2564,7 @@ double* ScColumn::GetValueCell( SCROW nRow )
void ScColumn::GetInputString( SCROW nRow, OUString& rString ) const
{
ScRefCellValue aCell = GetCellValue(nRow);
- sal_uLong nFormat = GetNumberFormat(nRow);
+ sal_uLong nFormat = GetNumberFormat(pDocument->GetNonThreadedContext(), nRow);
ScCellFormat::GetInputString(aCell, nFormat, rString, *(pDocument->GetFormatTable()), pDocument);
}
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index 358774153027..fa7f9dfb8c05 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -262,14 +262,14 @@ bool ScValueIterator::GetThis(double& rValue, FormulaError& rErr)
}
}
-void ScValueIterator::GetCurNumFmtInfo( short& nType, sal_uLong& nIndex )
+void ScValueIterator::GetCurNumFmtInfo( const ScInterpreterContext& rContext, short& nType, sal_uLong& nIndex )
{
if (!bNumValid && mnTab < pDoc->GetTableCount())
{
SCROW nCurRow = GetRow();
const ScColumn* pCol = &(pDoc->maTabs[mnTab])->aCol[mnCol];
- nNumFmtIndex = pCol->GetNumberFormat(nCurRow);
- nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
+ nNumFmtIndex = pCol->GetNumberFormat(rContext, nCurRow);
+ nNumFmtType = rContext.GetFormatTable()->GetType( nNumFmtIndex );
bNumValid = true;
}
@@ -334,11 +334,12 @@ bool ScDBQueryDataIterator::IsQueryValid(
return rDoc.maTabs[nTab]->ValidQuery(nRow, rParam, pCell);
}
-ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(ScDBQueryParamInternal* pParam, ScDocument* pDoc)
+ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(ScDBQueryParamInternal* pParam, ScDocument* pDoc, const ScInterpreterContext& rContext)
: DataAccess()
, mpCells(nullptr)
, mpParam(pParam)
, mpDoc(pDoc)
+ , mrContext(rContext)
, pAttrArray(nullptr)
, nNumFormat(0) // Initialized in GetNumberFormat
, nNumFmtIndex(0)
@@ -432,7 +433,7 @@ bool ScDBQueryDataIterator::DataAccessInternal::getCurrent(Value& rValue)
rValue.mfValue = aCell.mpFormula->GetValue();
rValue.mbIsNumber = true;
mpDoc->GetNumberFormatInfo(
- nNumFmtType, nNumFmtIndex, ScAddress(nCol, nRow, nTab));
+ mrContext, nNumFmtType, nNumFmtIndex, ScAddress(nCol, nRow, nTab));
rValue.mnError = aCell.mpFormula->GetErrCode();
return true; // Found it!
}
@@ -744,7 +745,7 @@ ScDBQueryDataIterator::Value::Value() :
::rtl::math::setNan(&mfValue);
}
-ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam) :
+ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, ScDBQueryParamBase* pParam) :
mpParam (pParam)
{
switch (mpParam->GetType())
@@ -752,7 +753,7 @@ ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryPar
case ScDBQueryParamBase::INTERNAL:
{
ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pParam);
- mpData.reset(new DataAccessInternal(p, pDocument));
+ mpData.reset(new DataAccessInternal(p, pDocument, rContext));
}
break;
case ScDBQueryParamBase::MATRIX:
@@ -1046,10 +1047,11 @@ bool ScCellIterator::next()
return getCurrent();
}
-ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
+ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, const ScInterpreterContext& rContext, SCTAB nTable,
const ScQueryParam& rParam, bool bMod ) :
mpParam(new ScQueryParam(rParam)),
pDoc( pDocument ),
+ mrContext( rContext ),
nTab( nTable),
nStopOnMismatch( nStopOnMismatchDisabled ),
nTestEqualCondition( nTestEqualConditionDisabled ),
@@ -1681,7 +1683,7 @@ bool ScQueryCellIterator::BinarySearch()
if (aPos.first->type == sc::element_type_string || aPos.first->type == sc::element_type_edittext)
{
aCell = sc::toRefCell(aPos.first, aPos.second);
- sal_uLong nFormat = pCol->GetNumberFormat(nRow);
+ sal_uLong nFormat = pCol->GetNumberFormat(mrContext, nRow);
OUString aCellStr;
ScCellFormat::GetInputString(aCell, nFormat, aCellStr, rFormatter, pDoc);
sal_Int32 nTmp = pCollator->compareString(aCellStr, rEntry.GetQueryItem().maString.getString());
@@ -1715,7 +1717,7 @@ bool ScQueryCellIterator::BinarySearch()
aCell = aCellData.first;
if (aCell.hasString())
{
- sal_uLong nFormat = pCol->GetNumberFormat(aCellData.second);
+ sal_uLong nFormat = pCol->GetNumberFormat(mrContext, aCellData.second);
OUString aStr;
ScCellFormat::GetInputString(aCell, nFormat, aStr, rFormatter, pDoc);
aLastInRangeString = aStr;
@@ -1814,7 +1816,7 @@ bool ScQueryCellIterator::BinarySearch()
else if (bStr && bByString)
{
OUString aCellStr;
- sal_uLong nFormat = pCol->GetNumberFormat(aCellData.second);
+ sal_uLong nFormat = pCol->GetNumberFormat(mrContext, aCellData.second);
ScCellFormat::GetInputString(aCell, nFormat, aCellStr, rFormatter, pDoc);
nRes = pCollator->compareString(aCellStr, rEntry.GetQueryItem().maString.getString());
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 283c082199b2..b15ee591a7e2 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -502,6 +502,7 @@ void ScDocument::InitClipPtrs( ScDocument* pSourceDoc )
SvNumberFormatter* ScDocument::GetFormatTable() const
{
+ assert(!mbThreadedGroupCalcInProgress);
return mxPoolHelper->GetFormTable();
}
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index b29de4004c90..8bf1de3fb191 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 ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
+ScDocumentThreadSpecific ScDocument::CalculateInColumnInThread( const ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
{
ScTable* pTab = FetchTable(rTopPos.Tab());
if (!pTab)
@@ -436,7 +436,7 @@ ScDocumentThreadSpecific ScDocument::CalculateInColumnInThread( const ScAddress&
assert(mbThreadedGroupCalcInProgress);
maThreadSpecific.SetupFromNonThreadedData(maNonThreaded);
- pTab->CalculateInColumnInThread(rTopPos.Col(), rTopPos.Row(), nLen, nThisThread, nThreadsTotal);
+ pTab->CalculateInColumnInThread(rContext, rTopPos.Col(), rTopPos.Row(), nLen, nThisThread, nThreadsTotal);
assert(mbThreadedGroupCalcInProgress);
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 185115ac8ad7..f15107bc3fe7 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3702,13 +3702,13 @@ sal_uInt32 ScDocument::GetNumberFormat( const ScRange& rRange ) const
return nFormat;
}
-sal_uInt32 ScDocument::GetNumberFormat( const ScAddress& rPos ) const
+sal_uInt32 ScDocument::GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& rPos ) const
{
SCTAB nTab = rPos.Tab();
if (!TableExists(nTab))
return 0;
- return maTabs[nTab]->GetNumberFormat( rPos );
+ return maTabs[nTab]->GetNumberFormat( rContext, rPos );
}
void ScDocument::SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberFormat )
@@ -3720,14 +3720,14 @@ void ScDocument::SetNumberFormat( const ScAddress& rPos, sal_uInt32 nNumberForma
maTabs[nTab]->SetNumberFormat(rPos.Col(), rPos.Row(), nNumberFormat);
}
-void ScDocument::GetNumberFormatInfo( short& nType, sal_uLong& nIndex,
+void ScDocument::GetNumberFormatInfo( const ScInterpreterContext& rContext, short& nType, sal_uLong& nIndex,
const ScAddress& rPos ) const
{
SCTAB nTab = rPos.Tab();
if ( nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
{
- nIndex = maTabs[nTab]->GetNumberFormat( rPos );
- nType = GetFormatTable()->GetType( nIndex );
+ nIndex = maTabs[nTab]->GetNumberFormat( rContext, rPos );
+ nType = rContext.GetFormatTable()->GetType( nIndex );
}
else
{
@@ -6769,6 +6769,13 @@ ScMutationGuard::~ScMutationGuard()
#endif
}
+ScInterpreterContext ScDocument::GetNonThreadedContext() const
+{
+ // GetFormatTable() asserts that we are not in a threaded calculation
+ ScInterpreterContext aResult(*this, GetFormatTable());
+ return aResult;
+}
+
thread_local ScDocumentThreadSpecific ScDocument::maThreadSpecific;
ScRecursionHelper& ScDocument::GetRecursionHelper()
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index bc6fd157e34b..2d6d49bc191a 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1528,10 +1528,10 @@ void ScFormulaCell::Interpret()
bool bGroupInterpreted = InterpretFormulaGroup();
aDC.leaveGroup();
if (!bGroupInterpreted)
- InterpretTail( SCITP_NORMAL);
+ InterpretTail( pDocument->GetNonThreadedContext(), SCITP_NORMAL);
#else
if (!InterpretFormulaGroup())
- InterpretTail( SCITP_NORMAL);
+ InterpretTail( pDocument->GetNonThreadedContext(), SCITP_NORMAL);
#endif
pDocument->DecInterpretLevel();
}
@@ -1595,8 +1595,8 @@ void ScFormulaCell::Interpret()
bResumeIteration = false;
// Close circle once.
pDocument->IncInterpretLevel();
- rRecursionHelper.GetList().back().pCell->InterpretTail(
- SCITP_CLOSE_ITERATION_CIRCLE);
+ rRecursionHelper.GetList().back().pCell->InterpretTail( pDocument->GetNonThreadedContext(),
+ SCITP_CLOSE_ITERATION_CIRCLE);
pDocument->DecInterpretLevel();
// Start at 1, init things.
rRecursionHelper.StartIteration();
@@ -1627,7 +1627,7 @@ void ScFormulaCell::Interpret()
{
(*aIter).aPreviousResult = pIterCell->aResult;
pDocument->IncInterpretLevel();
- pIterCell->InterpretTail( SCITP_FROM_ITERATION);
+ pIterCell->InterpretTail( pDocument->GetNonThreadedContext(), SCITP_FROM_ITERATION);
pDocument->DecInterpretLevel();
}
rDone = rDone && !pIterCell->IsDirtyOrInTableOpDirty();
@@ -1699,7 +1699,7 @@ void ScFormulaCell::Interpret()
if (pCell->IsDirtyOrInTableOpDirty())
{
pDocument->IncInterpretLevel();
- pCell->InterpretTail( SCITP_NORMAL);
+ pCell->InterpretTail( pDocument->GetNonThreadedContext(), SCITP_NORMAL);
pDocument->DecInterpretLevel();
if (!pCell->IsDirtyOrInTableOpDirty() && !pCell->IsIterCell())
pCell->bRunning = (*aIter).bOldRunning;
@@ -1748,7 +1748,7 @@ class StackCleaner
};
}
-void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
+void ScFormulaCell::InterpretTail( const ScInterpreterContext& rContext, ScInterpretTailParameter eTailParam )
{
RecursionCounter aRecursionCounter( pDocument->GetRecursionHelper(), this);
nSeenInIteration = pDocument->GetRecursionHelper().GetIteration();
@@ -1775,7 +1775,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
if( pCode->GetCodeLen() && pDocument )
{
- ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode );
+ ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, rContext, aPos, *pCode );
StackCleaner aStackCleaner(pInterpreter);
FormulaError nOldErrCode = aResult.GetResultError();
if ( nSeenInIteration == 0 )
@@ -1981,7 +1981,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
}
if (bSetFormat && (bForceNumberFormat || ((nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0)))
- nFormatIndex = ScGlobal::GetStandardFormat(*pDocument->GetFormatTable(),
+ nFormatIndex = ScGlobal::GetStandardFormat(*rContext.GetFormatTable(),
nFormatIndex, nFormatType);
// Do not replace a General format (which was the reason why
@@ -2168,7 +2168,7 @@ void ScFormulaCell::HandleStuffAfterParallelCalculation()
if ( !pCode->IsRecalcModeAlways() )
pDocument->RemoveFromFormulaTree( this );
- ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode );
+ ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, pDocument->GetNonThreadedContext(), aPos, *pCode );
StackCleaner aStackCleaner(pInterpreter);
switch (pInterpreter->GetVolatileType())
@@ -4328,6 +4328,9 @@ bool ScFormulaCell::InterpretFormulaGroup()
static const bool bThreadingRequested = std::getenv("CPU_THREADED_CALCULATION");
+ // To temporarilu use threading for sc unit tests regardless of the size of the formula group,
+ // add the condition !std::getenv("LO_TESTNAME") below (with &&), and run with
+ // CPU_THREADED_CALCULATION=yes
if (GetWeight() < ScInterpreter::GetGlobalConfig().mnOpenCLMinimumFormulaGroupSize)
{
mxGroup->meCalcState = sc::GroupCalcDisabled;
@@ -4367,6 +4370,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
const unsigned mnThisThread;
const unsigned mnThreadsTotal;
ScDocument* mpDocument;
+ SvNumberFormatter* mpFormatter;
const ScAddress& mrTopPos;
SCROW mnLength;
@@ -4375,12 +4379,14 @@ bool ScFormulaCell::InterpretFormulaGroup()
unsigned nThisThread,
unsigned nThreadsTotal,
ScDocument* pDocument,
+ SvNumberFormatter* pFormatter,
const ScAddress& rTopPos,
SCROW nLength) :
comphelper::ThreadTask(rTag),
mnThisThread(nThisThread),
mnThreadsTotal(nThreadsTotal),
mpDocument(pDocument),
+ mpFormatter(pFormatter),
mrTopPos(rTopPos),
mnLength(nLength)
{
@@ -4388,11 +4394,18 @@ bool ScFormulaCell::InterpretFormulaGroup()
virtual void doWork() override
{
- mpDocument->CalculateInColumnInThread(mrTopPos, mnLength, mnThisThread, mnThreadsTotal).MergeBackIntoNonThreadedData(mpDocument->maNonThreaded);
+ std::unique_ptr<SvNumberFormatter> pFormatterForThisThread
+ (new SvNumberFormatter(mpFormatter->GetComponentContext(),
+ mpFormatter->GetLanguage()));
+ ScInterpreterContext aContext(*mpDocument, pFormatterForThisThread.get());
+
+ mpDocument->CalculateInColumnInThread(aContext, mrTopPos, mnLength, mnThisThread, mnThreadsTotal).MergeBackIntoNonThreadedData(mpDocument->maNonThreaded);
}
};
+ SvNumberFormatter* pNonThreadedFormatter = pDocument->GetNonThreadedContext().GetFormatTable();
+
comphelper::ThreadPool& rThreadPool(comphelper::ThreadPool::getSharedOptimalPool());
sal_Int32 nThreadCount = rThreadPool.getWorkerCount();
@@ -4408,7 +4421,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
std::shared_ptr<comphelper::ThreadTaskTag> aTag = comphelper::ThreadPool::createThreadTaskTag();
for (int i = 0; i < nThreadCount; ++i)
{
- rThreadPool.pushTask(new Executor(aTag, i, nThreadCount, pDocument, mxGroup->mpTopCell->aPos, mxGroup->mnLength));
+ rThreadPool.pushTask(new Executor(aTag, i, nThreadCount, pDocument, pNonThreadedFormatter, mxGroup->mpTopCell->aPos, mxGroup->mnLength));
}
SAL_INFO("sc.threaded", "Joining threads");
@@ -4606,14 +4619,14 @@ bool ScFormulaCell::InterpretInvariantFormulaGroup()
ScCompiler aComp(pDocument, aPos, aCode, pDocument->GetGrammar());
aComp.CompileTokenArray(); // Create RPN token array.
- ScInterpreter aInterpreter(this, pDocument, aPos, aCode);
+ ScInterpreter aInterpreter(this, pDocument, pDocument->GetNonThreadedContext(), aPos, aCode);
aInterpreter.Interpret();
aResult.SetToken(aInterpreter.GetResultToken().get());
}
else
{
// Formula contains no references.
- ScInterpreter aInterpreter(this, pDocument, aPos, *pCode);
+ ScInterpreter aInterpreter(this, pDocument, pDocument->GetNonThreadedContext(), aPos, *pCode);
aInterpreter.Interpret();
aResult.SetToken(aInterpreter.GetResultToken().get());
}
diff --git a/sc/source/core/data/simpleformulacalc.cxx b/sc/source/core/data/simpleformulacalc.cxx
index b1e0f65f9ff7..859114515e5c 100644
--- a/sc/source/core/data/simpleformulacalc.cxx
+++ b/sc/source/core/data/simpleformulacalc.cxx
@@ -44,7 +44,7 @@ void ScSimpleFormulaCalculator::Calculate()
return;
mbCalculated = true;
- ScInterpreter aInt(nullptr, mpDoc, maAddr, *mpCode.get());
+ ScInterpreter aInt(nullptr, mpDoc, mpDoc->GetNonThreadedContext(), maAddr, *mpCode.get());
std::unique_ptr<sfx2::LinkManager> pNewLinkMgr( new sfx2::LinkManager(mpDoc->GetDocumentShell()) );
aInt.SetLinkManager( pNewLinkMgr.get() );
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 961b2f443568..e43ab0efc7ac 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2338,12 +2338,12 @@ void ScTable::SetFormulaResults(
aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
}
-void ScTable::CalculateInColumnInThread( SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
+void ScTable::CalculateInColumnInThread( const ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
{
if (!ValidCol(nCol))
return;
- aCol[nCol].CalculateInThread( nRow, nLen, nThisThread, nThreadsTotal );
+ aCol[nCol].CalculateInThread( rContext, nRow, nLen, nThisThread, nThreadsTotal );
}
void ScTable::HandleStuffAfterParallelCalculation( SCCOL nCol, SCROW nRow, size_t nLen)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 60e05b323be9..56be6df03201 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1899,17 +1899,17 @@ const SfxPoolItem* ScTable::GetAttr( SCCOL nCol, SCROW nRow, sal_uInt16 nWhich )
return nullptr;
}
-sal_uInt32 ScTable::GetNumberFormat( const ScAddress& rPos ) const
+sal_uInt32 ScTable::GetNumberFormat( const ScInterpreterContext& rContext, const ScAddress& rPos ) const
{
return ValidColRow(rPos.Col(),rPos.Row()) ?
- aCol[rPos.Col()].GetNumberFormat( rPos.Row() ) :
+ aCol[rPos.Col()].GetNumberFormat( rContext, rPos.Row() ) :
0;
}
sal_uInt32 ScTable::GetNumberFormat( SCCOL nCol, SCROW nRow ) const
{
if (ValidColRow(nCol,nRow))
- return aCol[nCol].GetNumberFormat( nRow );
+ return aCol[nCol].GetNumberFormat( pDocument->GetNonThreadedContext(), nRow );
else
return 0;
}
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 2579545c4c91..45927fe4de8f 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -1380,14 +1380,14 @@ void ScTable::FillAutoSimple(
return;
}
bBooleanCell = (pDocument->GetFormatTable()->GetType(
- aCol[rCol].GetNumberFormat( nSource)) == css::util::NumberFormat::LOGICAL);
+ aCol[rCol].GetNumberFormat( pDocument->GetNonThreadedContext(), nSource)) == css::util::NumberFormat::LOGICAL);
}
else // rInner&:=nCol, rOuter&:=nRow
{
aSrcCell = aCol[nSource].GetCellValue(rRow);
bBooleanCell = (pDocument->GetFormatTable()->GetType(
- aCol[nSource].GetNumberFormat( rRow)) == css::util::NumberFormat::LOGICAL);
+ aCol[nSource].GetNumberFormat( pDocument->GetNonThreadedContext(), rRow)) == css::util::NumberFormat::LOGICAL);
}
bGetCell = false;
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 9917e943fe59..9c754c2e9386 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -29,6 +29,7 @@
#include <sfx2/linkmgr.hxx>
#include <scdll.hxx>
#include <scdllapi.h>
+#include <interpretercontext.hxx>
#include <types.hxx>
#include <externalrefmgr.hxx>
#include <calcconfig.hxx>
@@ -198,6 +199,7 @@ private:
formula::FormulaTokenIterator aCode;
ScAddress aPos;
ScTokenArray& rArr;
+ const ScInterpreterContext& mrContext;
ScDocument* pDok;
sfx2::LinkManager* mpLinkManager;
svl::SharedStringPool& mrStrPool;
@@ -988,7 +990,7 @@ private:
double GetTInv( double fAlpha, double fSize, int nType );
public:
- ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
+ ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, const ScInterpreterContext& rContext,
const ScAddress&, ScTokenArray& );
~ScInterpreter();
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 0730bae98a4d..f637ab5753bc 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -251,7 +251,7 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
ScCompiler aComp(&rDoc, aTmpPos, aCode2);
aComp.CompileTokenArray();
- ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
+ ScInterpreter aInterpreter(pDest, &rDoc, rDoc.GetNonThreadedContext(), aTmpPos, aCode2);
aInterpreter.Interpret();
aResults.push_back(aInterpreter.GetResultToken());
} // for loop end (xGroup->mnLength)
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 157c8a2dcedd..9fac42814541 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -3550,7 +3550,7 @@ void ScInterpreter::ScMin( bool bTextAsZero )
{
if (nMin > nVal)
nMin = nVal;
- aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
+ aValIter.GetCurNumFmtInfo( mrContext, nFuncFmtType, nFuncFmtIndex );
while ((nErr == FormulaError::NONE) && aValIter.GetNext(nVal, nErr))
{
if (nMin > nVal)
@@ -3707,7 +3707,7 @@ void ScInterpreter::ScMax( bool bTextAsZero )
{
if (nMax < nVal)
nMax = nVal;
- aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
+ aValIter.GetCurNumFmtInfo( mrContext, nFuncFmtType, nFuncFmtIndex );
while ((nErr == FormulaError::NONE) && aValIter.GetNext(nVal, nErr))
{
if (nMax < nVal)
@@ -4864,7 +4864,7 @@ void ScInterpreter::ScMatch()
rParam.bByRow = false;
rParam.nRow2 = nRow1;
rEntry.nField = nCol1;
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false);
// Advance Entry.nField in Iterator if column changed
aCellIter.SetAdvanceQueryParamEntryField( true );
if (fTyp == 0.0)
@@ -5343,7 +5343,7 @@ void ScInterpreter::IterateParametersIf( ScIterFuncIf eFunc )
}
else
{
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false);
// Increment Entry.nField in iterator when switching to next column.
aCellIter.SetAdvanceQueryParamEntryField( true );
if ( aCellIter.GetFirst() )
@@ -5605,7 +5605,7 @@ void ScInterpreter::ScCountIf()
}
else
{
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false);
// Keep Entry.nField in iterator on column change
aCellIter.SetAdvanceQueryParamEntryField( true );
if ( aCellIter.GetFirst() )
@@ -5898,7 +5898,7 @@ void ScInterpreter::IterateParametersIfs( double(*ResultFunc)( const sc::ParamIf
}
else
{
- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, rParam, false);
// Increment Entry.nField in iterator when switching to next column.
aCellIter.SetAdvanceQueryParamEntryField( true );
if ( aCellIter.GetFirst() )
@@ -6724,7 +6724,7 @@ void ScInterpreter::ScLookup()
if (rItem.meType == ScQueryEntry::ByString)
aParam.eSearchType = DetectSearchType(rItem.maString.getString(), pDok);
- ScQueryCellIterator aCellIter(pDok, nTab1, aParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, aParam, false);
SCCOL nC;
SCROW nR;
// Advance Entry.nField in iterator upon switching columns if
@@ -7071,7 +7071,7 @@ void ScInterpreter::CalculateLookup(bool bHLookup)
rEntry.eOp = SC_LESS_EQUAL;
if ( bHLookup )
{
- ScQueryCellIterator aCellIter(pDok, nTab1, aParam, false);
+ ScQueryCellIterator aCellIter(pDok, mrContext, nTab1, aParam, false);
// advance Entry.nField in Iterator upon switching columns
aCellIter.SetAdvanceQueryParamEntryField( true );
if ( bSorted )
@@ -7447,7 +7447,7 @@ void ScInterpreter::DBIterator( ScIterFunc eFunc )
SetError(FormulaError::NoValue);
return;
}
- ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter(pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if ( aValIter.GetFirst(aValue) && aValue.mnError == FormulaError::NONE )
{
@@ -7535,7 +7535,7 @@ void ScInterpreter::ScDBCount()
// so the source range has to be restricted, like before the introduction
// of ScDBQueryParamBase.
p->nCol1 = p->nCol2 = p->mnField;
- ScQueryCellIterator aCellIter( pDok, nTab, *p, true);
+ ScQueryCellIterator aCellIter( pDok, mrContext, nTab, *p, true);
if ( aCellIter.GetFirst() )
{
do
@@ -7551,7 +7551,7 @@ void ScInterpreter::ScDBCount()
SetError(FormulaError::NoValue);
return;
}
- ScDBQueryDataIterator aValIter( pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter( pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if ( aValIter.GetFirst(aValue) && aValue.mnError == FormulaError::NONE )
{
@@ -7582,7 +7582,7 @@ void ScInterpreter::ScDBCount2()
}
sal_uLong nCount = 0;
pQueryParam->mbSkipString = false;
- ScDBQueryDataIterator aValIter( pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter( pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if ( aValIter.GetFirst(aValue) && aValue.mnError == FormulaError::NONE )
{
@@ -7636,7 +7636,7 @@ void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount )
SetError(FormulaError::NoValue);
return;
}
- ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter(pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if (aValIter.GetFirst(aValue) && aValue.mnError == FormulaError::NONE)
{
@@ -9297,11 +9297,11 @@ utl::SearchParam::SearchType ScInterpreter::DetectSearchType( const OUString& rS
return utl::SearchParam::SearchType::Normal;
}
-static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument * pDoc,
+static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument * pDoc, const ScInterpreterContext& rContext,
const ScQueryParam & rParam, const ScQueryEntry & rEntry )
{
bool bFound = false;
- ScQueryCellIterator aCellIter( pDoc, rParam.nTab, rParam, false);
+ ScQueryCellIterator aCellIter( pDoc, rContext, rParam.nTab, rParam, false);
if (rEntry.eOp != SC_EQUAL)
{
// range lookup <= or >=
@@ -9338,7 +9338,7 @@ bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
* direct lookups here. We could even further attribute volatility per
* parameter so it would affect only the lookup range parameter. */
if (!bColumnsMatch || GetVolatileType() != NOT_VOLATILE)
- bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
+ bFound = lcl_LookupQuery( o_rResultPos, pDok, mrContext, rParam, rEntry);
else
{
ScRange aLookupRange( rParam.nCol1, rParam.nRow1, rParam.nTab,
@@ -9351,7 +9351,7 @@ bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
{
case ScLookupCache::NOT_CACHED :
case ScLookupCache::CRITERIA_DIFFERENT :
- bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
+ bFound = lcl_LookupQuery( o_rResultPos, pDok, mrContext, rParam, rEntry);
if (eCacheResult == ScLookupCache::NOT_CACHED)
rCache.insert( o_rResultPos, aCriteria, aPos, bFound);
break;
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 50350fac8e85..e62610b1d50b 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -203,7 +203,7 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, ScRefCellValue&
if (pFCell->IsValue())
{
fValue = pFCell->GetValue();
- pDok->GetNumberFormatInfo( nCurFmtType, nCurFmtIndex,
+ pDok->GetNumberFormatInfo( mrContext, nCurFmtType, nCurFmtIndex,
rPos );
}
else
@@ -221,7 +221,7 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, ScRefCellValue&
case CELLTYPE_VALUE:
{
fValue = rCell.mfValue;
- nCurFmtIndex = pDok->GetNumberFormat( rPos );
+ nCurFmtIndex = pDok->GetNumberFormat( mrContext, rPos );
nCurFmtType = pFormatter->GetType( nCurFmtIndex );
if ( bCalcAsShown && fValue != 0.0 )
fValue = pDok->RoundValueAsShown( fValue, nCurFmtIndex );
@@ -697,7 +697,7 @@ void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString,
{
bool bInherited = (aCell.meType == CELLTYPE_FORMULA);
if (pRetTypeExpr && pRetIndexExpr)
- pDok->GetNumberFormatInfo(*pRetTypeExpr, *pRetIndexExpr, rAddress);
+ pDok->GetNumberFormatInfo(mrContext, *pRetTypeExpr, *pRetIndexExpr, rAddress);
PushTempToken( new ScEmptyCellToken( bInherited, bDisplayEmptyAsString));
return;
}
@@ -2503,7 +2503,7 @@ void ScInterpreter::ScDBGet()
}
pQueryParam->mbSkipString = false;
- ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
+ ScDBQueryDataIterator aValIter(pDok, mrContext, pQueryParam.release());
ScDBQueryDataIterator::Value aValue;
if (!aValIter.GetFirst(aValue) || aValue.mnError != FormulaError::NONE)
{
@@ -3782,18 +3782,19 @@ void ScInterpreter::ScTTT()
PushError(FormulaError::NoValue);
}
-ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
+ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, const ScInterpreterContext& rContext,
const ScAddress& rPos, ScTokenArray& r )
: aCode(r)
, aPos(rPos)
, rArr(r)
+ , mrContext(rContext)
, pDok(pDoc)
, mpLinkManager(pDok->GetLinkManager())
, mrStrPool(pDoc->GetSharedStringPool())
, pJumpMatrix(nullptr)
, pTokenMatrixMap(nullptr)
, pMyFormulaCell(pCell)
- , pFormatter(pDoc->GetFormatTable())
+ , pFormatter(rContext.GetFormatTable())
, pCur(nullptr)
, nGlobalError(FormulaError::NONE)
, sp(0)
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 0fe8cced4c6f..909965676139 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -3224,7 +3224,7 @@ void ScInterpreter::ScMatRef()
else
{
// Determine nFuncFmtType type before PushDouble().
- pDok->GetNumberFormatInfo(nCurFmtType, nCurFmtIndex, aAdr);
+ pDok->GetNumberFormatInfo(mrContext, nCurFmtType, nCurFmtIndex, aAdr);
nFuncFmtType = nCurFmtType;
nFuncFmtIndex = nCurFmtIndex;
PushDouble(nMatVal.fVal); // handles DoubleError
@@ -3234,7 +3234,7 @@ void ScInterpreter::ScMatRef()
else
{
// Determine nFuncFmtType type before PushDouble().
- pDok->GetNumberFormatInfo(nCurFmtType, nCurFmtIndex, aAdr);
+ pDok->GetNumberFormatInfo(mrContext, nCurFmtType, nCurFmtIndex, aAdr);
nFuncFmtType = nCurFmtType;
nFuncFmtIndex = nCurFmtIndex;
// If not a result matrix, obtain the cell value.
diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx
index ea19289230a2..0f513c231327 100644
--- a/sc/source/core/tool/interpr6.cxx
+++ b/sc/source/core/tool/interpr6.cxx
@@ -319,13 +319,14 @@ public:
class FuncCount : public sc::ColumnSpanSet::ColumnAction
{
+ const ScInterpreterContext& mrContext;
sc::ColumnBlockConstPosition maPos;
ScColumn* mpCol;
size_t mnCount;
sal_uInt32 mnNumFmt;
public:
- FuncCount() : mpCol(nullptr), mnCount(0), mnNumFmt(0) {}
+ FuncCount(const ScInterpreterContext& rContext) : mrContext(rContext), mpCol(nullptr), mnCount(0), mnNumFmt(0) {}
virtual void startColumn(ScColumn* pCol) override
{
@@ -341,7 +342,7 @@ public:
NumericCellCounter aFunc;
maPos.miCellPos = sc::ParseBlock(maPos.miCellPos, mpCol->GetCellStore(), aFunc, nRow1, nRow2);
mnCount += aFunc.getCount();
- mnNumFmt = mpCol->GetNumberFormat(nRow2);
+ mnNumFmt = mpCol->GetNumberFormat(mrContext, nRow2);
};
size_t getCount() const { return mnCount; }
@@ -350,6 +351,7 @@ public:
class FuncSum : public sc::ColumnSpanSet::ColumnAction
{
+ const ScInterpreterContext& mrContext;
sc::ColumnBlockConstPosition maPos;
ScColumn* mpCol;
double mfSum;
@@ -357,7 +359,7 @@ class FuncSum : public sc::ColumnSpanSet::ColumnAction
sal_uInt32 mnNumFmt;
public:
- FuncSum() : mpCol(nullptr), mfSum(0.0), mnError(FormulaError::NONE), mnNumFmt(0) {}
+ FuncSum(const ScInterpreterContext& rContext) : mrContext(rContext), mpCol(nullptr), mfSum(0.0), mnError(FormulaError::NONE), mnNumFmt(0) {}
virtual void startColumn(ScColumn* pCol) override
{
@@ -389,7 +391,7 @@ public:
mfSum += aFunc.getRest();
}
- mnNumFmt = mpCol->GetNumberFormat(nRow2);
+ mnNumFmt = mpCol->GetNumberFormat(mrContext, nRow2);
};
FormulaError getError() const { return mnError; }
@@ -821,7 +823,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
if ( eFunc == ifSUM )
{
- FuncSum aAction;
+ FuncSum aAction(mrContext);
aSet.executeColumnAction( *pDok, aAction, fMem );
FormulaError nErr = aAction.getError();
if ( nErr != FormulaError::NONE )
@@ -836,7 +838,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
}
else
{
- FuncCount aAction;
+ FuncCount aAction(mrContext);
aSet.executeColumnAction(*pDok, aAction);
nCount += aAction.getCount();
@@ -853,7 +855,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
if (aValIter.GetFirst(fVal, nErr))
{
// placed the loop on the inside for performance reasons:
- aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
+ aValIter.GetCurNumFmtInfo( mrContext, nFuncFmtType, nFuncFmtIndex );
switch( eFunc )
{
case ifAVERAGE:
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx
index 999600c58cc3..21f2963f8abb 100644
--- a/sc/source/filter/excel/xepivot.cxx
+++ b/sc/source/filter/excel/xepivot.cxx
@@ -341,7 +341,7 @@ void XclExpPCField::InitStandardField( const ScRange& rRange )
if( rDoc.HasValueData( aPos.Col(), aPos.Row(), aPos.Tab() ) )
{
double fValue = rDoc.GetValue( aPos );
- short nFmtType = rFormatter.GetType( rDoc.GetNumberFormat( aPos ) );
+ short nFmtType = rFormatter.GetType( rDoc.GetNumberFormat( rDoc.GetNonThreadedContext(), aPos ) );
if( nFmtType == css::util::NumberFormat::LOGICAL )
InsertOrigBoolItem( fValue != 0, aText );
else if( nFmtType & css::util::NumberFormat::DATETIME )
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
index cf4163c82cff..8cdbde3bb22d 100644
--- a/sc/source/filter/excel/xicontent.cxx
+++ b/sc/source/filter/excel/xicontent.cxx
@@ -173,7 +173,7 @@ void lclInsertUrl( XclImpRoot& rRoot, const OUString& rUrl, SCCOL nScCol, SCROW
case CELLTYPE_STRING:
case CELLTYPE_EDIT:
{
- sal_uLong nNumFmt = rDoc.getDoc().GetNumberFormat(aScPos);
+ sal_uLong nNumFmt = rDoc.getDoc().GetNumberFormat(rDoc.getDoc().GetNonThreadedContext(), aScPos);
SvNumberFormatter* pFormatter = rDoc.getDoc().GetFormatTable();
Color* pColor;
OUString aDisplText;
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index beb47fc010dd..c7c380178e74 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -2878,7 +2878,7 @@ public:
if (pTok)
{
// Cache this cell.
- mpRefTab->setCell(mpCurCol->GetCol(), nRow, pTok, mpCurCol->GetNumberFormat(nRow));
+ mpRefTab->setCell(mpCurCol->GetCol(), nRow, pTok, mpCurCol->GetNumberFormat(mpCurCol->GetDoc().GetNonThreadedContext(), nRow));
mpRefTab->setCachedCell(mpCurCol->GetCol(), nRow);
}
}
commit 3695439ada8f9a85a2ef405d07875e4b73f09c6c
Author: Tor Lillqvist <tml at collabora.com>
Date: Fri Sep 29 17:43:24 2017 +0300
Disable formula group threading for macros and table ops
Those are likely highly problematic to do in parallel.
Change-Id: I50cc32eb72f6b7951d247ecd787b2942cd7d9163
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index d6ee44cf86c0..d0ebe0ca2e76 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1337,16 +1337,28 @@ bool ScTokenArray::AddFormulaToken(
void ScTokenArray::CheckToken( const FormulaToken& r )
{
+ static const std::set<OpCode> aThreadedCalcBlackList({
+ ocMacro,
+ ocTableOp
+ });
+
if (IsFormulaVectorDisabled())
// It's already disabled. No more checking needed.
return;
static const bool bThreadingRequested = std::getenv("CPU_THREADED_CALCULATION");
+ OpCode eOp = r.GetOpCode();
+
if (!ScCalcConfig::isOpenCLEnabled() && bThreadingRequested)
+ {
+ if (aThreadedCalcBlackList.count(eOp))
+ {
+ meVectorState = FormulaVectorDisabledNotInSubSet;
+ SAL_INFO("sc.core.formulagroup", "opcode " << formula::FormulaCompiler().GetOpCodeMap(sheet::FormulaLanguage::ENGLISH)->getSymbol(eOp) << " disables threaded calculation of formula group");
+ }
return;
-
- OpCode eOp = r.GetOpCode();
+ }
if (SC_OPCODE_START_FUNCTION <= eOp && eOp < SC_OPCODE_STOP_FUNCTION)
{
commit 07c7ab11ead9345998b10d5613648953ad09c9e5
Author: Tor Lillqvist <tml at collabora.com>
Date: Fri Sep 29 17:01:03 2017 +0300
Move nInterpreterTableOpLevel back to ScDocument
Change-Id: I4de0051d9fa5de9147954c6021d47076145a3e59
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index d8d0879f6a87..e85b4ba29365 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -276,14 +276,11 @@ const sal_uInt8 SC_DDE_IGNOREMODE = 255; /// For usage in FindDdeLink()
// During threaded calculation fields being mutated are kept in this struct
struct ScDocumentThreadSpecific
{
- sal_uInt16 nInterpreterTableOpLevel; // >0 if in interpreter TableOp
-
ScRecursionHelper* pRecursionHelper; // information for recursive and iterative cell formulas
ScLookupCacheMapImpl* pLookupCacheMapImpl; // cache for lookups like VLOOKUP and MATCH
ScDocumentThreadSpecific() :
- nInterpreterTableOpLevel(0),
pRecursionHelper(nullptr),
pLookupCacheMapImpl(nullptr)
{
@@ -456,6 +453,7 @@ private:
sal_uLong nXMLImportedFormulaCount; // progress count during XML import
sal_uInt16 nInterpretLevel; // >0 if in interpreter
sal_uInt16 nMacroInterpretLevel; // >0 if macro in interpreter
+ sal_uInt16 nInterpreterTableOpLevel; // >0 if in interpreter TableOp
ScDocumentThreadSpecific maNonThreaded;
@@ -2193,9 +2191,17 @@ public:
if ( nMacroInterpretLevel )
nMacroInterpretLevel--;
}
- bool IsInInterpreterTableOp() const;
- void IncInterpreterTableOpLevel();
- void DecInterpreterTableOpLevel();
+ bool IsInInterpreterTableOp() const { return nInterpreterTableOpLevel != 0; }
+ void IncInterpreterTableOpLevel()
+ {
+ if ( nInterpreterTableOpLevel < USHRT_MAX )
+ nInterpreterTableOpLevel++;
+ }
+ void DecInterpreterTableOpLevel()
+ {
+ if ( nInterpreterTableOpLevel )
+ nInterpreterTableOpLevel--;
+ }
// add a formula to be remembered for TableOp broadcasts
void AddTableOpFormulaCell( ScFormulaCell* );
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 9fab88f4e910..283c082199b2 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -176,6 +176,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
nXMLImportedFormulaCount( 0 ),
nInterpretLevel(0),
nMacroInterpretLevel(0),
+ nInterpreterTableOpLevel(0),
nSrcVer( SC_CURRENT_VERSION ),
nFormulaTrackCount(0),
eHardRecalcState(HardRecalcState::OFF),
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 1706342ccd36..185115ac8ad7 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6771,42 +6771,6 @@ ScMutationGuard::~ScMutationGuard()
thread_local ScDocumentThreadSpecific ScDocument::maThreadSpecific;
-bool ScDocument::IsInInterpreterTableOp() const
-{
- if (!mbThreadedGroupCalcInProgress)
- return maNonThreaded.nInterpreterTableOpLevel != 0;
- else
- return maThreadSpecific.nInterpreterTableOpLevel != 0;
-}
-
-void ScDocument::IncInterpreterTableOpLevel()
-{
- if (!mbThreadedGroupCalcInProgress)
- {
- if (maNonThreaded.nInterpreterTableOpLevel < USHRT_MAX)
- maNonThreaded.nInterpreterTableOpLevel++;
- }
- else
- {
- if (maThreadSpecific.nInterpreterTableOpLevel < USHRT_MAX)
- maThreadSpecific.nInterpreterTableOpLevel++;
- }
-}
-
-void ScDocument::DecInterpreterTableOpLevel()
-{
- if (!mbThreadedGroupCalcInProgress)
- {
- if (maNonThreaded.nInterpreterTableOpLevel)
- maNonThreaded.nInterpreterTableOpLevel--;
- }
- else
- {
- if (maThreadSpecific.nInterpreterTableOpLevel)
- maThreadSpecific.nInterpreterTableOpLevel--;
- }
-}
-
ScRecursionHelper& ScDocument::GetRecursionHelper()
{
if (!mbThreadedGroupCalcInProgress)
@@ -6825,16 +6789,12 @@ ScRecursionHelper& ScDocument::GetRecursionHelper()
void ScDocumentThreadSpecific::SetupFromNonThreadedData(const ScDocumentThreadSpecific& rNonThreadedData)
{
- nInterpreterTableOpLevel = rNonThreadedData.nInterpreterTableOpLevel;
-
// What about the recursion helper?
// Copy the lookup cache?
}
void ScDocumentThreadSpecific::MergeBackIntoNonThreadedData(ScDocumentThreadSpecific& rNonThreadedData)
{
- assert(nInterpreterTableOpLevel == rNonThreadedData.nInterpreterTableOpLevel);
-
// What about recursion helper and lookup cache?
}
commit e40902d30f596d3fd804728240288a92ccc66e5d
Author: Tor Lillqvist <tml at collabora.com>
Date: Fri Sep 29 16:00:18 2017 +0300
Move nMacroInterpretLevel back to ScDocument
Change-Id: I48748434c845af963af160f8bbd75e4ab7ce95bd
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index d253a17c60ef..d8d0879f6a87 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -276,7 +276,6 @@ const sal_uInt8 SC_DDE_IGNOREMODE = 255; /// For usage in FindDdeLink()
// During threaded calculation fields being mutated are kept in this struct
struct ScDocumentThreadSpecific
{
- sal_uInt16 nMacroInterpretLevel; // >0 if macro in interpreter
sal_uInt16 nInterpreterTableOpLevel; // >0 if in interpreter TableOp
ScRecursionHelper* pRecursionHelper; // information for recursive and iterative cell formulas
@@ -284,7 +283,6 @@ struct ScDocumentThreadSpecific
ScLookupCacheMapImpl* pLookupCacheMapImpl; // cache for lookups like VLOOKUP and MATCH
ScDocumentThreadSpecific() :
- nMacroInterpretLevel(0),
nInterpreterTableOpLevel(0),
pRecursionHelper(nullptr),
pLookupCacheMapImpl(nullptr)
@@ -457,6 +455,7 @@ private:
sal_uLong nFormulaCodeInTree; // formula RPN in the formula tree
sal_uLong nXMLImportedFormulaCount; // progress count during XML import
sal_uInt16 nInterpretLevel; // >0 if in interpreter
+ sal_uInt16 nMacroInterpretLevel; // >0 if macro in interpreter
ScDocumentThreadSpecific maNonThreaded;
@@ -2181,9 +2180,19 @@ public:
if ( nInterpretLevel )
nInterpretLevel--;
}
- sal_uInt16 GetMacroInterpretLevel();
- void IncMacroInterpretLevel();
- void DecMacroInterpretLevel();
+ sal_uInt16 GetMacroInterpretLevel() { return nMacroInterpretLevel; }
+ void IncMacroInterpretLevel()
+ {
+ assert(!mbThreadedGroupCalcInProgress);
+ if ( nMacroInterpretLevel < USHRT_MAX )
+ nMacroInterpretLevel++;
+ }
+ void DecMacroInterpretLevel()
+ {
+ assert(!mbThreadedGroupCalcInProgress);
+ if ( nMacroInterpretLevel )
+ nMacroInterpretLevel--;
+ }
bool IsInInterpreterTableOp() const;
void IncInterpreterTableOpLevel();
void DecInterpreterTableOpLevel();
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index c5d0c7e8cea2..9fab88f4e910 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -175,6 +175,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
nFormulaCodeInTree(0),
nXMLImportedFormulaCount( 0 ),
nInterpretLevel(0),
+ nMacroInterpretLevel(0),
nSrcVer( SC_CURRENT_VERSION ),
nFormulaTrackCount(0),
eHardRecalcState(HardRecalcState::OFF),
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 2df3f8e10a8b..1706342ccd36 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6771,30 +6771,6 @@ ScMutationGuard::~ScMutationGuard()
thread_local ScDocumentThreadSpecific ScDocument::maThreadSpecific;
-sal_uInt16 ScDocument::GetMacroInterpretLevel()
-{
- if (!mbThreadedGroupCalcInProgress)
- return maNonThreaded.nMacroInterpretLevel;
- else
- return maThreadSpecific.nMacroInterpretLevel;
-}
-
-void ScDocument::IncMacroInterpretLevel()
-{
- if (!mbThreadedGroupCalcInProgress)
- maNonThreaded.nMacroInterpretLevel++;
- else
- maThreadSpecific.nMacroInterpretLevel++;
-}
-
-void ScDocument::DecMacroInterpretLevel()
-{
- if (!mbThreadedGroupCalcInProgress)
- maNonThreaded.nMacroInterpretLevel--;
- else
- maThreadSpecific.nMacroInterpretLevel--;
-}
-
bool ScDocument::IsInInterpreterTableOp() const
{
if (!mbThreadedGroupCalcInProgress)
@@ -6849,7 +6825,6 @@ ScRecursionHelper& ScDocument::GetRecursionHelper()
void ScDocumentThreadSpecific::SetupFromNonThreadedData(const ScDocumentThreadSpecific& rNonThreadedData)
{
- nMacroInterpretLevel = rNonThreadedData.nMacroInterpretLevel;
nInterpreterTableOpLevel = rNonThreadedData.nInterpreterTableOpLevel;
// What about the recursion helper?
@@ -6858,7 +6833,6 @@ void ScDocumentThreadSpecific::SetupFromNonThreadedData(const ScDocumentThreadSp
void ScDocumentThreadSpecific::MergeBackIntoNonThreadedData(ScDocumentThreadSpecific& rNonThreadedData)
{
- assert(nMacroInterpretLevel == rNonThreadedData.nMacroInterpretLevel);
assert(nInterpreterTableOpLevel == rNonThreadedData.nInterpreterTableOpLevel);
// What about recursion helper and lookup cache?
commit 6f78078499a7c9f091fa828bcc8970686880e3cf
Author: Tor Lillqvist <tml at collabora.com>
Date: Fri Sep 29 14:26:29 2017 +0300
Move nInterpretLevel back to ScDocument
Move the calls to increment and decrement it out of InterpretTail(),
to those call sites that aren't reached during parallelized
calculations.
Change-Id: Ie1bd03dd62aea5f6c71c383df21afff29391dade
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index c5ab947feb95..d253a17c60ef 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -276,7 +276,6 @@ const sal_uInt8 SC_DDE_IGNOREMODE = 255; /// For usage in FindDdeLink()
// During threaded calculation fields being mutated are kept in this struct
struct ScDocumentThreadSpecific
{
- sal_uInt16 nInterpretLevel; // >0 if in interpreter
sal_uInt16 nMacroInterpretLevel; // >0 if macro in interpreter
sal_uInt16 nInterpreterTableOpLevel; // >0 if in interpreter TableOp
@@ -285,7 +284,6 @@ struct ScDocumentThreadSpecific
ScLookupCacheMapImpl* pLookupCacheMapImpl; // cache for lookups like VLOOKUP and MATCH
ScDocumentThreadSpecific() :
- nInterpretLevel(0),
nMacroInterpretLevel(0),
nInterpreterTableOpLevel(0),
pRecursionHelper(nullptr),
@@ -458,6 +456,8 @@ private:
sal_uLong nFormulaCodeInTree; // formula RPN in the formula tree
sal_uLong nXMLImportedFormulaCount; // progress count during XML import
+ sal_uInt16 nInterpretLevel; // >0 if in interpreter
+
ScDocumentThreadSpecific maNonThreaded;
// There can be only one ScDocument being calculated in a thread at a time, so we can use a
@@ -2167,9 +2167,20 @@ public:
void SetForcedFormulas( bool bVal ) { bHasForcedFormulas = bVal; }
sal_uLong GetFormulaCodeInTree() const { return nFormulaCodeInTree; }
- bool IsInInterpreter() const;
- void IncInterpretLevel();
- void DecInterpretLevel();
+ bool IsInInterpreter() const { return nInterpretLevel != 0; }
+
+ void IncInterpretLevel()
+ {
+ assert(!mbThreadedGroupCalcInProgress);
+ if ( nInterpretLevel < USHRT_MAX )
+ nInterpretLevel++;
+ }
+ void DecInterpretLevel()
+ {
+ assert(!mbThreadedGroupCalcInProgress);
+ if ( nInterpretLevel )
+ nInterpretLevel--;
+ }
sal_uInt16 GetMacroInterpretLevel();
void IncMacroInterpretLevel();
void DecMacroInterpretLevel();
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 701305d708f4..705b5ed83ae5 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
@@ -2899,6 +2899,9 @@ void ScColumn::CalculateInThread( SCROW nRow, size_t nLen, unsigned nThisThread,
continue;
ScFormulaCell& rCell = **itCell;
+ // Here we don't call IncInterpretLevel() and DecInterpretLevel() as this call site is
+ // always in a threaded calculation.
+ assert(pDocument->mbThreadedGroupCalcInProgress);
rCell.InterpretTail(ScFormulaCell::SCITP_NORMAL);
}
}
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 43332c2ec873..c5d0c7e8cea2 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -174,6 +174,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
mbThreadedGroupCalcInProgress( false ),
nFormulaCodeInTree(0),
nXMLImportedFormulaCount( 0 ),
+ nInterpretLevel(0),
nSrcVer( SC_CURRENT_VERSION ),
nFormulaTrackCount(0),
eHardRecalcState(HardRecalcState::OFF),
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 2f2a0dabe995..2df3f8e10a8b 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6771,30 +6771,6 @@ ScMutationGuard::~ScMutationGuard()
thread_local ScDocumentThreadSpecific ScDocument::maThreadSpecific;
-bool ScDocument::IsInInterpreter() const
-{
- if (!mbThreadedGroupCalcInProgress)
- return maNonThreaded.nInterpretLevel != 0;
- else
- return maThreadSpecific.nInterpretLevel != 0;
-}
-
-void ScDocument::IncInterpretLevel()
-{
- if (!mbThreadedGroupCalcInProgress)
- maNonThreaded.nInterpretLevel++;
- else
- maThreadSpecific.nInterpretLevel++;
-}
-
-void ScDocument::DecInterpretLevel()
-{
- if (!mbThreadedGroupCalcInProgress)
- maNonThreaded.nInterpretLevel--;
- else
- maThreadSpecific.nInterpretLevel--;
-}
-
sal_uInt16 ScDocument::GetMacroInterpretLevel()
{
if (!mbThreadedGroupCalcInProgress)
@@ -6873,7 +6849,6 @@ ScRecursionHelper& ScDocument::GetRecursionHelper()
void ScDocumentThreadSpecific::SetupFromNonThreadedData(const ScDocumentThreadSpecific& rNonThreadedData)
{
- nInterpretLevel = rNonThreadedData.nInterpretLevel;
nMacroInterpretLevel = rNonThreadedData.nMacroInterpretLevel;
nInterpreterTableOpLevel = rNonThreadedData.nInterpreterTableOpLevel;
@@ -6883,7 +6858,6 @@ void ScDocumentThreadSpecific::SetupFromNonThreadedData(const ScDocumentThreadSp
void ScDocumentThreadSpecific::MergeBackIntoNonThreadedData(ScDocumentThreadSpecific& rNonThreadedData)
{
- assert(nInterpretLevel == rNonThreadedData.nInterpretLevel);
assert(nMacroInterpretLevel == rNonThreadedData.nMacroInterpretLevel);
assert(nInterpreterTableOpLevel == rNonThreadedData.nInterpreterTableOpLevel);
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index e0bc6aab9037..bc6fd157e34b 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1522,6 +1522,7 @@ void ScFormulaCell::Interpret()
}
else
{
+ pDocument->IncInterpretLevel();
#if DEBUG_CALCULATION
aDC.enterGroup();
bool bGroupInterpreted = InterpretFormulaGroup();
@@ -1532,6 +1533,7 @@ void ScFormulaCell::Interpret()
if (!InterpretFormulaGroup())
InterpretTail( SCITP_NORMAL);
#endif
+ pDocument->DecInterpretLevel();
}
// While leaving a recursion or iteration stack, insert its cells to the
@@ -1592,8 +1594,10 @@ void ScFormulaCell::Interpret()
{
bResumeIteration = false;
// Close circle once.
+ pDocument->IncInterpretLevel();
rRecursionHelper.GetList().back().pCell->InterpretTail(
SCITP_CLOSE_ITERATION_CIRCLE);
+ pDocument->DecInterpretLevel();
// Start at 1, init things.
rRecursionHelper.StartIteration();
// Mark all cells being in iteration.
@@ -1622,7 +1626,9 @@ void ScFormulaCell::Interpret()
pIterCell->GetSeenInIteration())
{
(*aIter).aPreviousResult = pIterCell->aResult;
+ pDocument->IncInterpretLevel();
pIterCell->InterpretTail( SCITP_FROM_ITERATION);
+ pDocument->DecInterpretLevel();
}
rDone = rDone && !pIterCell->IsDirtyOrInTableOpDirty();
}
@@ -1692,7 +1698,9 @@ void ScFormulaCell::Interpret()
ScFormulaCell* pCell = (*aIter).pCell;
if (pCell->IsDirtyOrInTableOpDirty())
{
+ pDocument->IncInterpretLevel();
pCell->InterpretTail( SCITP_NORMAL);
+ pDocument->DecInterpretLevel();
if (!pCell->IsDirtyOrInTableOpDirty() && !pCell->IsIterCell())
pCell->bRunning = (*aIter).bOldRunning;
}
@@ -1728,16 +1736,14 @@ void ScFormulaCell::Interpret()
namespace {
class StackCleaner
{
- ScDocument* pDoc;
ScInterpreter* pInt;
public:
- StackCleaner( ScDocument* pD, ScInterpreter* pI )
- : pDoc(pD), pInt(pI)
+ StackCleaner( ScInterpreter* pI )
+ : pInt(pI)
{}
~StackCleaner()
{
delete pInt;
- pDoc->DecInterpretLevel();
}
};
}
@@ -1769,9 +1775,8 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
if( pCode->GetCodeLen() && pDocument )
{
- pDocument->IncInterpretLevel();
ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode );
- StackCleaner aStackCleaner( pDocument, pInterpreter);
+ StackCleaner aStackCleaner(pInterpreter);
FormulaError nOldErrCode = aResult.GetResultError();
if ( nSeenInIteration == 0 )
{ // Only the first time
@@ -2163,9 +2168,8 @@ void ScFormulaCell::HandleStuffAfterParallelCalculation()
if ( !pCode->IsRecalcModeAlways() )
pDocument->RemoveFromFormulaTree( this );
- pDocument->IncInterpretLevel();
ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode );
- StackCleaner aStackCleaner( pDocument, pInterpreter);
+ StackCleaner aStackCleaner(pInterpreter);
switch (pInterpreter->GetVolatileType())
{
commit 0a2e85e7f2852cadad0a1fab7e13323d06478b00
Author: Tor Lillqvist <tml at collabora.com>
Date: Fri Sep 29 11:04:17 2017 +0300
Re-work how the thread-specific data in ScDocument works
We can use normal thread_local data for it as a thread can only be
acting on one ScDocument in parallelized formula group calculation
anyway. Use separate data instance for the non-threaded data, and when
a thread starts, copy that to the thread-specific data.
Change-Id: I3e58320a728d1c5639a8a078748b3d4d7a451b25
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 64929d7e43ac..c5ab947feb95 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
@@ -273,6 +273,7 @@ const sal_uInt8 SC_DDE_ENGLISH = 1;
const sal_uInt8 SC_DDE_TEXT = 2;
const sal_uInt8 SC_DDE_IGNOREMODE = 255; /// For usage in FindDdeLink() only!
+// During threaded calculation fields being mutated are kept in this struct
struct ScDocumentThreadSpecific
{
sal_uInt16 nInterpretLevel; // >0 if in interpreter
@@ -295,6 +296,12 @@ struct ScDocumentThreadSpecific
~ScDocumentThreadSpecific()
{
}
+
+ // To be called in the thread at start
+ void SetupFromNonThreadedData(const ScDocumentThreadSpecific& rNonThreadedData);
+
+ // To be called in the main thread after the thread has finished
+ void MergeBackIntoNonThreadedData(ScDocumentThreadSpecific& rNonThreadedData);
};
enum class ScMutationGuardFlags
@@ -437,6 +444,7 @@ public:
/// list of ScInterpreterTableOpParams currently in use
std::vector<std::unique_ptr<ScInterpreterTableOpParams>> m_TableOpList;
ScInterpreterTableOpParams aLastTableOpParams; // remember last params
+
private:
LanguageType eLanguage; // default language
@@ -450,7 +458,12 @@ private:
sal_uLong nFormulaCodeInTree; // formula RPN in the formula tree
sal_uLong nXMLImportedFormulaCount; // progress count during XML import
- static thread_local std::map<const ScDocument *, ScDocumentThreadSpecific> maThreadSpecific;
+ ScDocumentThreadSpecific maNonThreaded;
+
+ // There can be only one ScDocument being calculated in a thread at a time, so we can use a
+ // plain thread_local static member.
+ thread_local static ScDocumentThreadSpecific maThreadSpecific;
+
sal_uInt16 nSrcVer; // file version (load/save)
sal_uInt16 nFormulaTrackCount;
HardRecalcState eHardRecalcState; // off, temporary, eternal
@@ -2046,7 +2059,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 );
- void CalculateInColumnInThread( const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
+ ScDocumentThreadSpecific CalculateInColumnInThread( const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
void HandleStuffAfterParallelCalculation( const ScAddress& rTopPos, size_t nLen );
/**
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 3c3266225c1b..43332c2ec873 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -396,10 +396,8 @@ ScDocument::~ScDocument()
ScAddInListener::RemoveDocument( this );
DELETEZ( pChartListenerCollection); // before pBASM because of potential Listener!
- if (maThreadSpecific.find(this) != maThreadSpecific.end())
- {
- DELETEZ( maThreadSpecific[this].pLookupCacheMapImpl ); // before pBASM because of listeners
- }
+ DELETEZ(maNonThreaded.pLookupCacheMapImpl); // before pBASM because of listeners
+ DELETEZ(maThreadSpecific.pLookupCacheMapImpl);
// destroy BroadcastAreas first to avoid un-needed Single-EndListenings of Formula-Cells
delete pBASM; // BroadcastAreaSlotMachine
@@ -449,16 +447,14 @@ ScDocument::~ScDocument()
mxPoolHelper.clear();
delete pScriptTypeData;
- if (maThreadSpecific.find(this) != maThreadSpecific.end())
- delete maThreadSpecific[this].pRecursionHelper;
+ delete maNonThreaded.pRecursionHelper;
+ delete maThreadSpecific.pRecursionHelper;
delete pPreviewFont;
SAL_WARN_IF( pAutoNameCache, "sc.core", "AutoNameCache still set in dtor" );
mpFormulaGroupCxt.reset();
mpCellStringPool.reset();
-
- maThreadSpecific.erase(this);
}
void ScDocument::InitClipPtrs( ScDocument* pSourceDoc )
@@ -1234,50 +1230,103 @@ ScRecursionHelper* ScDocument::CreateRecursionHelperInstance()
ScLookupCache & ScDocument::GetLookupCache( const ScRange & rRange )
{
ScLookupCache* pCache = nullptr;
- if (!maThreadSpecific[this].pLookupCacheMapImpl)
- maThreadSpecific[this].pLookupCacheMapImpl = new ScLookupCacheMapImpl;
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list