[Libreoffice-commits] core.git: Branch 'feature/perfwork4' - 3 commits - comphelper/Library_comphelper.mk comphelper/source include/comphelper sc/Library_scfilt.mk sc/source vcl/source
Michael Meeks
michael.meeks at collabora.com
Thu Oct 30 15:16:42 PDT 2014
comphelper/Library_comphelper.mk | 1
comphelper/source/misc/threadpool.cxx | 182 ++++++++++++++++++++++++++++++
include/comphelper/threadpool.hxx | 72 +++++++++++
sc/Library_scfilt.mk | 1
sc/source/filter/oox/threadpool.cxx | 164 ---------------------------
sc/source/filter/oox/threadpool.hxx | 53 --------
sc/source/filter/oox/workbookfragment.cxx | 11 -
vcl/source/bitmap/bitmapscalesuper.cxx | 32 +----
8 files changed, 273 insertions(+), 243 deletions(-)
New commits:
commit bc483c75571d7a46ab003857200cea8af91bedc7
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Thu Oct 30 22:17:04 2014 +0000
Switch image scaling to use the shared thread pool.
Change-Id: I7450e10b329247d972ef048f61b8ce1ca943aca8
diff --git a/include/comphelper/threadpool.hxx b/include/comphelper/threadpool.hxx
index 2e51719..1b49f87 100644
--- a/include/comphelper/threadpool.hxx
+++ b/include/comphelper/threadpool.hxx
@@ -45,6 +45,9 @@ public:
/// wait until all queued tasks are completed
void waitUntilEmpty();
+ /// return the number of live worker threads
+ sal_Int32 getWorkerCount() { return maWorkers.size(); }
+
private:
class ThreadWorker;
friend class ThreadWorker;
diff --git a/vcl/source/bitmap/bitmapscalesuper.cxx b/vcl/source/bitmap/bitmapscalesuper.cxx
index 4e734c4..2c01709 100644
--- a/vcl/source/bitmap/bitmapscalesuper.cxx
+++ b/vcl/source/bitmap/bitmapscalesuper.cxx
@@ -21,9 +21,8 @@
#include <vcl/bitmapscalesuper.hxx>
#include <algorithm>
-#include <thread>
-#include <osl/thread.hxx>
#include <boost/scoped_array.hpp>
+#include <comphelper/threadpool.hxx>
namespace {
@@ -85,15 +84,14 @@ struct ScaleRangeContext {
typedef void (*ScaleRangeFn)(ScaleContext &rCtx, long nStartY, long nEndY);
-// FIXME: should really be pooled & managed intelligently etc.
-class ScaleThread : public osl::Thread
+class ScaleTask : public comphelper::ThreadTask
{
ScaleRangeFn mpFn;
std::vector< ScaleRangeContext > maStrips;
public:
- ScaleThread( ScaleRangeFn pFn ) : mpFn( pFn ) {}
+ ScaleTask( ScaleRangeFn pFn ) : mpFn( pFn ) {}
void push( ScaleRangeContext &aRC ) { maStrips.push_back( aRC ); }
- virtual void SAL_CALL run() SAL_OVERRIDE
+ virtual void doWork() SAL_OVERRIDE
{
std::vector< ScaleRangeContext >::iterator it;
for (it = maStrips.begin(); it != maStrips.end(); ++it)
@@ -1001,35 +999,29 @@ bool BitmapScaleSuper::filter(Bitmap& rBitmap)
else
{
// partition and queue work
- sal_uInt32 nThreads = std::max(std::thread::hardware_concurrency(), 1U);
+ comphelper::ThreadPool &rShared = comphelper::ThreadPool::getSharedOptimalPool();
+ sal_uInt32 nThreads = rShared.getWorkerCount();
+ assert( nThreads > 0 );
sal_uInt32 nStrips = ((nEndY - nStartY) + SCALE_THREAD_STRIP - 1) / SCALE_THREAD_STRIP;
sal_uInt32 nStripsPerThread = nStrips / nThreads;
SAL_INFO("vcl.gdi", "Scale in " << nStrips << " strips " << nStripsPerThread << " per thread" << " we have " << nThreads << " CPU threads ");
long nStripY = nStartY;
- std::vector<ScaleThread *> aThreads;
for ( sal_uInt32 t = 0; t < nThreads - 1; t++ )
{
- ScaleThread *pThread = new ScaleThread( pScaleRangeFn );
+ ScaleTask *pTask = new ScaleTask( pScaleRangeFn );
for ( sal_uInt32 j = 0; j < nStripsPerThread; j++ )
{
ScaleRangeContext aRC( aContext, nStripY );
- pThread->push( aRC );
+ pTask->push( aRC );
nStripY += SCALE_THREAD_STRIP;
}
- pThread->create(); // set it running
- aThreads.push_back( pThread );
+ rShared.pushTask( pTask );
}
// finish any remaining bits here
pScaleRangeFn( aContext, nStripY, nEndY );
- // join threads...
- for ( std::vector<ScaleThread *>::iterator it = aThreads.begin();
- it != aThreads.end(); ++it )
- {
- (*it)->join();
- delete *it;
- }
- SAL_INFO("vcl.gdi", "Joined all scaling threads");
+ rShared.waitUntilEmpty();
+ SAL_INFO("vcl.gdi", "All threaded scaling tasks complete");
}
bRet = true;
commit a885c10d845101cb7459a582538d4f1b2557495e
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Thu Oct 30 21:58:36 2014 +0000
thread-pool: re-work termination semantics to avoid problems.
We want a pre-spun-up, shared thread-pool that doesn't get its
workers created & joined frequently.
Change-Id: I29081e3a3e3849ca30e63fd080ee3315d99cbe8d
diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx
index d2101ad..236a314 100644
--- a/comphelper/source/misc/threadpool.cxx
+++ b/comphelper/source/misc/threadpool.cxx
@@ -92,7 +92,7 @@ ThreadPool::ThreadPool( sal_Int32 nWorkers ) :
ThreadPool::~ThreadPool()
{
- waitUntilWorkersDone();
+ waitAndCleanupWorkers();
}
struct ThreadPoolStatic : public rtl::StaticWithInit< boost::shared_ptr< ThreadPool >,
@@ -109,9 +109,7 @@ ThreadPool& ThreadPool::getSharedOptimalPool()
return *ThreadPoolStatic::get().get();
}
-/// wait until all the workers have completed and
-/// terminate all threads
-void ThreadPool::waitUntilWorkersDone()
+void ThreadPool::waitAndCleanupWorkers()
{
waitUntilEmpty();
@@ -169,7 +167,6 @@ void ThreadPool::waitUntilEmpty()
pTask->doWork();
delete pTask;
}
- mbTerminate = true;
}
else
{
diff --git a/include/comphelper/threadpool.hxx b/include/comphelper/threadpool.hxx
index ae103f1..2e51719 100644
--- a/include/comphelper/threadpool.hxx
+++ b/include/comphelper/threadpool.hxx
@@ -39,14 +39,19 @@ public:
ThreadPool( sal_Int32 nWorkers );
virtual ~ThreadPool();
+ /// push a new task onto the work queue
void pushTask( ThreadTask *pTask /* takes ownership */ );
+
+ /// wait until all queued tasks are completed
void waitUntilEmpty();
- void waitUntilWorkersDone();
private:
class ThreadWorker;
friend class ThreadWorker;
+ /// wait until all work is completed, then join all threads
+ void waitAndCleanupWorkers();
+
ThreadTask *waitForWork( osl::Condition &rNewWork );
ThreadTask *popWork();
diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index 7fb04fa..b4945b9 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -333,8 +333,9 @@ void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVect
// bar updating.
Application::Yield();
}
- // join all the threads:
- aPool.waitUntilWorkersDone();
+ aPool.waitUntilEmpty();
+
+ // threads joined in ThreadPool destructor
}
else // single threaded iteration
{
commit 2da34cd240fba5abb7de4c2a39a405d33d1b9a1c
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Thu Oct 30 18:37:42 2014 +0000
Move thread-pool down into comphelper for re-use elsewhere.
Change-Id: Ib27b8b1ccc07ff194035d6c2ef3d45c429e3cea1
diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk
index cfe48f6..84bf698 100644
--- a/comphelper/Library_comphelper.mk
+++ b/comphelper/Library_comphelper.mk
@@ -114,6 +114,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\
comphelper/source/misc/string \
comphelper/source/misc/synchronousdispatch \
comphelper/source/misc/syntaxhighlight \
+ comphelper/source/misc/threadpool \
comphelper/source/misc/types \
comphelper/source/misc/weak \
comphelper/source/misc/weakeventlistener \
diff --git a/sc/source/filter/oox/threadpool.cxx b/comphelper/source/misc/threadpool.cxx
similarity index 84%
rename from sc/source/filter/oox/threadpool.cxx
rename to comphelper/source/misc/threadpool.cxx
index 3fcfa75..d2101ad 100644
--- a/sc/source/filter/oox/threadpool.cxx
+++ b/comphelper/source/misc/threadpool.cxx
@@ -7,17 +7,22 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#include "threadpool.hxx"
+#include <comphelper/threadpool.hxx>
+#include <rtl/instance.hxx>
+#include <boost/shared_ptr.hpp>
+#include <thread>
#include <algorithm>
+namespace comphelper {
+
class ThreadPool::ThreadWorker : public salhelper::Thread
{
ThreadPool *mpPool;
osl::Condition maNewWork;
public:
ThreadWorker( ThreadPool *pPool ) :
- salhelper::Thread("sheet-import-thread-pool"),
+ salhelper::Thread("thread-pool"),
mpPool( pPool ) {}
virtual void execute() SAL_OVERRIDE
@@ -90,6 +95,20 @@ ThreadPool::~ThreadPool()
waitUntilWorkersDone();
}
+struct ThreadPoolStatic : public rtl::StaticWithInit< boost::shared_ptr< ThreadPool >,
+ ThreadPoolStatic >
+{
+ boost::shared_ptr< ThreadPool > operator () () {
+ sal_Int32 nThreads = std::max( std::thread::hardware_concurrency(), 1U );
+ return boost::shared_ptr< ThreadPool >( new ThreadPool( nThreads ) );
+ };
+};
+
+ThreadPool& ThreadPool::getSharedOptimalPool()
+{
+ return *ThreadPoolStatic::get().get();
+}
+
/// wait until all the workers have completed and
/// terminate all threads
void ThreadPool::waitUntilWorkersDone()
@@ -161,4 +180,6 @@ void ThreadPool::waitUntilEmpty()
assert( maTasks.empty() );
}
+} // namespace comphelper
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/oox/threadpool.hxx b/include/comphelper/threadpool.hxx
similarity index 73%
rename from sc/source/filter/oox/threadpool.hxx
rename to include/comphelper/threadpool.hxx
index 19b524c..ae103f1 100644
--- a/sc/source/filter/oox/threadpool.hxx
+++ b/include/comphelper/threadpool.hxx
@@ -7,8 +7,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#ifndef INCLUDED_SC_SOURCE_FILTER_OOX_THREADPOOL_HXX
-#define INCLUDED_SC_SOURCE_FILTER_OOX_THREADPOOL_HXX
+#ifndef INCLUDED_COMPHELPER_THREADPOOL_HXX
+#define INCLUDED_COMPHELPER_THREADPOOL_HXX
#include <sal/config.h>
#include <salhelper/thread.hxx>
@@ -16,8 +16,12 @@
#include <osl/conditn.hxx>
#include <rtl/ref.hxx>
#include <vector>
+#include <comphelper/comphelperdllapi.h>
-class ThreadTask
+namespace comphelper
+{
+
+class COMPHELPER_DLLPUBLIC ThreadTask
{
public:
virtual ~ThreadTask() {}
@@ -25,11 +29,16 @@ public:
};
/// A very basic thread pool implementation
-class ThreadPool
+class COMPHELPER_DLLPUBLIC ThreadPool
{
public:
+ /// returns a pointer to a shared pool with optimal thread
+ /// count for the CPU
+ static ThreadPool& getSharedOptimalPool();
+
ThreadPool( sal_Int32 nWorkers );
virtual ~ThreadPool();
+
void pushTask( ThreadTask *pTask /* takes ownership */ );
void waitUntilEmpty();
void waitUntilWorkersDone();
@@ -48,6 +57,8 @@ private:
std::vector< ThreadTask * > maTasks;
};
-#endif // INCLUDED_SC_SOURCE_FILTER_OOX_THREADPOOL_HXX
+} // namespace comphelper
+
+#endif // INCLUDED_COMPHELPER_THREADPOOL_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/Library_scfilt.mk b/sc/Library_scfilt.mk
index 00d32da..77c8486 100644
--- a/sc/Library_scfilt.mk
+++ b/sc/Library_scfilt.mk
@@ -214,7 +214,6 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\
sc/source/filter/oox/tablebuffer \
sc/source/filter/oox/tablefragment \
sc/source/filter/oox/themebuffer \
- sc/source/filter/oox/threadpool \
sc/source/filter/oox/unitconverter \
sc/source/filter/oox/viewsettings \
sc/source/filter/oox/workbookfragment \
diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index 1ce4376..7fb04fa 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -46,7 +46,6 @@
#include "worksheethelper.hxx"
#include "worksheetfragment.hxx"
#include "sheetdatacontext.hxx"
-#include "threadpool.hxx"
#include "officecfg/Office/Common.hxx"
#include "document.hxx"
@@ -58,6 +57,7 @@
#include <oox/core/fastparser.hxx>
#include <salhelper/thread.hxx>
+#include <comphelper/threadpool.hxx>
#include <osl/conditn.hxx>
#include <queue>
@@ -205,7 +205,7 @@ namespace {
typedef std::pair<WorksheetGlobalsRef, FragmentHandlerRef> SheetFragmentHandler;
typedef std::vector<SheetFragmentHandler> SheetFragmentVector;
-class WorkerThread : public ThreadTask
+class WorkerThread : public comphelper::ThreadTask
{
sal_Int32 &mrSheetsLeft;
WorkbookFragment& mrWorkbookHandler;
@@ -309,7 +309,7 @@ void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVect
// test sequential read in this mode
if( nThreads < 0)
nThreads = 0;
- ThreadPool aPool( nThreads );
+ comphelper::ThreadPool aPool( nThreads );
sal_Int32 nSheetsLeft = 0;
ProgressBarTimer aProgressUpdater;
More information about the Libreoffice-commits
mailing list