[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