comphelper/source/misc/threadpool.cxx | 40 ++++++++++++++++++++++++++++------ include/comphelper/threadpool.hxx | 12 ++++++---- sc/source/filter/excel/xetable.cxx | 26 +++++++++++----------- 3 files changed, 55 insertions(+), 23 deletions(-)
New commits: commit 26a0edf153c70adb7e1b0208616e81acb05289fb Author: Michael Meeks <[email protected]> Date: Fri Oct 31 12:32:12 2014 +0000 thread-pool: fix waiting until all tasks are complete. Change-Id: Iaf5a3bf28879f229a223a8760fd878f96958a53c diff --git a/comphelper/source/misc/threadpool.cxx b/comphelper/source/misc/threadpool.cxx index 236a314..3717ffb 100644 --- a/comphelper/source/misc/threadpool.cxx +++ b/comphelper/source/misc/threadpool.cxx @@ -20,10 +20,15 @@ class ThreadPool::ThreadWorker : public salhelper::Thread { ThreadPool *mpPool; osl::Condition maNewWork; + bool mbWorking; public: + ThreadWorker( ThreadPool *pPool ) : salhelper::Thread("thread-pool"), - mpPool( pPool ) {} + mpPool( pPool ), + mbWorking( false ) + { + } virtual void execute() SAL_OVERRIDE { @@ -45,6 +50,9 @@ public: while( !pRet ) { + if (mbWorking) + mpPool->stopWork(); + mbWorking = false; maNewWork.reset(); if( mpPool->mbTerminate ) @@ -59,6 +67,13 @@ public: pRet = mpPool->popWork(); } + if (pRet) + { + if (!mbWorking) + mpPool->startWork(); + mbWorking = true; + } + return pRet; } @@ -78,12 +93,13 @@ public: }; ThreadPool::ThreadPool( sal_Int32 nWorkers ) : + mnThreadsWorking( 0 ), mbTerminate( false ) { for( sal_Int32 i = 0; i < nWorkers; i++ ) maWorkers.push_back( new ThreadWorker( this ) ); - maTasksEmpty.reset(); + maTasksComplete.reset(); osl::MutexGuard aGuard( maGuard ); for( size_t i = 0; i < maWorkers.size(); i++ ) @@ -136,10 +152,11 @@ void ThreadPool::pushTask( ThreadTask *pTask ) { osl::MutexGuard aGuard( maGuard ); maTasks.insert( maTasks.begin(), pTask ); + // horrible beyond belief: for( size_t i = 0; i < maWorkers.size(); i++ ) maWorkers[ i ]->signalNewWork(); - maTasksEmpty.reset(); + maTasksComplete.reset(); } ThreadTask *ThreadPool::popWork() @@ -151,8 +168,19 @@ ThreadTask *ThreadPool::popWork() return pTask; } else - maTasksEmpty.set(); - return NULL; + return NULL; +} + +void ThreadPool::startWork() +{ + mnThreadsWorking++; +} + +void ThreadPool::stopWork() +{ + assert( mnThreadsWorking > 0 ); + if ( --mnThreadsWorking == 0 ) + maTasksComplete.set(); } void ThreadPool::waitUntilEmpty() @@ -171,7 +199,7 @@ void ThreadPool::waitUntilEmpty() else { aGuard.clear(); - maTasksEmpty.wait(); + maTasksComplete.wait(); aGuard.reset(); } assert( maTasks.empty() ); diff --git a/include/comphelper/threadpool.hxx b/include/comphelper/threadpool.hxx index 1b49f87..028808f 100644 --- a/include/comphelper/threadpool.hxx +++ b/include/comphelper/threadpool.hxx @@ -57,10 +57,14 @@ private: ThreadTask *waitForWork( osl::Condition &rNewWork ); ThreadTask *popWork(); - - osl::Mutex maGuard; - osl::Condition maTasksEmpty; - bool mbTerminate; + void startWork(); + void stopWork(); + + osl::Mutex maGuard; + sal_Int32 mnThreadsWorking; + /// signalled when all in-progress tasks are complete + osl::Condition maTasksComplete; + bool mbTerminate; std::vector< rtl::Reference< ThreadWorker > > maWorkers; std::vector< ThreadTask * > maTasks; }; commit c9a4a10e1be611fe219a975f3924c37e92c02ea4 Author: Michael Meeks <[email protected]> Date: Fri Oct 31 12:26:22 2014 +0000 Cleanup xetable threading - make it compile (urk). Change-Id: I966c7b214494c29545b1c4be3a98641bf440e16c diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx index e867162..174b78a 100644 --- a/sc/source/filter/excel/xetable.cxx +++ b/sc/source/filter/excel/xetable.cxx @@ -34,6 +34,7 @@ #include "xeescher.hxx" #include "xeextlst.hxx" #include "tokenarray.hxx" +#include <thread> #include <comphelper/threadpool.hxx> using namespace ::oox; @@ -2053,8 +2054,8 @@ public: void push_back( XclExpRow *pRow ) { maRows.push_back( pRow ); } virtual void doWork() { - for (size_t i = 0; i < aRows.size(); i++ ) - maRows[ i ]->Finalize( mrColXFIndexes ); + for (size_t i = 0; i < maRows.size(); i++ ) + maRows[ i ]->Finalize( mrColXFIndexes, mbProgress ); } }; @@ -2067,27 +2068,26 @@ void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt // This is staggeringly slow, and each element operates only // on its own data. size_t nRows = maRowMap.size(); - size_t nThreads = std::max( std::thread::hardware_concurrency(), 1U ); + size_t nThreads = std::max( std::thread::hardware_concurrency(), 1U ); if ( nThreads == 1 || nRows < 128 ) { RowMap::iterator itr, itrBeg = maRowMap.begin(), itrEnd = maRowMap.end(); - for (size_t i = 0, itr = itrBeg; itr != itrEnd; ++itr, ++i) - itr->second->Finalize( rColXFIndexes ); + for (itr = itrBeg; itr != itrEnd; ++itr) + itr->second->Finalize( rColXFIndexes, true ); } else { - ThreadPool &rPool = comphelper::ThreadPool::getSharedOptimalPool(); - ThreadTask *pTasks[ nThreads ]; - for (size_t i = 0; i < nThreads; i++) + comphelper::ThreadPool &rPool = comphelper::ThreadPool::getSharedOptimalPool(); + RowFinalizeTask *pTasks[ nThreads ]; + for ( size_t i = 0; i < nThreads; i++ ) pTasks[ i ] = new RowFinalizeTask( rColXFIndexes, i == 0 ); RowMap::iterator itr, itrBeg = maRowMap.begin(), itrEnd = maRowMap.end(); - for (size_t i = 0, itr = itrBeg; itr != itrEnd; ++itr, ++i) - { - pTasks[ i % nThreads ]->push_back( itr->second ); - } + size_t nIdx = 0; + for ( itr = itrBeg; itr != itrEnd; ++itr, ++nIdx ) + pTasks[ nIdx % nThreads ]->push_back( itr->second.get() ); - for (size_t i = 0; i < nThreads; i++) + for ( size_t i = 0; i < nThreads; i++ ) rPool.pushTask( pTasks[ i ] ); rPool.waitUntilEmpty(); _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
