From 769832cc1f592b1d0c39cda7795fe4548fc97566 Mon Sep 17 00:00:00 2001 From: Dennis Francis Date: Wed, 20 Mar 2019 20:07:58 +0530 Subject: [PATCH] Increase the life-cycle of threads in thread-pool... to ScDocument lifetime if possible. This helps to avoid lots of thread setup-cost while doing recalcs especially if there are many formula-groups in the document and most of them are fairly light-weight. Change-Id: Idd57e1ebd0d4e492f99e31237d4a55ec9c95a121 Reviewed-on: https://gerrit.libreoffice.org/69473 Tested-by: Jenkins Reviewed-by: Michael Meeks --- comphelper/source/misc/threadpool.cxx | 16 ++++++++++------ include/comphelper/threadpool.hxx | 9 +++++++-- sc/source/core/data/documen2.cxx | 4 ++++ sc/source/core/data/formulacell.cxx | 6 ++++-- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx index d0178e9aa9a7..89d80298432b 100644 --- a/comphelper/source/misc/threadpool.cxx +++ b/comphelper/source/misc/threadpool.cxx @@ -213,7 +213,7 @@ std::unique_ptr ThreadPool::popWorkLocked( std::unique_lock< std::mu return nullptr; } -void ThreadPool::waitUntilDone(const std::shared_ptr& rTag) +void ThreadPool::waitUntilDone(const std::shared_ptr& rTag, bool bJoinAll) { #if defined DBG_UTIL && (defined LINUX || defined _WIN32) assert(!gbIsWorkerThread && "cannot wait for tasks from inside a task"); @@ -232,12 +232,16 @@ void ThreadPool::waitUntilDone(const std::shared_ptr& rTag) rTag->waitUntilDone(); + if (bJoinAll) + joinAll(); +} + +void ThreadPool::joinAll() +{ + std::unique_lock< std::mutex > aGuard( maMutex ); + if (maTasks.empty()) // check if there are still tasks from another tag { - std::unique_lock< std::mutex > aGuard( maMutex ); - if (maTasks.empty()) // check if there are still tasks from another tag - { - shutdownLocked(aGuard); - } + shutdownLocked(aGuard); } } diff --git a/include/comphelper/threadpool.hxx b/include/comphelper/threadpool.hxx index 092078199981..1cb9441cfdd1 100644 --- a/include/comphelper/threadpool.hxx +++ b/include/comphelper/threadpool.hxx @@ -63,8 +63,13 @@ public: /// push a new task onto the work queue void pushTask( std::unique_ptr pTask); - /// wait until all queued tasks associated with the tag are completed - void waitUntilDone(const std::shared_ptr&); + /** Wait until all queued tasks associated with the tag are completed + @param bJoinAll - if set it joins all threads at the end if no other tasks from other tags. + */ + void waitUntilDone(const std::shared_ptr&, bool bJoinAll = true); + + /// join all threads if there are no tasks presently. + void joinAll(); /// return the number of live worker threads sal_Int32 getWorkerCount() const { return mnWorkers; } diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 321c4535e10b..0892025b242a 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -307,6 +308,9 @@ ScDocument::~ScDocument() { OSL_PRECOND( !bInLinkUpdate, "bInLinkUpdate in dtor" ); + // Join any pending(recalc) threads in global threadpool + comphelper::ThreadPool::getSharedOptimalPool().joinAll(); + bInDtorClear = true; // first of all disable all refresh timers by deleting the control diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 17dc29811ae5..9edddf0bfc54 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -4758,8 +4758,10 @@ bool ScFormulaCell::InterpretFormulaGroupThreading(sc::FormulaLogger::GroupScope nStartOffset, nEndOffset)); } - SAL_INFO("sc.threaded", "Joining threads"); - rThreadPool.waitUntilDone(aTag); + SAL_INFO("sc.threaded", "Waiting for threads to finish work"); + // Do not join the threads here. They will get joined in ScDocument destructor + // if they don't get joined from elsewhere before (via ThreadPool::waitUntilDone). + rThreadPool.waitUntilDone(aTag, false); pDocument->SetThreadedGroupCalcInProgress(false); -- 2.11.4.GIT