summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Holesovsky <kendy@collabora.com>2016-05-30 17:36:37 +0200
committerJan Holesovsky <kendy@collabora.com>2016-05-31 15:26:59 +0200
commit5acdf13b21e52e3c26657d063a9b327006bc5494 (patch)
treeed552a9ba856082e85944f45477cca370bc3ae5d
parent407c675229e803ce1038384c233e3dc028d786e0 (diff)
tdf#100092: Deterministic scheduling to prevent unpredictable behavior.
Low priority idles can fire more or less randomly, and consequently two consequent runs of LibreOffice differ in the amount of the idles that have been performed during an operation. This commit adds a possibility to turn on a 'deterministic mode' where two subsequent runs of LibreOffice trigger about the same amount of events when they perform the same set of operations. Change-Id: I92566ef4eee20e7d604cfd48f01c4df30c77e653
-rw-r--r--include/vcl/scheduler.hxx9
-rw-r--r--offapi/com/sun/star/awt/XToolkitExperimental.idl16
-rw-r--r--toolkit/source/awt/vclxtoolkit.cxx14
-rw-r--r--vcl/source/app/idle.cxx18
-rw-r--r--vcl/source/app/scheduler.cxx12
5 files changed, 59 insertions, 10 deletions
diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
index 760c228b174e..3abd37d6976e 100644
--- a/include/vcl/scheduler.hxx
+++ b/include/vcl/scheduler.hxx
@@ -47,6 +47,7 @@ protected:
// These should be constexpr static, when supported.
static const sal_uInt64 ImmediateTimeoutMs = 1;
+ static const sal_uInt64 InfiniteTimeoutMs = 1000 * 60 * 60 * 24; // 1 day
static void ImplStartTimer(sal_uInt64 nMS, bool bForce = false);
@@ -84,7 +85,7 @@ public:
Scheduler& operator=( const Scheduler& rScheduler );
static void ImplDeInitScheduler();
- // Process one pending Timer with highhest priority
+ /// Process one pending Timer with highhest priority
static void CallbackTaskScheduling( bool ignore );
/// Calculate minimum timeout - and return its value.
static sal_uInt64 CalculateMinimumTimeout( bool &bHasActiveIdles );
@@ -92,6 +93,12 @@ public:
static bool ProcessTaskScheduling( bool bTimerOnly );
/// Process all events until we are idle
static void ProcessEventsToIdle();
+
+ /// Control the deterministic mode. In this mode, two subsequent runs of
+ /// LibreOffice fire about the same amount idles.
+ static void SetDeterministicMode(bool bDeterministic);
+ /// Return the current state of deterministic mode.
+ static bool GetDeterministicMode();
};
#endif // INCLUDED_VCL_SCHEDULER_HXX
diff --git a/offapi/com/sun/star/awt/XToolkitExperimental.idl b/offapi/com/sun/star/awt/XToolkitExperimental.idl
index 7c5d36331958..89828b2864e1 100644
--- a/offapi/com/sun/star/awt/XToolkitExperimental.idl
+++ b/offapi/com/sun/star/awt/XToolkitExperimental.idl
@@ -19,14 +19,18 @@ module com { module sun { module star { module awt {
interface XToolkitExperimental : XToolkit2
{
- /** Process all pending idle events
- */
- void processEventsToIdle();
+ /** Process all pending idle events
+ */
+ void processEventsToIdle();
- /** Get the number of OpenGL buffer swaps.
- */
- hyper getOpenGLBufferSwapCounter();
+ /** Get the number of OpenGL buffer swaps.
+ */
+ hyper getOpenGLBufferSwapCounter();
+
+ /** Turn on or off deterministic scheduling (off is the default).
+ */
+ void setDeterministicScheduling([in] boolean bDeterministicMode);
};
}; }; }; };
diff --git a/toolkit/source/awt/vclxtoolkit.cxx b/toolkit/source/awt/vclxtoolkit.cxx
index c99030cabecf..2dfa25cf13cb 100644
--- a/toolkit/source/awt/vclxtoolkit.cxx
+++ b/toolkit/source/awt/vclxtoolkit.cxx
@@ -202,6 +202,9 @@ public:
virtual sal_Int64 SAL_CALL getOpenGLBufferSwapCounter()
throw (css::uno::RuntimeException, std::exception) override;
+ virtual void SAL_CALL setDeterministicScheduling(sal_Bool bDeterministicMode)
+ throw (css::uno::RuntimeException, std::exception) override;
+
// css::awt::XToolkit
css::uno::Reference< css::awt::XWindowPeer > SAL_CALL getDesktopWindow( ) throw(css::uno::RuntimeException, std::exception) override;
css::awt::Rectangle SAL_CALL getWorkArea( ) throw(css::uno::RuntimeException, std::exception) override;
@@ -1926,12 +1929,19 @@ sal_Int64 SAL_CALL VCLXToolkit::getOpenGLBufferSwapCounter()
throw (css::uno::RuntimeException, std::exception)
{
#if HAVE_FEATURE_OPENGL
- return OpenGLWrapper::getBufferSwapCounter();
+ return OpenGLWrapper::getBufferSwapCounter();
#else
- return 0;
+ return 0;
#endif
}
+void SAL_CALL VCLXToolkit::setDeterministicScheduling(sal_Bool bDeterministicMode)
+ throw (css::uno::RuntimeException, std::exception)
+{
+ SolarMutexGuard aSolarGuard;
+ Scheduler::SetDeterministicMode(bDeterministicMode);
+}
+
// css:awt:XToolkitRobot
void SAL_CALL VCLXToolkit::keyPress( const css::awt::KeyEvent & aKeyEvent )
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
index ad9829b97074..10a7a495a92f 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -44,7 +44,23 @@ Idle::Idle( const Idle& rIdle ) : Scheduler(rIdle)
void Idle::Start()
{
Scheduler::Start();
- Scheduler::ImplStartTimer(Scheduler::ImmediateTimeoutMs);
+
+ sal_uInt64 nPeriod = Scheduler::ImmediateTimeoutMs;
+ if (Scheduler::GetDeterministicMode())
+ {
+ switch (mePriority)
+ {
+ case SchedulerPriority::LOW:
+ case SchedulerPriority::LOWER:
+ case SchedulerPriority::LOWEST:
+ nPeriod = Scheduler::InfiniteTimeoutMs;
+ break;
+ default:
+ break;
+ }
+ }
+
+ Scheduler::ImplStartTimer(nPeriod);
}
bool Idle::ReadyForSchedule( bool bTimerOnly, sal_uInt64 /* nTimeNow */ ) const
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index 291c4f73571c..4dcbc4d196b6 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -181,6 +181,18 @@ bool Scheduler::ProcessTaskScheduling( bool bTimerOnly )
return false;
}
+static bool g_bDeterministicMode = false;
+
+void Scheduler::SetDeterministicMode(bool bDeterministic)
+{
+ g_bDeterministicMode = bDeterministic;
+}
+
+bool Scheduler::GetDeterministicMode()
+{
+ return g_bDeterministicMode;
+}
+
sal_uInt64 Scheduler::CalculateMinimumTimeout( bool &bHasActiveIdles )
{
// process all pending Tasks