[Libreoffice-commits] core.git: Branch 'feature/priorities' - include/vcl vcl/source
Tobias Madl
tobias.madl.dev at gmail.com
Fri Jan 16 05:32:54 PST 2015
include/vcl/idle.hxx | 22 +++++++++++---------
include/vcl/timer.hxx | 1
vcl/source/app/idle.cxx | 51 +++++++++++++++++++++++++++++++++++++++++++++--
vcl/source/app/timer.cxx | 25 +++++++++++++++++++++++
4 files changed, 88 insertions(+), 11 deletions(-)
New commits:
commit f3e757ea37d176f70605bbadbb1b5018f9fbce9f
Author: Tobias Madl <tobias.madl.dev at gmail.com>
Date: Fri Jan 16 13:28:29 2015 +0000
Scheduling optimization and starving protection
If a Timeout appears, while the idle scheduling is in progress.
The idle scheduler gets interrupted and the timeouts are handled.
Now the idle scheduler has a new starving protection.
Change-Id: Ic9081c647e3fb0abf3b0dc014e711a3b97e0e37d
diff --git a/include/vcl/idle.hxx b/include/vcl/idle.hxx
index 9da8414..da0a5c7 100644
--- a/include/vcl/idle.hxx
+++ b/include/vcl/idle.hxx
@@ -28,14 +28,16 @@ struct ImplIdleData;
struct ImplSVData;
enum class IdlePriority {
- VCL_IDLE_PRIORITY_HIGHEST = 0, // -> 0ms
- VCL_IDLE_PRIORITY_HIGH = 1, // -> 1ms
- VCL_IDLE_PRIORITY_REPAINT = 2, // -> 30ms
- VCL_IDLE_PRIORITY_RESIZE = 3, // -> 50ms
- VCL_IDLE_PRIORITY_MEDIUM = 4, // -> 50ms
- VCL_IDLE_PRIORITY_LOW = 5, // -> 100ms
- VCL_IDLE_PRIORITY_LOWER = 6, // -> 200ms
- VCL_IDLE_PRIORITY_LOWEST = 7 // -> 400ms
+ VCL_IDLE_PRIORITY_STARVATIONPROTECTION = -1, // Do not use this for normal prioritizing
+ VCL_IDLE_PRIORITY_HIGHEST = 0, // -> 0ms
+ VCL_IDLE_PRIORITY_HIGH = 1, // -> 1ms
+ VCL_IDLE_PRIORITY_DEFAULT = 1, // -> 1ms
+ VCL_IDLE_PRIORITY_REPAINT = 2, // -> 30ms
+ VCL_IDLE_PRIORITY_RESIZE = 3, // -> 50ms
+ VCL_IDLE_PRIORITY_MEDIUM = 3, // -> 50ms
+ VCL_IDLE_PRIORITY_LOW = 5, // -> 100ms
+ VCL_IDLE_PRIORITY_LOWER = 6, // -> 200ms
+ VCL_IDLE_PRIORITY_LOWEST = 7 // -> 400ms
};
@@ -46,6 +48,7 @@ class VCL_DLLPUBLIC Idle
protected:
ImplIdleData* mpIdleData;
IdlePriority mePriority;
+ IdlePriority meDefaultPriority;
bool mbActive;
Link maIdleHdl;
@@ -56,8 +59,9 @@ public:
Idle( const Idle& rIdle );
virtual ~Idle();
- void SetPriority( IdlePriority ePriority ) { mePriority = ePriority; }
+ void SetPriority( IdlePriority ePriority );
IdlePriority GetPriority() const { return mePriority; }
+ IdlePriority GetDefaultPriority() const { return meDefaultPriority; }
/// Make it possible to associate a callback with this idle handler
/// of course, you can also sub-class and override 'DoIdle'
diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx
index ea65d6f..3aca8e5 100644
--- a/include/vcl/timer.hxx
+++ b/include/vcl/timer.hxx
@@ -62,6 +62,7 @@ public:
static void ImplDeInitTimer();
static void ImplTimerCallbackProc();
+ static bool TimerReady();
};
/// An auto-timer is a multi-shot timer re-emitting itself at
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
index 15427d6..74f0eaf 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -19,6 +19,7 @@
#include <vcl/svapp.hxx>
#include <vcl/idle.hxx>
+#include <vcl/timer.hxx>
#include <svdata.hxx>
#include <salinst.hxx>
@@ -35,6 +36,7 @@ struct ImplIdleData
if (mbDelete || mbInIdle )
return;
+ mpIdle->SetPriority(mpIdle->GetDefaultPriority());
mbDelete = true;
mpIdle->mbActive = false;
@@ -59,12 +61,47 @@ struct ImplIdleData
{
// Find the highest priority one somehow.
if ( p->mpIdle->GetPriority() < pMostUrgent->mpIdle->GetPriority() )
+ {
+ IncreasePriority(pMostUrgent->mpIdle);
pMostUrgent = p;
+ }
+ else
+ IncreasePriority(p->mpIdle);
}
}
return pMostUrgent;
}
+
+ static void IncreasePriority( Idle *pIdle )
+ {
+ switch(pIdle->GetPriority())
+ {
+ case IdlePriority::VCL_IDLE_PRIORITY_STARVATIONPROTECTION:
+ break;
+ case IdlePriority::VCL_IDLE_PRIORITY_HIGHEST:
+ pIdle->SetPriority(IdlePriority::VCL_IDLE_PRIORITY_STARVATIONPROTECTION);
+ break;
+ case IdlePriority::VCL_IDLE_PRIORITY_HIGH:
+ pIdle->SetPriority(IdlePriority::VCL_IDLE_PRIORITY_HIGHEST);
+ break;
+ case IdlePriority::VCL_IDLE_PRIORITY_REPAINT:
+ pIdle->SetPriority(IdlePriority::VCL_IDLE_PRIORITY_HIGH);
+ break;
+ case IdlePriority::VCL_IDLE_PRIORITY_MEDIUM:
+ pIdle->SetPriority(IdlePriority::VCL_IDLE_PRIORITY_REPAINT);
+ break;
+ case IdlePriority::VCL_IDLE_PRIORITY_LOW:
+ pIdle->SetPriority(IdlePriority::VCL_IDLE_PRIORITY_MEDIUM);
+ break;
+ case IdlePriority::VCL_IDLE_PRIORITY_LOWER:
+ pIdle->SetPriority(IdlePriority::VCL_IDLE_PRIORITY_LOW);
+ break;
+ case IdlePriority::VCL_IDLE_PRIORITY_LOWEST:
+ pIdle->SetPriority(IdlePriority::VCL_IDLE_PRIORITY_LOWER);
+ break;
+ }
+ }
};
void Idle::ImplDeInitIdle()
@@ -97,7 +134,7 @@ void Idle::ProcessAllIdleHandlers()
ImplIdleData* pIdleData = NULL;
ImplIdleData* pPrevIdleData = NULL;
ImplSVData* pSVData = ImplGetSVData();
- while ((pIdleData = ImplIdleData::GetFirstIdle()))
+ while (!Timer::TimerReady() && (pIdleData = ImplIdleData::GetFirstIdle()))
{
pIdleData->Invoke();
}
@@ -126,6 +163,13 @@ void Idle::ProcessAllIdleHandlers()
}
}
+void Idle::SetPriority( IdlePriority ePriority )
+{
+ mePriority = ePriority;
+ if( !mbActive && meDefaultPriority == IdlePriority::VCL_IDLE_PRIORITY_DEFAULT )
+ meDefaultPriority = mePriority;
+}
+
void Idle::DoIdle()
{
maIdleHdl.Call( this );
@@ -183,6 +227,7 @@ Idle& Idle::operator=( const Idle& rIdle )
mbActive = false;
mePriority = rIdle.mePriority;
+ meDefaultPriority = rIdle.meDefaultPriority;
maIdleHdl = rIdle.maIdleHdl;
if ( rIdle.IsActive() )
@@ -193,7 +238,8 @@ Idle& Idle::operator=( const Idle& rIdle )
Idle::Idle():
mpIdleData(NULL),
- mePriority(IdlePriority::VCL_IDLE_PRIORITY_HIGH),
+ mePriority(IdlePriority::VCL_IDLE_PRIORITY_DEFAULT),
+ meDefaultPriority(IdlePriority::VCL_IDLE_PRIORITY_DEFAULT),
mbActive(false)
{
}
@@ -201,6 +247,7 @@ Idle::Idle():
Idle::Idle( const Idle& rIdle ):
mpIdleData(NULL),
mePriority(rIdle.mePriority),
+ meDefaultPriority(rIdle.meDefaultPriority),
mbActive(false),
maIdleHdl(rIdle.maIdleHdl)
{
diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx
index 50023cb..4adc8e8 100644
--- a/vcl/source/app/timer.cxx
+++ b/vcl/source/app/timer.cxx
@@ -210,6 +210,31 @@ void Timer::ImplTimerCallbackProc()
pSVData->mbNotAllTimerCalled = false;
}
+bool Timer::TimerReady()
+{
+// find timer where the timer handler needs to be called
+ ImplSVData* pSVData = ImplGetSVData();
+ ImplTimerData* pTimerData = pSVData->mpFirstTimerData;
+ sal_uLong nTime = tools::Time::GetSystemTicks();
+ while ( pTimerData )
+ {
+ // If the timer is not new, was not deleted, and if it is not in the timeout handler, then
+ // call the handler as soon as the time is up.
+ if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) &&
+ !pTimerData->mbDelete && !pTimerData->mbInTimeout)
+ {
+ // time has expired
+ if ( pTimerData->GetDeadline() <= nTime )
+ {
+ return true;
+ }
+ }
+
+ pTimerData = pTimerData->mpNext;
+ }
+ return false;
+}
+
Timer::Timer():
mpTimerData(NULL),
mnTimeout(1),
More information about the Libreoffice-commits
mailing list