summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2013-11-13 10:50:12 +0200
committerMichael Meeks <michael.meeks@collabora.com>2013-11-20 18:23:04 +0000
commitc0307ec2bafa0751e7d8ea1f4d6caac58c5cc5dc (patch)
tree9409294335033e5faf8999684b162301e6d8fd7b /sc
parentfeca57d41d515959e3f730eb372a3d33bb251a03 (diff)
WIP commit of threaded OpenCL compilation work
Change-Id: I210d0ded9cb38569b0831355522d8309cee05f56
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/clkernelthread.hxx16
-rw-r--r--sc/inc/formulacell.hxx3
-rw-r--r--sc/source/core/data/formulacell.cxx22
-rw-r--r--sc/source/core/tool/clkernelthread.cxx43
4 files changed, 75 insertions, 9 deletions
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);
}
}