diff options
author | Tor Lillqvist <tml@collabora.com> | 2013-11-13 10:50:12 +0200 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2013-11-20 18:23:04 +0000 |
commit | c0307ec2bafa0751e7d8ea1f4d6caac58c5cc5dc (patch) | |
tree | 9409294335033e5faf8999684b162301e6d8fd7b | |
parent | feca57d41d515959e3f730eb372a3d33bb251a03 (diff) |
WIP commit of threaded OpenCL compilation work
Change-Id: I210d0ded9cb38569b0831355522d8309cee05f56
-rw-r--r-- | include/sal/log-areas.dox | 1 | ||||
-rw-r--r-- | sc/inc/clkernelthread.hxx | 16 | ||||
-rw-r--r-- | sc/inc/formulacell.hxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 22 | ||||
-rw-r--r-- | sc/source/core/tool/clkernelthread.cxx | 43 |
5 files changed, 76 insertions, 9 deletions
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox index a6ffef998215..eb22ea098275 100644 --- a/include/sal/log-areas.dox +++ b/include/sal/log-areas.dox @@ -84,6 +84,7 @@ certain functionality. @li @c sc @li @c sc.opencl +@li @c sc.opencl.thread @li @c sc.core @li @c sc.filter - Calc filter @li @c sc.ui - Calc UI diff --git a/sc/inc/clkernelthread.hxx b/sc/inc/clkernelthread.hxx index c780c2852b9a..89ae860318f0 100644 --- a/sc/inc/clkernelthread.hxx +++ b/sc/inc/clkernelthread.hxx @@ -7,11 +7,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <queue> + #include <osl/conditn.hxx> #include <salhelper/thread.hxx> +#include "formulacell.hxx" + namespace sc { +struct CLBuildKernelWorkItem +{ + enum { COMPILE, FINISH } meWhatToDo; + ScFormulaCellGroupRef mxGroup; +}; + class CLBuildKernelThread : public salhelper::Thread { public: @@ -20,11 +30,15 @@ public: void finish(); + void push(CLBuildKernelWorkItem item); + protected: virtual void execute(); private: - osl::Condition maConsumeCondition; + osl::Mutex maMutex; + osl::Condition maCondition; + std::queue<CLBuildKernelWorkItem> maQueue; void produce(); void consume(); }; diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx index 4e56b6ab795d..68648fc1049a 100644 --- a/sc/inc/formulacell.hxx +++ b/sc/inc/formulacell.hxx @@ -53,6 +53,7 @@ struct SC_DLLPUBLIC ScFormulaCellGroup : boost::noncopyable mutable size_t mnRefCount; ScTokenArray* mpCode; + osl::Mutex maMutex; sc::CompiledFormula* mpCompiledFormula; ScFormulaCell *mpTopCell; SCROW mnLength; // How many of these do we have ? @@ -64,6 +65,8 @@ struct SC_DLLPUBLIC ScFormulaCellGroup : boost::noncopyable ScFormulaCellGroup(); ~ScFormulaCellGroup(); + void scheduleCompilation(); + void setCode( const ScTokenArray& rCode ); void compileCode( ScDocument& rDoc, const ScAddress& rPos, formula::FormulaGrammar::Grammar eGram ); diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index e0ee5a75f710..c17e4f3638dd 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -418,11 +418,11 @@ ScFormulaCellGroup::ScFormulaCellGroup() : { osl::MutexGuard aGuard(getOpenCLCompilationThreadMutex()); if (mnCount++ == 0) - { - assert(!mxCLKernelThread.is()); - mxCLKernelThread.set(new sc::CLBuildKernelThread); - mxCLKernelThread->launch(); - } + { + assert(!mxCLKernelThread.is()); + mxCLKernelThread.set(new sc::CLBuildKernelThread); + mxCLKernelThread->launch(); + } } } @@ -443,6 +443,14 @@ ScFormulaCellGroup::~ScFormulaCellGroup() delete mpCode; } +void ScFormulaCellGroup::scheduleCompilation() +{ + sc::CLBuildKernelWorkItem aWorkItem; + aWorkItem.meWhatToDo = sc::CLBuildKernelWorkItem::COMPILE; + aWorkItem.mxGroup = this; + mxCLKernelThread->push(aWorkItem); +} + void ScFormulaCellGroup::setCode( const ScTokenArray& rCode ) { delete mpCode; @@ -929,7 +937,9 @@ void ScFormulaCell::CompileTokenArray( bool bNoListening ) { // Not already compiled? if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() ) + { Compile( aResult.GetHybridFormula(), bNoListening, eTempGrammar); + } else if( bCompile && !pDocument->IsClipOrUndo() && !pCode->GetCodeError() ) { // RPN length may get changed @@ -3319,6 +3329,7 @@ ScFormulaCellGroupRef ScFormulaCell::CreateCellGroup( SCROW nLen, bool bInvarian mxGroup->mbInvariant = bInvariant; mxGroup->mnLength = nLen; mxGroup->mpCode = pCode; // Move this to the shared location. + mxGroup->scheduleCompilation(); return mxGroup; } @@ -3509,7 +3520,6 @@ public: aComp.SetGrammar(formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1); OUStringBuffer aAsString; aComp.CreateStringFromTokenArray(aAsString); - SAL_DEBUG("interpret formula: " << aAsString.makeStringAndClear()); } #endif diff --git a/sc/source/core/tool/clkernelthread.cxx b/sc/source/core/tool/clkernelthread.cxx index 90c9496bfc20..b89312b26678 100644 --- a/sc/source/core/tool/clkernelthread.cxx +++ b/sc/source/core/tool/clkernelthread.cxx @@ -26,7 +26,43 @@ CLBuildKernelThread::~CLBuildKernelThread() void CLBuildKernelThread::execute() { - SAL_INFO("sc.opencl", "opencl-buildkernel-thread running"); + SAL_INFO("sc.opencl.thread", "running"); + + bool done = false; + while (!done) + { + SAL_INFO("sc.opencl.thread", "waiting for condition"); + maCondition.wait(); + SAL_INFO("sc.opencl.thread", "got condition"); + osl::ResettableMutexGuard aGuard(maMutex); + maCondition.reset(); + while (!maQueue.empty()) + { + CLBuildKernelWorkItem aWorkItem = maQueue.front(); + maQueue.pop(); + aGuard.clear(); + + switch (aWorkItem.meWhatToDo) + { + case CLBuildKernelWorkItem::COMPILE: + SAL_INFO("sc.opencl.thread", "told to compile group " << aWorkItem.mxGroup << " to binary"); + break; + case CLBuildKernelWorkItem::FINISH: + SAL_INFO("sc.opencl.thread", "told to finish"); + done = true; + break; + } + + aGuard.reset(); + } + } +} + +void CLBuildKernelThread::push(CLBuildKernelWorkItem item) +{ + osl::MutexGuard guard(maMutex); + maQueue.push(item); + maCondition.set(); } void CLBuildKernelThread::produce() @@ -39,7 +75,10 @@ void CLBuildKernelThread::consume() void CLBuildKernelThread::finish() { - SAL_INFO("sc.opencl", "opencl-buildkernel-thread request to finish"); + SAL_INFO("sc.opencl", "telling thread to finish"); + CLBuildKernelWorkItem aWorkItem; + aWorkItem.meWhatToDo = CLBuildKernelWorkItem::FINISH; + push(aWorkItem); } } |