[Libreoffice-commits] core.git: Branch 'feature/perfwork4' - 2 commits - comphelper/source include/comphelper sc/source

Michael Meeks michael.meeks at collabora.com
Fri Oct 31 05:32:15 PDT 2014


 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 <michael.meeks at collabora.com>
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 <michael.meeks at collabora.com>
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();


More information about the Libreoffice-commits mailing list